發表文章

陣列中的陣列之亂數九宮格~~

看到題目時,我思考邏輯上是用亂數直接給予九宮格數值, 一格一格走00,01,02,10,11,12,20,21,22,並在每一格用counter驗證生成的亂數數值是否出現過(0無1有),再配合while迴圈直到生出未出現的亂數,然後再給予當下位置數值,不過似乎可讀性很差.... 最近有點挫折,原本一點就通的感覺,在進入陣列後慢慢要花更多時間消耗範例裡面的用法與為什麼這樣寫的思考邏輯,好像在走天堂路.....不過解開也是很有成就就是了.... #include<stdio.h> #include<stdlib.h> #include<time.h> int main(){ srand(time(0)); int i,j,c; int n[3][3]; int counter[9]={0}; ///////用於檢查生成數值是否出現過 for(i=0;i<3;++i){ /////一共3列 for(j=0;j<3;++j){ /////一共3行 while(1){ c=rand()%9+1; ////生成亂數0~9 if(counter[c-1]==0){ ////檢查生成的亂數是否出現過(有的話回到while重新生成) counter[c-1]++; ////未出現數值則該數值計數器+1,+1後即為已使用過。 break; ////停止生成亂數,讓變數c停留該數值。 } } n[i][j]=c; ////將亂數新生成且未使用過的數值放入該位置。 } } for(i=0;i<3;++i){ /////列印迴圈-第一列、第二列、第三列 for(j=0;j<3;++j){ /////列印迴圈-第一行、第二...

陣列中的陣列(二維思維基本運用概念)【重要】

如題所述,以下程式演繹兩種方式詮釋陣列中的陣列類似二維【n[3][3]】,其實在電腦記憶體中所記錄的還是等於9個int空間,且是連續的,並不是像我們所想的二維方式,這個二維是使用者所想像出來的。 記憶體與實際紀錄 *n[0][0]**n[0][1]**n[0][2]**n[1][0]**n[1][1]**n[1][2]**n[2][0]**n[2][1]**n[2][2]* ***int******int*****int******int*****int******int*****int******int******int** 範例的二維想像: *****J***** ****j0*j1*j2* **i0  1   2   3 i *i1  4   5   6 **i2  7   8   9 *********** 下面範例用兩種方式詮釋陣列中的陣列,陣列n則是在宣告時以定義好每個陣列中int的數值,當然列印方式可以是一個與記憶體相同連續不換行的數字,但這邊我是想像成二維方式列印出來,所以運用了兩層for迴圈加上換行去列印n陣列已達成我想像的二維。 另外陣列g則是利用For迴圈條件判斷,以及counter++給予其數值。 【for(i=0;i<3;++i)】是第一個[3],其用於印出三組 n[0][ ],n[1][ ],n[2][ ] ; 【for(j=0;j<3;++j)】是第二個[3],其用於印出每組內容值 n[ ][0],n[ ][1],n[ ][2] ; #include<stdio.h> int main(){ int i,j,k=10; int n[3][3]={ {1,2,3}, {4,5,6}, {7,8,9} }; int g[3][3]; for(i=0;i<3;++i){ for(j=0;j<3;++j){ ++k; g[i][j]=k; } } for(i=0;i<3;++i){ for(j=0;j<3;++j){ printf...

泡沫排序法(陣列)

泡沫排序,由陣列中每一個位置已有的數值,進行由左至右(++)倆倆比較的方式 #include<stdio.h> int main(){ int i,t,j,n[5]; for(i=1;i<=5;++i){ scanf("%d",&n[i-1]); } for(i=0;i<4;++i){                ////執行4輪由第n[0]開始的兩兩比較 for(j=0;j<4-i;++j){     ////執行每輪倆倆比較,最大值搬遷至最右(後),而-i是因為最後的已經為最大值(陣列最後組不必再比較) if(n[j]>n[j+1]){ t=n[j]; n[j]=n[j+1]; n[j+1]=t; } } } for(i=1;i<=5;++i){ printf("%d ",n[i-1]); } return 0; }

產生不重複的亂數 (使用陣列)-2-(亂數組-交換法)

