c语言习题---(循环语句)
這里寫目錄標題
- 前言
- 題目目錄
- 非編程題
- 編程題
- 第一題解析
- 第二題解析
- 第三題解析
- 第一題解析
- 第二題解析
- 第三題解析
- 第四題詳解
- 第五題解析
- 第六題解析
- 第七題解析
- 第八題解析
- 第九題解析
- 第十題解析
前言
從這一章開始我們的題就多起來了,因為前面的分支語句,啊不管怎么出類型就那樣,但是我們的循環語句就復雜一些,我們就多來點題目好吧廢話不多說先看題。
題目目錄
非編程題
第一題:
#include<stdio.h> int main() {int n = 0;while (n++ <= 2);printf("%d\n", n);return 0; }第二題:
#include<stdio.h> int main() {int x = 0;int y = 0;for (y = 1; y < 10;){y = ((x = 3 * y, x + 1), x - 1);printf("x=%d,y=%d", x, y);}return 0; }第三題:
#include<stdio.h> int main() {int n = 2;int k = 0;while (k++ && n++ > 2);{printf("%d %d\n", k, n);} return 0; }編程題
第1題:
第2題:
第3題:
第4題:
第5題:
第6題:
第7題:
第8題:
第9題:
第十題:
第一題解析
#include<stdio.h> int main() {int n = 0;while (n++ <= 2);printf("%d\n", n);return 0; }我們來這段代碼,我們這道題的目的就是提醒大家n++的區別,首先可以看到我們一開始將n初始化為0,然后我們就進入了while循環的判斷部分,我們來看這個判斷部分的內容是n++<=2,那么這里我就有個問題來問大家,我們是將n之前的值跟2進行比較?還是將n++之后的值來跟2比較?這里我就直接跟大家說,因為這里的++是后置++,所以我們是先將n之前的值來跟2進行比較,比完之后再將n的值再加上1 ,如果我們這里改一下改成++n的話,那么我們這里就是將n加1之后的值·,再來跟2進行比較。好這時候可能就有小伙伴們放松警惕了給出了類似1 2 3 4 這樣的答案,但是小伙伴發現了沒,我們這里的while語句后面是直接加一個分號的,這說明了什么我們這里是空語句也就是while循環里面的循環體什么都沒有,所以我們這里的printf語句是等while循環結束之后再執行的,所以這里的printf語句就只會執行一次,那么來看while循環結束之后我們的n等于多少,首先我們來看當n等于2的時候我們來執行判斷語句,首先這里的2==2判斷為真,就會執行了下面的循環體于此同時n的值也就會變成3,因為循環體為空,所以我們就又來到了while循環的判斷部分,因為這里的n等于3 所以我們就會判斷為假,所以就會跳出循環,但是因為這里為n++,所以跳出循環的同時n的值會再加上1 ,所以這里的n就變成了4,所以再執行下面的printf語句的時候就會打印出4 。
第二題解析
#include<stdio.h> int main() {int x = 0;int y = 0;for (y = 1; y < 10;){y = ((x = 3 * y, x + 1), x - 1);printf("x=%d,y=%d", x, y);}return 0; }我們這題主要是來帶大家看看逗號表達式在這里的運算,首先我們來回顧一下逗號表達式的知識點:1.逗號表達式的運算順序是從做向右計算2.逗號表達式的值為逗號最右邊表達式的指。那我們再來看這道題首先y的值初始化為1 ,然后判斷部分判斷為真就進入for循環的循環體里面,好我們來看這個循環體的內容為y = ((x = 3 * y, x + 1), x - 1);我們首先來看右邊的內容他是一個逗號表達式因為逗號表達式是從最左邊開始吧,那么我們就來看最左邊,這時候我們就發現這個最左邊的表達式它也是一個逗號表達式,那么這里就是一個逗號表達式里面嵌套一個逗號表達式,那我們就看最里面的逗號表達式:首先最左邊的表達式意思是將y的值乘以3然后再賦值給x,那么我們這里的y是1 乘以3就變成了3所以我們這里的x就變成了3,然后我們再來看下一個表達式x+1,那么我們這里就變成了4,所以我們里面的逗號表達式的結果就變成了4,然后就執行外層的逗號表達式的表達式2 ,它是x-1,又因為x的值為3所以這個外層的逗號表達式的結果就為2 ,然后賦值給y,那么我們第一層循環下來我們的y=2,x=3,進入for循環的判斷部分,判斷為真,那么繼續執行下面的循環體部分,有了第一次循環的經驗我們發現這里的兩個逗號表達式可以將其化簡為先x=3y然后y=x-1,大家可以想想是不是這個意思,那么這樣的話我們這里就簡單了,因為第一次循環之后y的值變成了2,所以第二次循環x就等于6,y就等于5,進入第三循環x就等于3y等于15,然后x就等于了14,進入判斷部分發現不成立就跳出循環執行printf語句,那么我們這里打印的結果就變成了x=15 y=14,看到這里大家應該能夠明白這里的意思,然后大家發現了沒有我們這里的for循環的表達式3是省略了的,因為我們下面的循環體可以改變y的值,所以我們這里的表達式3也就可以省略,而且也不會造成死循環。
第三題解析
#include<stdio.h> int main() {int n = 2;int k = 0;while (k++ && n++ > 2);printf("%d %d\n", k, n);return 0; }其實我們的第三題和第一題有 那么點相似,啊這時候就有小伙伴們會說啦,啊葉超凡啊你這是在水文章吧,搞兩個相似的文章上來,啊大家千萬別誤會了,我們這里還是有個地方值得大家學習的,首先我們這里將n初始化為2,k初始化為0,然后就進入了while語句的判斷部分,首先我們看到這里有個&&操作符它的兩邊的表達式都為真的時候整個表達式才能判斷為真,首先會判斷左邊的表達式,這時我們發現它是k++這是一個后置++,那我們這里是先判斷k再來++,因為我們的k一開始為0所以我們左邊就判斷為假,然后k再++,但是我們這里是&&它的左邊為假的話,那么不管右邊的表達式判斷結果如何整個表達式都會為假,所以我們的編譯器就不會執行右邊的表達式,所以這里的n++就不會執行,所以n的值就不會改變,又因為while后面有分號所以就會執行下面的printf語句,所以我們這里打印出來的值為1 2 .同理哈我們還有個操作符||這個跟&&是同樣的道理,當||左邊的表達式判斷為真的時候就不會執行右邊的表達式,大家這里要注意別搞錯了。看到沒沒水文章吧。
第一題解析
第1題:
首先我們這里求解的是n的階乘,那么我們這里肯定是先得輸入一個n的值的,然后再來計算這個值的階乘,那么這里就來看如何計算這個值的階乘,其實我們之前做個一個類似的題,就是計算累加從1一直加到n,我們當時的代碼時長這樣的:
我們是先創建一個變量i,并且將其初始化為1,表示的是從1開始一直往后加,然后每次循環都會使得i的值加上1 ,然后我們還創建了一個變量n,表示該循環要循環的次數,那么我們這里也就表示的從1開始累加,累加到n為止,這些都完成了那么我們這里就還剩下一個問題就是,如何把這些累加給儲存下來?那么我們這里就可以這樣,再創建一個變量sum,將其初始化為0,每次循環之后將sum的值加上i的值再賦值給sum,這樣我們就可以將每次累加的值儲存起來,這里我們可以梳理一下一開始sum的值為0,i的值為1 ,那么經過第一次循環sum的值就等于0+1=1,i++,i就等于2,再經歷一次循環,因為在上一次循環之后sum的值就變成了1,所以在第二次循環的時候sum的值就變成了1+2=3,同理第三次循環sum的值就等于1+2+3=6,第四次循環sum的值就變成了1+2+3+4=10后面就以此類推。我們就可以得到任何一個數累加的值,那么我們看這里是累加的,那我們的階乘是累乘,所以我們這里就可以照葫蘆畫瓢,我們將變量sum改成變量multiply,并且將其初始化為1,然后每次循環的循環體改成multiply=multiply*i,這樣我們就可以將每次相乘的值存儲下來,這里我們可以推一下,一開始multiply的值為1 ,i的值也為1,那么相乘再賦值可以得到multiply還是1,然后i++,i就變成了2,再經歷一次循環,相乘再賦值multiply的值就變成了12=2,i的值也就變成了3,再經歷一次循環,相乘再賦值multiply的值就變成了了123=6,i的值就變成了4,再經歷一次循環,相乘再賦值multiply的值就變成了1234=24然后我們后面就可以依次類推,我們更具這個循環體就可以得到n的階乘的值。代碼如下:
#include<stdio.h> int main() {int i = 1;int multiply = 1;int n = 0;scanf("%d", &n);while (i <= n){multiply = multiply * i;i++;}printf("%d", multiply);return 0; }第二題解析
第2題:
我們上一題講到了n的階乘如何求解,那么我們這道題講解如何將這些階乘求和,那么我們這里能否將其看成兩個問題,一個是得到不同的階乘的值,另一個就是將這些值進行累加,并且將其放到循環里面進行實現,這里我們可以使用一個內部嵌套的循環的形式,外層循環用于計算階乘的相加,內部的循環用于計算階乘的值,并且內部的循環是放到實現階乘相加的前面,那么這里每一次外部循環就是先計算出階乘的值,再將其相加,這時候我們就有小伙伴們就反應特別塊一下子寫出了代碼這里我們為了方便一點就改成計算到3的階乘:
其實大家可以運行一下這段代碼,大家就會發現在這段代碼是有問題的,答案等于15,可能很多的小伙伴都不是很能理解哈,因為這個代碼很清楚很有道理,咋就出錯了呢?對吧每次循環先計算階乘再把就階乘相加,這不是靠譜他媽給靠譜開門靠譜到了家嗎?咋就錯了呢?好這里我就給大家詳細的一個一個的分析首先我們看階乘的概念是從1乘到指定數,大家記住是從1開始
那我們我們就從循環開始一開始進入for循環將n賦值為1,然后就進入內部的for循環將i賦值為1,因為這里的判斷條件為i<=n所以我們這里就只會循環一次multiply就等于11=1,然后就跳出來內部的循環,sum就等于0+1,好這里外部循環就執行完了一次,n的值就變成了2 ,再繼續執行內部的for循環,一開始將i初始化為1 ,然后根據判斷條件這里會循環兩次,第一次multiply=11 第二次multiply=12=2,然后就跳出了內部循環下面的sum=1+2=3,好這時外部的for循環第二次就執行完了,開始執行第三次我們的n就變成了3,再進入內部的for循環將i初始化為1 ,根據判斷條件這里會循環三次,那我們來看第一次循環,因為根據我們第二次外部循環的結果我們這里的multiply為2 ,我們并沒將其初始化為其他的值,所以在外部第三次循環的內部第一次循環我們的multiply=multiplyi=21=2,第二次multiply=22=4,第三次就是multiply=43=12,因為我們上面說了階乘是從1開始的,而我們的第三次外部循環求3的階乘就變成了從2 開始也就是說從123變成了22*3=12所以這里就是我們造成錯誤的原因,那我們如何進行修改呢?我們可以在外部循環里面講multiply進行一次賦值使得每次循環的開始都能保證multiply是從1開始的,那么我們的代碼如下:
這樣我們的結果就是對的了。當然有些小伙伴們可能覺得這里嵌套的循環不是很好的想,那么我們這里就可以改一下代碼如下:
#include<stdio.h> int main() {int sum = 0;int multiply = 1;int i = 1;int n = 0;scanf("%d", &n);while (i <= n){multiply = multiply * i;//計算階乘sum = sum + multiply;//階乘相加i++;}printf("%d", sum);return 0; }那么這段代碼的運行原理就是:我們3的階乘變成4的階乘的時候,我們是沒有必要再從1開始相乘的,我們可以直接在3的階乘基礎上直接乘以4 ,所以我們的代碼就可以這么寫。
第三題解析
第3題:
這題我也來給大家講兩個寫法好吧,啊有些小伙伴看到這個題的時候一下子就慌了,啊這是算出來的結果是小數啊,這我們怎么能得到小數啊,而且這里的循環一下子是正數,一下子是負數這咋搞啊。大家不要慌哈,首先我們來解決小數的問題,我們之前在講初始c語言的時候說過這么一句話,叫當我們這個(/)操作符的左右兩端只要有一個是小數的時候,我們得到的結果就是小數,所以我們可以把這里的1改成1.0這樣得到的結果就是小數,好這個問題解決了我們再來看如何解決這個減號的問題,我們這里就分為兩種解決的辦法
第一種:雖然這里有加號和減號,但是這里的加減都是有規律的分母為偶數的話就為減,分母為奇數就為+,但是我們知道一件事就是偶數之間相差為2 ,奇數之間相差也為2 ,那么我們這里可以先計算出都是相加的情況就是1/1+1/2+1/3+1/4…+1/100,然后再減去兩倍的1/2+1/4+1/6+…1/100,如果是這樣的話,那就很簡單了嘛這不就是兩個循環嗎,而且第二個循環不就是講將i++改成i+=2嘛,那我們的代碼實現如下:
解法2
因為這里是一個正數接一個負數,而且之前我們在講操作符的時候提到過(-)這個操作符,可以使正數變成負數,還可以使得負數變成正數,那么我們這里可以創建一個變量signed并且將其初始化為1,每次計算的時候可以將它乘以變量i,在計算完之后在下面執行signed=-signed這個操作,這樣就可以使得在下一次循環的時候signed變成負數,他變成了負數也就表明這里變成了減號,而且在下下次循環他又會變成正數,那也就又變成了加號那么我們的代碼如下:
第四題詳解
第4題:
這題要我們求兩個數的最小公倍數,那我們先來看看最小公倍數的概念是什么?首先創建兩個正整數a,b然后我們a和b的公倍數設為c,那么這個c%a是等于0的并且c%b也是等于0的,那么我們稱這個c為a和 b的公倍數,其實c是有非常多的值的,比如說a*b這就是一個非常容易得到值,但是這只是其中一個我們這里要求這所有公倍數中最小的一個,那么我們這里就將這個數稱為最小公倍數。這里我們給出兩種方法來球這個數
第一種:
其實大家可以在生活中發現這么一個規律就是:如果求解一個問題有多種方法的話,那么越是簡單的方法他的計算量越大,越是難以理解的方法他的計算量就越小,那么我們這里的第一種方法就是最簡單最容易想到的方法我們將他稱為窮舉法,首先我們要想的一個問題就是這個最小公倍數會不會比那兩個數都小肯定不會,那么這個數會不會比這兩個數中的較大的數小,也不會那么這個數一定是比這兩個數都要大,那么我們就可以創建一個變量將他的值附值為最大的值,然后將這個變量%a和b,只要有一個%出來的值不等于0那么這個數就不是a和b的公倍數,那么我們就將這個值加1,再繼續嘗試直到%a和b的值都等于0的時候,我們就可以找到公倍數,并且那個數還是最小的,因為前面的數都不是公倍數,那么我們這里就可以使用while循環后面表達式寫成(x%a!=0||x%b!=0)然后循環體里面就可以直接寫成x++來表示驗證下一個數是不是最小公倍數:
第二種方法:
其實大家可以感覺的到,我們的第一種方法十分的無腦,這不就是一個一個的找嘛,而且這個方法的效率也非常的低,那我們來看這個有沒有非常快的解決辦法,首先我們想啊,我們先創建一個變量n將其賦值為這兩個數的最大的一個數,這里我們假設較大的數是a,較小的數是b,然后我們上一個方法是每次循環都加1 ,但是大家發現沒有其實這個1,他加的有點多余的,或者說加的有點小,那我們試著能不能加一個更大的數呢?每次都加一個更大的數,是不是就可以更快的到達目的地,那這個更大的數如何來找呢?好我們一開始是將n賦值為啊a,那么這時候這個n%a是不是一定等于0,但是n%b就不一定吧,那么我們這個時候再讓n的值加a的話,是不是%上a還是等于0,兩倍嘛!但是%b的話是不是也不一定,但是我們這里是循環嘛,我們可以一直重復直到找到為止,那么這里可能有小伙伴感到疑惑為什么每次都加這個最大的數呢?加一個小一點的不行嗎?或者加個更大的不行嗎?大家這里可以這么想,我們之所以每次都加最大的數是因為我們要保證這個數首先得是a的倍數,然后再來測試是否為b的倍數,我們本來一開始就是a的倍數你加一個比a小的數他還能是a的倍數嗎?肯定就不是了嘛,好這時候有小伙伴們說那更大的呢?我一下子不能加2a嗎?它也可以保證是a的整數倍啊。那么這里確實是a的整數倍,我們不停的循環下去也確實是可以找到b的整數倍的數,但是大家要記住我們這里要求的是最小公倍數,一下子加兩倍的a的話很可能會導致找到了公倍數但不是最小的,所以大家這里要注意一下,看到這里大家應該能夠明白這道題的做法了,我們來看一下代碼。
這里大家看的可能有點難受,這里主要是想讓大家熟悉一下條件操作符。
第五題解析
第5題:
上面講了如何求得最小公倍數,那么我們這里來講講如何求得最大公約數,大家感覺我這里的設計是不是還挺合理的。我們先來看看最大公約數的概念:這里我們就簡述一下:我們假設一個為x,如果m能整除x,并且n也能整除x,那么我們就稱x為m和n的公約數。當然這個x有好多個數,我們要求最大的,那么我們這里同樣有兩個方法來求解:
第一個方法:
首先創建一個變量x,那么我們首先可以知道的是x的值一定不會大于這兩個數的最小值的,那么我們就可以將這個數賦值為這個較小的數,那么這樣我們就可以確定了x這個最大公約數的范圍,那么我們這里就可以一個一個的將其試出來,這里我們可以使用while循環,且后面括號里面的表達式為
(a % i != 0 || b % i != 0)這個就可以來判斷是否為最大公約數,并且每次循環都讓i的值減一,如果i的值等于1 的話,我們這里就用break跳出循環,因為1就是下線了,這里跟上面的例子差不多這里大家可以參考上面的步驟照葫蘆畫瓢其代碼如下:
第二個方法:
這里我們就用輾轉相除法來寫這個題,但是我們這里就不介紹這個輾轉相除法的原理了,因為我們這里主要是要大家體會循環的運用,那么輾轉相除法的運算過程是:第一步:對于兩個整數m和n,使得m>n 。第二步:取余數r=m%n。第三步:若r=0,則n為取得的最大公約數,否則執行m=n;n=r;r=m%n。我們來舉一個例子吧,我們求24和18的最大公約數,那么這里就m等于24,n等于18,r=24%18=6不等于0,那么就讓m=18,n等于6,再計算r的值r=18%6=0,所以我們這里的最大公約數就為n=6 。 那么我們這里就可以發現其實這里是有一個循環的,而且跳出循環的條件就是r=0,那么我們這里就可以使用while循環,因為當r不等于0的時候我們會繼續輾轉相除,所以我們這個循環繼續的條件就是r!=0,那么我們就可以將這個表達式放到while后面的括號里面,那么這道題的思路也就非常的清楚了,首先輸入兩個值,然后再找到這兩個值的最大值,再用循環實現輾轉相除法,那么這道題的代碼如下:
這個方法是不是就比我們一個一個試來的快的多啊,那么我們這道題就說到這。
第六題解析
第6題:
我們來解個方程,這里我們根據高中的知識其實可以知道這里是個?,但是我們發現在這個園還非常的大,那么我們這里是很明顯不能將其一個一個的列出來的,但是我們這里可以使用循環結構呀,我一個一個的嘗試很麻煩,但是電腦就很快啊,而且我們的方法還十分的簡單題目已經告訴了我們計算的公式,首先我們知道這里是x方,和y方,然后要求的還是正整數的解,那么我們這里可以知道的是x的值肯定是小于45的,因為45*45等于2025它已經大于了1989,而且同理可得我們的y值它也是要小于45的,并且還是正整數,那么x和y的值就是從1開始,那么我們這里是不是可以將所有的可能全部列出x是從1到45,y是從1到45,我們是不是就可以使用循環的嵌套將所有的坐標到原點的距離全部算出來然后再與1989進行比較如果等于的話就將其寫出來那么這里我們就可以使用循環的嵌套實現,代碼詳細如下:
第七題解析
第7題:
首先我們來看看素數的概念:數學上指在大于1的整數中只能被1和它本身整除的數。如2、3、5、7、11、43、109,那我們如何求解素數呢?這里我們也可以使用窮舉法,比如說一個數n,我們要判斷他是不是素數,那么我們是不是可以用循環的方法將他除以大于1小于n-1的所有數,如果發現其中只要有一個數能夠將他整除,那么說明這個一定不是素數,如果所有的數都試完了,還是不能整除的話,就說明他是素數,那么我們的代碼如下:
#include<stdio.h> int main() {int n = 0;int i = 2;scanf("%d", &n);for (i = 2; i < n; i++)//一個一個的檢查是否為素數{if (n % i == 0)//判斷是否可以整除{printf("%d不是素數\n", n);break;}}if (i == n)//判斷為素數{printf("%d是素數", n);}return 0; }好一個數是否為素數我們判斷完了,那么接下來我們就要將這些數全部都加起來,那么這里我們是不是可以在外面再加上一個循環,這個循環就是產生2到n的各個值,并且外面這個外部循環還可以將所有的素數加起來,那我們這里可以類比之前的題的做法,但是我們這里要加的數是素數,那么我們的代碼實現如下:
#include<stdio.h> int main() {int n = 0;int i = 2;int j = 0;int sum = 0;scanf("%d",&n);for (j = 2; j <= n; j++)//該循環的作用是產生2~n的數{for (i = 2; i <j; i++)//該循環用于判斷是否為素數{if (j % i == 0){break;}}if (i==j)//判斷為素數則將其相加{sum = sum +j;}}printf("%d", sum);return 0; }大家可以自己多多嘗試
第八題解析
第8題:
我們看到這道題,首先他給出了完數的概念,首先我們是不是得得出一個數的所有的因子,那么我們這里是不是就可以用到窮舉法,將這個數%上除了他自己本身以外的所有數,如果%之后等于0那么就說明這個數是因子,那么我們這里求的是所有的因子,那么我們是不是得要一個循環來得出所有的因子,然后將所有的因子加起來,那么我們的代碼如下:
#include<stdio.h> int main() {int i = 0;int j = 0;int sum = 0;scanf("%d", &j);for (i = 1; i < j; i++)//列出所有的初速{if (j % i == 0)//判斷死否是因子{sum = sum + i;//將所有的因子相加}}if (sum == j)//判斷是否是完數{printf("%d是完數\n", j);}else{printf("不是完數\n");}return 0; }好這里我們知道了如何判斷一個數是否為完數,那么我們的題目的要求是將所有1000以內的完數的和,那么我們這里就需要一個外層循環來列出所有的數,再通過內部循環篩選出完數,再將他們全部打印出來,大家這里要注意一下,因為我們這里是循環的嵌套,所以我們每次外部循環執行一次之后記得要將sum的值賦值為0,以確保下面的判斷能繼續執行,那么我們的代碼如下:
#include<stdio.h> int main() {int i = 0;int j = 0;int sum = 0;for (j = 2; j <= 1000; j++){sum = 0;//大家注意這里要初始化for (i = 1; i < j; i++)//列出所有的初速{if (j % i == 0)//判斷死否是因子{sum = sum + i;//將所有的因子相加}}if (sum == j)//判斷是否是完數{printf("%d是完數\n", j);}}return 0; }第九題解析
第9題:
我們再來看一下這個題:首先我們可以看到這個題首先我們可以知道,每一項的分子為前一項的分子和分母的和,然后每一項的分母為前一項的分子,首先這個規則是從第二項開始的,那么我們這里的第一項是2/1,所以我們這里是不是就可以創建三個變量一個用來儲存分子,一個用來儲存分母,一個用來儲存相加的值,假設分母為y分子為x,那么下一項的分母就等于x,下一項的分子就等于x+y,但是大家在寫代碼的時候要注意一點的是我們要先賦值分母再來賦值分子,大家可以自行思考一下為什么,那么我們一開始將x初始化為2,將y初始化為1 ,再通過循環來實現累加sum=sum+x/y,因為我們這里要得到小數所以我們在x的前面乘以1.0,用來得到小數那我們的代碼實現如下:
第十題解析
第十題:
這里我們來看一下這個題怎么來做哈,這里我們講兩個方法:
第一種:
首先我們可以得到這是一個數組,我們要在一個數組里面找到一個數字n,那么首先我們要知曉的一件事情就是我們這個數字很可能是找不到的,我們這里就得分兩種情況一個是找的到,另一個就是找不到,因為這里是一個數組,數組里面裝的數肯定是有限的,那么我們這里就可以用循環來一個一個的找,我每一個數組的元素都對比一下,是不是就可以找到了,那么我們這里假設一個數組有十個元素,數組的元素為1 2 3 4 5 6 7 8 9 10我們要找7這個元素,如果找到的話我們就返回這個元素的下標,那么我們這里通過循環用一個一個比較的方法來實現這個功能代碼如下:
第二種方法:
其實大家可以發現我們上面的方法在做題的時候其實效率是非常的低的,因為我要從頭開始尋找,如果我們要找的那個數在末尾的話,那么我們這個方法就非常的吃虧,如果這個數組的數據還非常的多的話,那么我們這個查找的效率其實是非常的低的,那么這里大家在讀題的時候是否發現了這個點沒?我們的數組其實是一個有序的數組,也就是說我們的數組里面的元素其實是按由小到大的規律遞增的,那么我們是不是就可以使用這個規律呢?好這里我們先創建三個變量一個是left表示最左邊的數,一個是最右邊的數表示right,一個是mid表示中間的數,那么我們這個mid就等于(left+right)/2,然后我們假設我們要找的數大小為k,那么這里我們就用下標為mid所對應的數來和k進行比較,如果k大于下標為mid所對應的數,那么這里我們就可以知道k的值所對應的下標其實是在mid和right之間,那么我們這里就要縮小范圍我們就將left等于mid+1,那么我們這里的mid就等于新的(right+left)/2,然后繼續進行比較,那么如果k的值小于下標為mid所對應的數呢?那么我們這里就將right等于mid-1;來縮小范圍然后繼續用新的mid來繼續進行判斷,那么這里大家其實可以看的出來這里是一個循環,那么既然是循環的話,我們就得要有讓循環停止下來的條件,這里我們可以將條件分為兩種:第一種就是找到了,那么這個條件就非常好的得出來,我們可以使用if語句如果arr[mid]=k我們就可以通過break語句來跳出循環,另外一個循環終止的條件就是當我們這樣不停的求出mid再將mid-1的值賦給right或mid的時候我們肯定會出現一種情況就是left的值大于right出現這樣的情況就表明這個數在我們的數組里面是不存在的,我們來看個例子假設數組的元素為0 1 2 3 4 5 6 8 9 10,我們要找7這個數所對應的下標,那么我們這里一開始left的值等于0 ,right等于9,所以根據計算我們這里的mid就等于了4,下標4所對應的數組的元素就為4,4的值是小于7的,那么我們這里就將left的值賦值為4+1=5,所以這里我們再計算以下mid的值就等于(5+9)/2=6,而下標為6所對應的值為6,而6還是小于7,所以left就等于6+1=7,mid就等于(7+9)/2=8,下標為8對應的值為9,這時9是大于7的,所及我們就將right的值改為8-1=7,而mid就等于(7+7)/2=7,但是下標7所對應的值為8,還是大于7,所以right就等于7-1=6,好這時候就出現了right小于left的情況就說明了這里是找不到該值的下標的,那么希望大家能夠理解這個方法我們的代碼實現如下:
其實看到這里我們上面有個地方可能會出現錯誤不知道大家發現沒,我們的mid=(left+right)/2,但是這里的相加之和的值超出了int的范圍的話,是不是就會出現問題呢?我們在除以2的話得到的結果視乎就不一樣了吧,那么我們這里就可以將他改一下改成(left+(right-left)/2)就不會出現這樣的情況我們將right相較于left多出來的一部分切一半再加到left的頭上是不是就不會產生超出范圍的情況了,這里大家好好體會一下。那么本篇文章就結束了大家好好體會一下,這里為了大家更好的學習本篇文章的所有代碼點擊下面鏈接可以查看:
點擊此處查看
總結
以上是生活随笔為你收集整理的c语言习题---(循环语句)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [MindManager]“R6025
- 下一篇: Golang基于学习总结