延續上一篇用紀錄數值到陣列、紀錄數值出現次數的計數(建表法),另外嘗試用另一個方式來解出試題,這方式(交換法)是將數值依序記入陣列中【即n[0]=1,n[1]=2......n[9]=10】,接下來用亂數取得要交換的組別,直到全部完成。 #include<stdio.h> #include<stdlib.h> #include<time.h> int main(){ srand(time(0)); int i,n[10]={0}; for(i=1;i<=10;++i){ n[i-1]=i;              /////數值依序紀錄在陣列中 } for(i=1;i<=10;++i){  ////至於為什麼減11,因為一共剩下X組可交換 (第1次有10組) int j=rand()%(11-i)+i;   ////j為亂數,用於指定交換陣列的組別。 int t=n[i-1];    ////將第n[i-1]組數值搬入t,第一次就是n[0]。 n[i-1]=n[j-1]; ////將第n[j]組搬入n[i-1],亂數5給j,就是n[j-1]搬過去n[i-1] n[j-1]=t;     ////再將原來的n[i-1]組的數值暫存在t的搬過去n[j-1]。 printf("%d ",n[i-1]); } return 0; } 因為j為亂數,也是要交換的指定組別,所以也是等於隨機交換的。 做counter、swap在許多思考與應用上很重要,有時也很有用,這裡是將counter、swap運用在陣列上。

產生不重複的亂數 (使用陣列)

亂數產生10組數字(1~10),不可以重複 第一個方法是紀錄輸入的數字到陣列,然後每次都要比對陣列中每一個儲存的數字是否出現過。 這裡的n是從幾個數字來看(可無範圍限制),亂數出69就紀錄69在當時i為多少的n[i]陣列裡面。 #include<stdio.h> #include<stdlib.h> #include<time.h> int main(){ srand(time(0)); int i,j,n[10]={0}; for(i=1;i<=10;++i){ do{ n[i-1]=rand()%10+1; for(j=1;j<i;++j){ if(n[i-1]==n[j-1]){ break; } } }while(j!=i); printf("第%2d號: %2d\n",i,n[i-1]); } return 0; } 第二個方式是用counter陣列來計算每一個號碼出現過幾次,此試題條件僅能出現一次,所以概念是要為計數器要為0才可以使用。(建表法) 這裡的n是以數值範圍來看,1~1000的話,就需要有1000個counter。 #include<stdio.h> #include<stdlib.h> #include<time.h> int main(){ srand(time(0)); int i,n,counter[10]={0}; for(i=1;i<=10;++i){ do{ n=rand()%10+1; }while(counter[n-1]!=0); printf("%d ",n); counter[n-1]++; } return 0; }

求平均、最大值(運用陣列與函式)

這次是一樣輸入10個數值,求出最大值與平均值。 首先先用最簡易但卻不夠清楚條理分明的,雖然在執行上可能會比較有效率,但卻在撰寫時可能會造成不良的可讀性,若在程式量開始大時,在擴充與修改以及Debug方面可能會造成困擾甚至混亂等等。 簡易式運行可能有效率,但是可讀性不良與擴充較為不便: #include<stdio.h> int main(){ int i,n[10]; int sum=0,avg,max=n[0]; for(i=0;i<10;++i){ scanf("%d",&n[i]); sum=sum+n[i]; if(n[i]>max){ max=n[i]; } } printf("%d\n",sum); avg=sum/10; printf("MAX: %d\nAVG: %d\n",max,avg); return 0; } 再來運用函式將其功能分開,條理分明許多: #include<stdio.h> int avg(int n[]); int max(int n[]); int main(){ int i,n[10]; for(i=0;i<10;++i){ scanf("%d",&n[i]); } printf("MAX: %d\nAVG: %d\n",max(n),avg(n)); return 0; } int avg(int n[10]){ int avg=n[0]; for(int i=1;i<10;++i){ avg=avg+n[i]; } return avg/10; } int max(int n[10]){ int max=n[0]; for(int i=1;i<10;++i){ if(n[i]>max){ max=n[i]; } } return max; } 程式是一種建立解決方式以及選擇解決路徑,有時候又需要規劃欲想未來式,多多練習思考多樣性有益於解讀條件與創造解決...

求小範圍的眾數

雖然陣列基本使用方式不難理解,但經過多種不同條件題目的練習,體會到困難的地方在於運用方式,其實解一個問題每個人都有不同見解,但結論都是要符合條件,讓自己可以更有效率且撰寫得更清楚明白,是需要多多省思的,下面題目雖然不難,解法也有很多種,如何靈活運用陣列特性來解決,才是多練習的其中一個大目的。 輸入10組個位數,求小範圍的眾數(相同時取大者為解) e.g:1,3,9,7,3,8,6,8,2,2,ANS=8(8>3>2) #include<stdio.h> int main(){         int g[10]={0};//陣列g的[10]分別為0~9,我們可以利用它的編號(也就是         int i,n;             //輸入的個位數)與內容關係來取的答案。姑且用n當作代         for(i=1;i<=10;++i){      //號來靈活運用                 scanf("%d",&n);                 g[n]++;         }         int ans=0;                    //暫時為最眾         for(n=1;n<10;++n){   //輸入1~9數值分別存在n數裡(1有x個....2有x個....)                 if(g[n]>=g[ans]...

畫數字統計長條圖的練習 (使用陣列)

看到題目時自己先撰寫一次,很燒腦~ 輸入10組 0~100之間的 數字,畫出以10為區分的*長條圖。(0~10,10~20......90~100) #include<stdio.h> int main(){ int i,j,n[10]={0},star[10]={0}; for(i=1;i<=10;++i){ scanf("%d",&n[i-1]); } for(i=1;i<=10;++i){ int a=n[i-1]; for(j=1;j<=10;++j){ if(a>(j-1)*10 && a<=j*10){ star[j-1]++; } } } for(i=1;i<=10;++i){ printf("%3d: ",10*i); for(j=1;j<=star[i-1];++j){ printf("*"); } printf("\n"); } return 0; } 看完課程以後開始認為自己的不足,在給予條件時的思考模式太過笨拙了,重新理解知道了看條件的角度不同決定程度的不同,不過想必這也是成長的過程之一。 再把100區分為10分的範圍,一共有10個(0~10,11~20,21~30....),陣列相對於0~9一共10個區塊,輸入數字可除10的商數可以對應到陣列區塊,不過記得要減1,因為例如20/10=2,而陣列是從0(0~10)開始,故2就變成21~30的區間了,所以我們應該要把數值減1後再/10得其商數【 n[(30-1)/10]++ 】,這樣n[2]就會+1了(n[2]是數值在範圍21~30的計數統計),這樣可以對應到計數器n[ ]之中對應的位置。 #include<stdio.h> int main(){ int t[10]={0}; int i,j,n; for(i=1;i<=10;++i){ scanf("%d",&n); t[(n-1)/10]++; //計數器 } for(i=1;i...

尋找相近值(相同距取小值)【陣列練習運用】

在邏輯思考上有時候會因為條件與敘述方式不同而讓自己的思緒卡彈,有時候是會而無法融會貫通,所以在不同背景與人事物各方面的差異,在練習題過後,實做上會遭遇到種種困難,必須要仔細去品嘗製作範例者的思維,了解後嘗試著自己建立,既使遇到困難處或Bug處,因為思慮比較清楚且有概念的狀態下,解決上並不會有太大的問題,除了多練習,還是要好好了解他人的程式結構與思考邏輯。 練習範例如下: #include<stdio.h> #include<stdlib.h> int main(){ int i,n[10],ask; for(i=1;i<=10;++i){ scanf("%d",&n[i-1]); } while(1){ for(i=1;i<=10;++i){ printf("%d ",n[i-1]); } printf("\n"); printf("ASK: "); scanf("%d",&ask); if(ask==0){ break; } int ans=n[0],near_d=abs(n[0]-ask); for(i=1;i<10;++i){ int d=abs(n[i]-ask); if(d<near_d ||(d==near_d&&n[i]<ans)){ ans=n[i]; near_d=d; } } printf("%d\n",ans); } return 0; }

很燒腦的陣列比較運用

輸入10數值 再輸入1數值 找出最接近的數值 若有相等則取最小 #include<stdio.h> #include<stdlib.h>//abs無論正負數皆為給正數值,例-5給5 int main(){ int i,n[10],g; for(int a=1;a<=10;a++){ scanf("%d",&n[a-1]); } while(1){ printf("key an integer:"); scanf("%d",&g); if(g==0){ break; } int near_n=n[0],near_d=abs(g-n[0]); //陣列組內內容///目標值與比較組差距 for(i=1;i<10;++i){ int d=abs(g-n[i]);//此d為目標值比較另一個陣列位置 if(d<near_d || (d==near_d &&n[i]<near_n)){ near_d=d;//目標值差距 near_n=n[i];//組別內數字 } } printf("near_d:%d\n",near_d); printf("near_n:%d\n",near_n); } return 0; }