c++語言基礎數組_第1頁
c++語言基礎數組_第2頁
c++語言基礎數組_第3頁
c++語言基礎數組_第4頁
c++語言基礎數組_第5頁
已閱讀5頁,還剩35頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第五章第五章 數組數組 第一節(jié)第一節(jié) 一維數組一維數組第二節(jié)第二節(jié) 二維數組二維數組第三節(jié)第三節(jié) 字符數組和字符串類型字符數組和字符串類型第一節(jié)第一節(jié) 一維數組一維數組一、為什么要使用數組通過前面幾章的學習,我們已經可以編寫程序來解決各種相當復雜的問題了,但是當需要處理的數據比較多時,僅依靠前面的知識是不夠的,即使簡單的問題也可能需要比較復雜的程序來處理。請看下面的例子:例題:輸入50個學生的某門課程的成績,打印出低于平均分的學生序號與成績。【分析】在解決這個問題時,雖然可以通過一個變量來累加讀入的50個成績求出學生的總分,進而求出平均分。但因為只有讀入最后一個學生的分數后才能求得平均分,并且

2、要求打印出低于平均分的學生序號和成績,故必須把50個學生的成績都保留起來,然后逐個和平均分比較,把低于平均分的成績打印出來。如果,用簡單變量a1,a2,,a50存儲這些數據,要用50個變量保存輸入的數據,程序片斷如下:cina1a2a10;cina41a42a50;注意,如果真正要像上面這樣編寫程序,則上面的所有省略號必須用完整的語句寫出來。可以看出,這樣的程序是多么繁瑣。如果說處理的數據規(guī)模達到成千上萬,上面的例子單單讀入就會異常復雜,電腦的優(yōu)勢沒有得到體現。從以上的討論可以看出,如果只使用簡單變量處理大量數據,就必須使用大量只能單獨處理的變量,即使是簡單問題也需要編寫冗長的程序。選手們可能

3、已經看出,我們需要把一大批具有相同性質的數據組合成一個新類型的變量,可以用簡單的程序(比如循環(huán)50次)對這個新變量的各個分量進行相同的處理,每個分量仍然保留單個變量的所有性質(在上面的例子中,各分量是整型變量或實型變量的性質)。如果能像數學中使用下標變量ai形式表示這50個數,則問題就容易實現。在C+語言中,具有下標性質的數據類型是數組。如果使用數組,上面的問題就變得十分簡單、清晰。例如,讀入50個學生的成績,只需寫如下語句即可: for (int i=1;iai;在這里引用了帶下標的變量(分量變量稱為數組元素)ai來代替a1,a2,a50,方括號中的i稱為下標,當循環(huán)變量i=1時ai就是a1

4、;當i=2時ai就是a2;當i=50時ai就是a50。輸入的時候,讓i從1變化到50,循環(huán)體內輸入語句中的ai也就分別代表了a1,a2,a50這50個帶下標的變量。這樣上述問題的程序可寫為:tot = 0;/ tot存儲50個學生的總分for (int i=1;iai; tot+=ai;ave= tot/50; /計算平均分for (int i=1;i=50;+i)if (aiave) coutNo. i ai;/如果第i個同學成績小于平均分,則將輸出這個學生的序號和成績。 要在程序中使用下標變量,必須先說明這些下標變量的整體為數組,即數組是若干個同名(如上面的下標變量的名字都為a)下標變量的

5、集合,這些變量的類型全部一致。二、一維數組的定義當數組中每個元素只帶有一個下標時,我們稱這樣的數組為一維數組。數組的定義格式如下:類型標識符 數組名常量表達式說明:數組名的命名規(guī)則與變量名的命名規(guī)則一致。常量表達式表示數組元素的個數??梢允浅A亢头柍A浚荒苁亲兞?。例如:int a10; /數組a定義是合法的 int bn; /數組b定義是非法的三、一組數組的引用通過給出的數組名稱和這個元素在數組中的位置編號(即下標),程序可以引用這個數組中的任何一個元素。一維數組元素的引用格式:數組名下標例如:int a10; 其中,a是一維數組的數組名,該數組有10個元素,依次表示為: a0,a1,a

6、2,a3,a4,a5,a6,a7,a8,a9。 需要注意的是:a10不屬于該數組的空間范圍。 當在說明部分定義了一個數組變量之后,C+編譯程序為所定義的數組在內存空間開辟一串連續(xù)的存儲單元。例如:上例中的a數組在內存的存儲如表所示: a數組共有10個元素組成,在內存中10個數組元素共占10個連續(xù)的存儲單元。a數組最小下標為0,最大下標9。按定義a數組所有元素都是整型變量。 再次提醒注意:類型和變量是兩個不同概念,不能混淆。就數組而言,程序的執(zhí)行部分使用的不是數組類型而是數組變量。說明: (1)下標可以是整型常量或整型表達式。如果使用表達式作為下標,就要計算表達式的值以確定下標。(2)C+語言中

7、,每個數組第一個元素的下標都是0,因此第一個元素為第0個數組元素。(3)C+語言只能逐個引用數組元素,而不能一次引用整個數組。例如:int a100,b100; a=b;這樣的寫法是非法的。(4)數組元素可以像同類型的普通變量那樣使用,對其進行賦值和運算的操作,和普通變量完全相同。例如: c10=34;實現了給c10賦值為34。四、一維數組的初始化 數組的初始化可以在定義時一并完成。格式: 類型標識符 數組名常量表達式=值1,值2,例如:int a5=1,2,3,4,5說明:(1)在初值列表中可以寫出全部數組元素的值,也可以寫出部分。例如,以下方式可以對數組進行初始化:int x10=0,1,

8、2,3,4;該方法一次僅對數組的前5個元素依次進行初始化。(2)對數組元素全部初始化為0,可以簡寫為:0。例如: int a5=0; 將數組a的5個元素都初始化為0。五、一維數組的應用例5.1 輸入n個數,要求程序按輸入時的逆序把這n個數打印出來,已知整數不超過100個。也就是說,按輸入相反順序打印這n個數?!痉治觥课覀兛啥x一個數組a用以存放輸入的n個數, 然后將數組a中的內容逆序輸出。#include#includeint a100;int a100;int main()int main() int x,n=0; int x,n=0; while(scanf(%d,&x)=1) an+=x

9、; / while(scanf(%d,&x)=1) an+=x; /相當相當an=x;n+;an=x;n+; for (int i=n-1;i=1;-i) for (int i=n-1;i=1;-i) printf(%d ,ai); / printf(%d ,ai); /注意注意%d%d后面有一個空格,保證行首行尾均無空格后面有一個空格,保證行首行尾均無空格 printf(%dn,a0); printf(%dn,a0); return 0; return 0; 【說明】: 語句int a100聲明了一個包含100個整型變量的數組,它們是:a0,a1,a2,a99。注意,沒有a100。在上述程序

10、中,數組a被聲明在main函數的外面。只有放在外面時,數組a才可以開得很大;放在main函數內時,數組稍大就會異常退出。它的道理將在后面討論,只需要記住規(guī)則即可。 數組不能夠進行賦值操作:如果聲明的是int aMAXN,bMAXN,是不能賦值b=a的(Pascal語言可以的)。如果要從數組a復制k個元素到數組b,可以這樣做:memcpy(b,a,sizeof(int)*k)。當然了,如果數組a和b都是浮點型的,復制時要寫成memcpy(b,a,sizeof(double)*k)。如果需要把數組a全部復制到數組b中,可以寫得簡單一些:memcpy(b,a,sizeof(a)。使用memcpy函數

11、要包含頭文件cstring。 例5.2 將a數組中第一個元素移到數組末尾,其余數據依次往前平移一個位置?!痉治觥繛橥瓿深}目所要求的操作,其算法應該包括以下幾個主要步驟: 把第一個元素的值取出放在一個臨時單元 temp中; 通過 a2a1, a3a2, a4a3, anan-1,實現其余元素前移 將 temp值送入an. #include#include /調用setw函數需注明使用該庫const int n=10;using namespace std; int an,temp; int main() coutread n datasendl;for (int i=0; iai;temp=a0

12、;for (int i=0; in-1; +i) ai=ai+1;an-1=temp;coutResult:endl;for (int i=0; in; +i) coutsetw(3)ai; /setw函數控制輸出場寬return 0; 運行結果 : read 10 datas: 1 2 3 4 5 6 7 8 9 10 Result: 2 3 4 5 6 7 8 9 10 1 例5.3 賓館里有一百個房間,從1-100編了號。第一個服務員把所有的房間門都打開了,第二個服務員把所有編號是2的倍數的房間“相反處理”,第三個服務員把所有編號是3的倍數的房間作“相反處理”,以后每個服務員都是如此。當

13、第100個服務員來過后,哪幾扇門是打開的。(所謂“相反處理”是:原來開著的門關上,原來關上的門打開。)【分析】此題較簡單,用a1,a2,an表示編號為1,2,3,,n的門是否開著。模擬這些操作即可,參考程序如下:#include#include#define MAXN 100+10int aMAXN;int main()int n,k,first=1;memset(a,0,sizeof(a); for (int i=1;i=100;+i) for (int j=1;j=100;+j) if (j%i=0) aj=!aj;for (int i=1;i=100;+i) if (ai) if(fir

14、st) first=0; else printf( ); printf(%d,i); printf(n);return 0;運行結果:14 9 16 25 36 49 64 81 100【說明】: memset(a,0,sizeof(a)的作用是把數組a清零,它在cstring中定義。雖然也能用for循環(huán)完成相同的任務,但是用memset又方便又快捷。另一個技巧在輸出:為了避免輸出多余空格,設置了一個標志變量first,可以表示當前要輸出是否為第一個。第一個變量前不應該有空格,但其他都有。例5.4 約瑟夫問題:N個人圍成一圈,從第一個人開始報數,數到M的人出圈;再由下一個人開始報數,數到M的人

15、出圈;輸出依次出圈的人的編號。N,M由鍵盤輸入?!痉治觥?(1)由于對于每個人只有出圈和沒有圈兩種狀態(tài),因此可以用布爾型標志數組存儲游戲 過程中每個人的狀態(tài)。不妨用true表示出圈,false 表示沒有出圈。 (2)開始的時候,給標志數組賦初值為false,即全部在圈內。 (3)模擬報數游戲的過程,直到所有的人出圈為止。程序如下:#includeusing namespace std;int n,m,s,f,t;bool a101;/根據題意開出數組大小int main() cinnm;/共n人,報到m出圈 coutendl; for (t=1;t=n;+t) at=false; /等同于me

16、mset(a,0,sizeof(a),要調用cstring庫 f=0; t=0; s=0; /剛開始所有變量默認值也是0,或者用f=t=s=0; do +t;/逐個枚舉圈中的所有位置 if (t=n+1) t=1;/數組模擬環(huán)狀,最后一個與第一個相連 if (at=false) +s;/第t個位置上有人則報數 if (s=m) /當前報的數是m s=0;/計數器清零 coutt ;/輸出出圈人的編號 at=true;/此處的人已出圈,設置為空 f+; /出圈的人數增加一個 while(f!=n);/直到所有的人都出圈為止 return 0;運行結果:輸入: 8 5輸出: 5 2 8 7 1 4

17、 6 3這是一個在算法設計上很有名氣的經典約瑟夫(Josephu)問題,它有很多變例。如猴子選大王、持密碼報數、狐貍追兔子等(見上機練習)。例5.5 輸入十個正整數,把這十個數按由大到小的順序排列。(選擇排序 )將數據按一定順序排列稱為排序,排序的算法有很多,其中選擇排序是一種較簡單的方法?!締栴}分析】要把十個數按從大到小順序排列,則排完后,第一個數最大,第二個數次大,。因此,我們第一步可將第一個數與其后的各個數依次比較,若發(fā)現,比它大的,則與之交換,比較結束后,則第一個數已是最大的數。同理,第二步,將第二個數與其后各個數再依次比較,又可得出次大的數。如此方法進行比較,最后一次,將第九個數與第

18、十個數比較,以決定次小的數。于是十個數的順序排列結束。如對5個進行排序,這個五個數分別為829105。按選擇排序方法,過程如下:初始數據:829105第一次排序:829105928105102895102895第二次排序:108295109285109285第三次排序:109825109825第四次排序:109852對于十個數,則排序要進行9次。程序如下:#include#includeusing namespace std;int t,a11;int main()coutInput 10 intergers:endl; /讀入10個初始數據 for (int i=1; iai;coutend

19、l; for (int i=1; i=9; +i) /進行9次排序 for (int j=i+1; j=10; +j) /將第i個數與其后所有數比較 if (aiaj) t=ai; ai=aj; aj=t; /若有比ai大,則與之交換 for (int i=1;i=10;+i) coutsetw(5)ai; return 0;運行結果:輸入: 8 67 52 189 74 5 58 9 23 41輸出: 189 74 67 58 52 41 23 9 8 5例5.6 編程輸入十個正整數,然后自動按從大到小的順序輸出。(冒泡排序)【問題分析】用循環(huán)把十個數輸入到A數組中;從A1到A10,相鄰的兩

20、個數兩兩相比較,即: A1與A2比,A2與A3比,A9與A10比。只需知道兩個數中的前面那元素的標號,就能進行與后一個序號元素(相鄰數)比較,可寫成通用形式Ai與Ai+1比較,那么,比較的次數又可用1( n-i )循環(huán)進行控制(即循環(huán)次數與兩兩相比較時前面那個元素序號有關) ;在每次的比較中,若較大的數在后面,就把前后兩個對換,把較大的數調到前面,否則不需調換位置。下面例舉5個數來說明兩兩相比較和交換位置的具體情形: 5 6 4 3 7 5和6比較,交換位置,排成下行的順序; 6 5 4 3 7 5和4比較,不交換,維持同樣的順序; 6 5 4 3 7 4和3比較,不交換,順序不變 6 5 4

21、 3 7 3和7比較,交換位置,排成下行的順序; 6 5 4 7 3 經過(1(n-1)次比較后,將3調到了末尾經過第一輪的1 (N-1)次比較,就能把十個數中的最小數調到最末尾位置,第二輪比較1 (N-2)次進行同樣處理,又把這一輪所比較的“最小數”調到所比較范圍的“最末尾”位置;每進行一輪兩兩比較后,其下一輪的比較范圍就減少一個。最后一輪僅有一次比較。在比較過程中,每次都有一個“最小數”往下“掉”,用這種方法排列順序,常被稱之為“冒泡法”排序。程序如下:#include#includeusing namespace std;const int n=10;int t,an+1; /定義數組i

22、nt main() for (int i=1; iai; /輸入十個數 for (int j=1; j=n-1; +j) /冒泡法排序 for (int i=1; i=n-j; +i) /兩兩相比較 if (aiai+1) /比較與交換 t=ai; ai=ai+1; ai+1=t; for (int i=1; i=n; +i) coutsetw(5)ai; /輸出排序后的十個數 coutfloor(sqrt(N) 為止; 打印輸出a數組中留下來、未被篩掉的各元素值,并按每行五個數顯示。用篩法求素數的過程示意如下(圖中用下劃線作刪去標志): 2 3 4 5 6 7 8 9 10 11 12 13

23、 14 1598 99 100 /置數 2 3 4 5 6 7 8 9 10 11 12 13 14 1598 99 100 /篩去被2整除的數 2 3 4 5 6 7 8 9 10 11 12 13 14 1598 99 100 /篩去被3整除的數 2 3 4 5 6 7 8 9 10 11 12 13 14 1598 99 100 /篩去被整除的數程序如下:#include#include /在Dev C+中可調用數學函數庫cmath#includeusing namespace std;const int n=100;int t;bool an+1;int main() for (int

24、 i=0; i=n; +i) ai=true; /等同于memset(a,1,sizeof(a) , 要調用cstrin庫 a1=false; for (int i=2; i=sqrt(n); +i) if (ai) for (int j=2; j=n/i; +j) ai*j=false; t=0; for (int i=2; i=n; +i) if (ai) coutsetw(5)i; t+; if (t%5=0) coutendl; return 0;【上機練習5.1】1、國際象棋盤中,第1格放1粒米,第2格放2粒米,第3格放4粒米,第4格放8粒米,第5格放16粒米,問:16個格子總共可以

25、放多少粒米?【分析】第i個格子可放多少粒米:2i12、輸出斐波列契數列的前N項(5個1行) 0 1 1 2 3 5 8 13 21 3、輸入N個整數,找出最大數所在位置,并將它與第一個數對調位置。4、將一個數組中的所有元素倒序存放 。【分析】A1AN A2 AN-1 AI AJ I 從1開始,每交換1次,I 加1;直到 I = N DIV 25、讀入n個數,打印其中的最大數及其位置號。6、有52張樸克牌,使它們全部正面朝上。從第2張牌開始,把凡是2的倍數位置上的牌翻成正面朝下;接著從第3張牌開始,把凡是3的倍數位置上的牌正面朝上的翻成正面朝下,正面朝下的翻成正面朝上;接著從第4張牌開始,把凡是

26、4的倍數位置上的牌按此規(guī)律翻轉;依此類推,直到第1張要翻的牌是第52張為止。統(tǒng)計最后有幾張牌正面朝上,并打印出它們的位置。7、圍繞著山頂有10個洞,一只狐貍和一只兔子各住一個洞。狐貍總想吃掉兔子。一天兔子對狐貍說:“你想吃我有一個條件,先把洞從110編上號,你從10號洞出發(fā),先到1號洞找我;第二次隔1個洞找我,第三次隔2個洞找我,以后依此類推,次數不限。若能找到我,你就可以飽餐一頓。不過在沒有找到我以前不能停下來?!焙倽M口答應就開始找了,它從早到晚找了1000次洞,累得昏了過去也沒有找到兔子。請問,免子躲在幾號洞里?【答案】2,4,7,9第二節(jié)第二節(jié) 二維數組二維數組一、二維數組的定義當一維

27、數組元素的類型也是一維數組時,便構成了“數組的數組”,即二維數組。二維數組定義的一般格式:數據類型 數組名常量表達式1 常量表達式2 ;例如:int a410;a數組實質上是一個有4行、10列的表格,表格中可儲存40個元素。第1行第1列對應a數組的a00,第n行第m列對應數組元素an-1m-1。說明:當定義的數組下標有多個時,我們稱為多維數組,下標的個數并不局限在一個或二個,可以任意多個,如定義一個三維數組a和四維數組b:int a10035;int b10010035;多維的數組引用賦值等操作與二維數組類似。二、二維數組元素的引用二維數組的數組元素引用與一維數組元素引用類似,區(qū)別在于二維數組

28、元素的引用必須給出兩個下標。引用的格式為: 下標1下標2說明:顯然,每個下標表達式取值不應超出下標所指定的范圍,否則會導致致命的越界錯誤。例如,設有定義:int a35;則表示a是二維數組(相當于一個3*5的表格),共有3*5=15個元素,它們是:a00 a01 a02 a03 a04a10 a11 a12 a13 a14a20 a21 a22 a23 a24因此可以看成一個矩陣(表格),a23即表示第3行第4列的元素。三、二維數組的初始化二維數組的初始化和一維數組類似。可以將每一行分開來寫在各自的括號里,也可以把所有數據寫在一個括號里。例如:int direct42 = 1,0,0,1,-1

29、,0,0,-1 int direct42 = 1,0,0,1,-1,0,0,-1 /盡量不要用四、二維數組程序設計例5.8 設有一程序#include#include#includeconst int n=3;using namespace std;int an+1n+1;int main() for (int i=1; i=n; +i) for (int j=1; jaij; getchar(); for (int i=1; i=n; +i) for (int j=1; j=n; +j) coutsetw(5)aji; coutendl; return 0;程序的輸入:2 1 33 3 11

30、 2 1程序的輸出:2 3 11 3 23 1 1例5.9 已知一個6*6的矩陣(方陣),把矩陣二條對角線上的元素值加上10,然后輸出這個新矩陣?!痉治觥?矩陣即表格,是一個二維數組,有6行6列共36個元素,每個矩陣都有二條對角線,本題難點在于對角線的元素怎么確定。#include#includeusing namespace std;int a77;int main() for (int i=1; i=6; +i) /輸入矩陣元素 for (int j=1; jaij; for (int i=1; i=6; +i) /更改對角線上元素的值 for (int j=1; j=6; +j) if

31、(i=j)|(i+j=7) aij+=10; /尋找對角線的特征 for (int i=1; i=6; +i) /輸出6行6列的矩陣元素 for (int j=1; j=6; +j) coutsetw(5)aij; coutendl; return 0;例5.10 大部分元素是0的矩陣稱為稀疏矩陣,假設有k個非0元素,則可把稀疏矩陣用K*3的矩陣簡記之,其中第一列是行號,第二列是列號,第三列是該行、該列下的非元素的值。如:0 0 0 5 寫簡記成: 1 4 5 /第1行第4列有個數是50 2 0 0 2 2 2 /第2行第2列有個數是20 1 0 0 3 2 1 /第3行第2列有個數是1試編程

32、讀入一稀疏矩陣,轉換成簡記形式,并輸出?!痉治觥?本題中需要解決的主要問題是查找非零元素并記憶位置。將原始矩陣存于數組a。轉換后的矩陣存于數組b,當然b數組的行數可以控制在一個小范圍內。#include#includeconst int n=3,m=5;using namespace std;int main() int an+1m+1,b1014,k=0; for (int i=1; i=n; +i) /矩陣初始 for (int j=1; jaij; for (int i=1; i=n; +i) for (int j=1; j=m; +j) if (aij!=0) /找到非零值,存儲 +k

33、; bk1=i; bk2=j; bk3=aij; for (int i=1; i=k; +i) /輸出 for (int j=1; j=3; +j) coutsetw(3)bij; coutendl; return 0;運行結果:輸入: 0 0 0 0 5 0 0 4 0 0 1 0 0 0 1輸出: 1 5 5 2 3 4 3 1 1 3 5 1例5.11 打印楊輝三角形的前10行。楊輝三角形如下圖: 1 1 1 1 1 1 1 2 1 1 2 1 1 3 3 1 1 3 3 11 4 6 4 1 1 4 6 4 1 圖5-1 圖5-2【問題分析】觀察圖5-1,大家不容易找到規(guī)律,但是如果將

34、它轉化為圖5-2,不難發(fā)現楊輝三角形其實就是一個二維表的小三角形部分,假設通過二維數組yh存儲,每行首尾元素為1,且其中任意一個非首位元素yhij的值其實就是yhi-1j-1與yhi-1j的和,另外每一行的元素個數剛好等于行數。有了數組元素的值,要打印楊輝三角形,只需要控制好輸出起始位置就行了。#include#includeusing namespace std;int main() int a1111; a11=1;/設定第一行的值 for (int i=2; i=10; +i)/從第二行開始推 ai1=1; aii=1;/設定每一行的首尾值為1 for (int j=2; j=i-1;

35、+j)/當前行非首尾的數 aij=ai-1j-1+ai-1j; /每個數等于上一行的二個數之和 for (int i=1; i=10; i+) if (i!=10) coutsetw(30-3*i) ;/控制每行的起始位置,即空格數量 for (int j=1; j=i; j+) coutsetw(6)aij; coutendl; return 0; 例5.12 輸入一串字符,字符個數不超過100,且以“.”結束。 判斷它們是否構成回文。【分析】所謂回文指從左到右和從右到左讀一串字符的值是一樣的,如12321,ABCBA,AA等。先讀入要判斷的一串字符(放入數組letter中),并記住這串字符

36、的長度,然后首尾字符比較,并不斷向中間靠攏,就可以判斷出是否為回文。程序如下:#includeusing namespace std;int main() char ch,letter101; int i=0,j=1; coutch; while (ch!=.)/讀入一個字符串以.號結束 +i; letteri=ch; cinch; while (j=i) coutYesendl; else coutNoendl; return 0;例5.13 蛇形填數 在n*n方陣里填入1,2,3,n*n,要求填成蛇形。例如n=4時方陣為: 10 11 12 1 9 16 13 2 8 15 14 3 7

37、6 5 4 上面的方陣中,多余的空格只是為了便于觀察規(guī)律,不必嚴格輸出,n=8?!痉治觥浚?類比數學中的矩陣,我們可以用一個所謂的二維數組來儲存題目中的方陣。只需聲明一個int aMAXNMAXN,就可以獲得一個大小為MAXNMAXN的方陣。在聲明時,兩維的大小不必相同,因此也可以聲明int a3050這樣的數組,第一維下標范圍是0,1,2,29,第二維下標范圍是0,1,2,49。 讓我們從1開始依次填寫。設“筆”的坐標為(x,y),則一開始x=0,y=n-1,即第0行,第n-1列(別忘了行列的范圍是0到n-1,沒有第n列)?!肮P”的移動軌跡是:下,下,下,左,左,左,上,上,上,右,右,下,

38、下,左,上。總之,先是下,到不能填了為止,然后是左,接著是上,最后是右?!安荒芴睢笔侵冈僮呔统鼋纾ɡ?5),或者再走就要走到以前填過的格子(例如1213)。如果我們把所有格子初始為0,就能很方便地加以判斷。#include#include#define MAXN 10int aMAXNMAXN;int main()int n,x,y,tot=0;scanf(%d,&n);memset(a,0,sizeof(a);tot=ax=0y=n-1=1;while (totn*n) while (x+1=0 & !axy-1) ax-y=+tot; while (x-1=0 & !ax-1y) a-x

39、y=+tot; while (y+1n & !axy+1) ax+y=+tot; for(x=0;xn;+x) for (y=0;yn;+y) printf(%3d,axy);printf(n); return 0;【說明】: 這段程序充分利用了C+語言簡潔的優(yōu)勢。首先,賦值x=0和y=n-1后馬上要把它們作為a數組的下標,因此可以合并完成;tot和a0n-1都要賦值1,也可以合并完成。這樣,我們用一條語句完成了多件事情,而且并沒有犧牲程序的可讀性,這段代碼的含義顯而易見。 那4條while語句有些難懂,不過十分相似,因此只需介紹其中的第一條:不斷向下走,并且填數。我們的原則是:先判斷,再移動

40、,而不是走一步以后發(fā)現越界了再退回來。這樣,我們需要進行“預判”,即是否越界,以及如果繼續(xù)往下走會不會到達一個已經填過的格子。越界只需判斷x+1n,因為y值并沒有修改;下一個格子是(x+1,y),因此只需ax+1y=0,簡寫成!ax+1y(其中!是“邏輯非”運算符)。 細心的讀者也許會發(fā)現這里的一個“潛在bug”;如果越界,x+1會等于n,ax+1y將訪問非法內存!幸運的是,這樣的擔心是不必要的。&是短路運算符。如果x+1n為假,將不會計算!ax+1y,也就不會越界了。 至于為什么是+tot而不是tot+,留給讀者思考?!旧蠙C練習5.2】1、輸入一個二維數組,找出其中最小的數,輸出它的值以及所

41、在行號和列號。2、輸入M行N列數組,將第I行與第J行元素對調(I,J M)。3、輸入44方陣,分別求兩條對角線上元素之和。4、矩陣的轉置: A: B: 1 2 3 轉置為 1 4 7 10 4 5 6 2 5 8 11 7 8 9 3 6 9 12 10 11 125、給一維數組輸入M個整數,假設M=6,數組元素分別為 7 4 8 9 1 5 , 要求建立一個如下數組(矩陣): 7 4 8 9 1 5 4 8 9 1 5 7 8 9 1 5 7 4 9 1 5 7 4 8 1 5 7 4 8 9 5 7 4 8 9 1 6、設數組a是有n個元素的整數數組,從中找出最大和子序列。7、打印楊輝三角

42、形的前10行。第三節(jié)第三節(jié) 字符數組和字符串類型字符數組和字符串類型無論數組的下標有幾個,類型如何,但數組中全體元素的類型必須相同。數組元素的類型可以是任何類型,當它是字符型時,我們稱它為字符數組。由于字符數組與字符類型的應用是計算機非數值處理的重要方面之一,所以我們把它們兩個放在一起進行討論。下面我們舉例說明字符數組的應用。一、字符類型字符類型為由一個字符組成的字符常量或字符變量。字符常量定義:const字符常量=字符字符變量定義: char 字符變量;字符類型是一個有序類型, 字符的大小順序按其ASC代碼的大小而定。例5.14 按字母表順序和逆序每隔一個字母打印。即打印出:a c e g

43、i k m o q s u w yz x r v t p n l j h f d b #include #includeusing namespace std;int main() for (char letter=a; letter=z; letter+=2) coutsetw(3)letter; cout=a; letter-=2) coutsetw(3)letter; return 0; 【說明】程序中,我們利用了字符類型是順序類型這一特性,靈活利用字符變量當作循環(huán)變量,使程序處理起來比較直觀。二、字符數組字符數組是指元素為字符的數組。字符數組是用來存放字符序列或字符串的。字符數組也有一

44、維、二維和三維之分。1、字符數組的定義格式字符數組定義格式同于一般數組,所不同的是數組類型是字符型,第一個元素同樣是從ch10開始,而不是ch11。具體格式如下: 存儲類型 char 數組名常量表達式1例如: char ch15; /數組ch1是一個具有5個字符元素的一維字符數組 char ch235; /數組ch2是一個具有15個字符元素的二維字符數組2.字符數組的賦值字符數組賦值類似于一維數組,賦值分為數組的初始化和數組元素的賦值。初始化的方式有用字符初始化和用字符串初始化兩種,也有用初始值表進行初始化的。(1).用字符初始化數組例如: char chr15=a,b,c,d,e;初始值表中

45、的每個數據項是一個字符,用字符給數組chr1的各個元素初始化。當初始值個數少于元素個數時,從首元素開始賦值,剩余元素默認為空字符。字符數組中也可以存放若干個字符,也可以來存放字符串。兩者的區(qū)別是字符串有一結束符(0)。反過來說,在一維字符數組中存放著帶有結束符的若干個字符稱為字符串。字符串是一維數組,但是一維字符數組不等于字符串。例如: char chr25=a,b,c,d,0; 即在數組chr2中存放著一個字符串“abcd”。(2).用字符串初始化數組用一個字符串初始化一個一維字符數組,可以寫成下列形式: char chr25=”abcd”;使用此格式均要注意字符串的長度應小于字符數組的大小

46、或等于字符數組的大小減1。同理,對二維字符數組來講,可存放若干個字符串??墒褂糜扇舾蓚€字符串組成的初始值表給二維字符數組初始化。例如:char chr334=“abc”,“mno”,“xyz”;在數組ch3中存放3個字符串,每個字符串的長度不得大于3。(3).數組元素賦值 字符數組的賦值是給該字符數組的各個元素賦一個字符值。例如:char chr3;chr0=a; chr1=b;chr2=c;對二維、三維字符數組也是如此。當需要將一個數組的全部元素值賦予另一數組時,不可以用數組名直接賦值的方式,要使用字符串拷貝函數來完成。 (4).字符常量和字符串常量的區(qū)別兩者的定界符不同,字符常量由單引號括

47、起來,字符串常量由雙引號括起來。字符常量只能是單個字符,字符串常量則可以是多個字符??梢园岩粋€字符常量賦給一個字符變量,但不能把一個字符串常量賦給一個字符變量。字符常量占一個字節(jié),而字符串常量占用字節(jié)數等于字符串的字節(jié)數加1。增加的一個字節(jié)中存放字符串結束標志0。例如:字符常量a占一個字節(jié),字符串常量“a”占二個字節(jié)。三、字符串的輸入與輸出字符串可以作為一維字符數組來處理,那么字符串的輸入和輸出也可以按照數組元素來處理,本節(jié)不再做介紹。本節(jié)僅介紹將字符串作為一個整體進行輸入和輸出的語句。1、輸入從鍵盤輸入一個字符數組可以使用scanf語句或gets語句。(1)scanf語句 格式:scanf(

48、“%s”,字符串名稱);說明:這里的字符串名稱之前不加&這個取地址符。例如:scanf(“%s”,&s1)是錯誤的。系統(tǒng)會自動在輸入的字符串常量后添加0標志,因此輸入時,僅輸入字符串的內容即可。輸入多個字符串時,以空格分隔。例如:scanf(“%s%s%s”,s1,s2,s3);從鍵盤分別輸入Let us go,則三個字符串分別獲取了三個單詞。反過來可以想到,如果僅有一個輸入字符串名稱的情況下,字符串變量僅獲取空格前的內容。例如:scanf(“%s”,s1);從鍵盤分別輸入Let us go,則僅有第一個單詞被獲取,即s1變量僅獲取第一個單詞Let。(2)gets語句 格式:gets(字符串名

49、稱);說明:使用gets只能輸入一個字符串。例如:gets(s1,s2);是錯誤的。使用gets,是從光標開始的地方讀到換行符也就是說讀入的是一整行,而使用scanf是從光標開始的地方到空格,如果這一行沒有空格,才讀到行尾。例如:scanf(“%s”,s1);gets(s2);對于相同的輸入Hello World!。s1獲取的結果僅僅是Hello,而s2獲取的結果則是Hello World!2、輸出向屏幕輸出一個字符串可以使用printf語句或puts語句。(1)printf語句 格式:printf(“%s”,字符串名稱); 說明:用%s格式輸出時,printf的輸出項只能是字符串(字符數組)

50、名稱,而不能是數組元素。例如:printf(“%s”,a5);是錯誤的。輸出字符串不包括字符串結束標志符0。(2) puts語句 格式:puts(字符串名稱); 說明:puts語句輸出一個字符串和一個換行符。對于已經聲明過的字符串a,printf(“%sn”,a)和 puts(a)是等價的。例5.15 C+中,一個字符串中的字符可以通過其對應的下標靈活使用。#include / gets()調用cstdio庫#include#include /strlen()調用cstring庫, 調用string庫在高版C+下編譯出錯using namespace std;int main() char s

51、t100; gets(st); /gets為專門讀字符串的 函數, 讀取一行字符串 for (int i=0; istrlen(st); +i)/輸出st串中的第i個字符 coutsti; return 0; 例5.16 對給定的10個國家名,按其字母的順序輸出?!緟⒖汲绦?】#include#include#includeusing namespace std;int main() char t21,cname1121; for (int i=1; i=10; +i) gets(cnamei); /gets為專門讀字符串的函數, 讀取一行字符串 for (int i=1; i=9; +i)

52、int k=i; for (int j=i+1; j0) k=j; strcpy(t,cnamei); strcpy(cnamei,cnamek); strcpy(cnamek,t); for (int i=1; i=10; +i) coutcnameiendl; return 0; 【參考程序2】(詳見第八章第一節(jié)和第三節(jié))#include#include#includeusing namespace std;string cname10;int main()for (int i=0;i!=10;+i) getline(cin,cnamei);sort(cname,cname+10);/利用

53、C+庫函數排序for (int i=0;i!=10;+i) coutcnameiendl;return 0;三、字符串處理函數系統(tǒng)提供了一些字符串處理函數,用來為用戶提供一些字符串的運算。常用的字符串函數介紹如下。四、應用舉例例5.17 數字統(tǒng)計(Noip2010)【問題描述】 請統(tǒng)計某個給定范圍L, R的所有整數中,數字2 出現的次數。 比如給定范圍2, 22 ,數字2 在數2 中出現了1 次,在數12 中出現1 次,在數20 中出現1 次,在數21 中出現1 次,在數22 中出現2 次,所以數字2 在該范圍內一共出現了6 次。【輸入】 輸入文件名為two.in 。 輸入共1 行,為兩個正整

54、數L 和R,之間用一個空格隔開?!据敵觥?輸出文件名為two.out 。 輸出共1 行,表示數字2 出現的次數。【輸入樣例1】two.in 2 22【輸出樣例1】two.out 6【輸入樣例2】two.in 2 100【輸出樣例2】two.out 20【數據范圍】1 L R 10000【算法分析1】枚舉L,R區(qū)間的所有整數,對于每個整數x: 1.將整數x轉化成字符串s,可以用sprintf(s,%d,x)來實現; 2.枚舉字符串s的每個字符判斷是否為2。【參考程序1】#include #include #include using namespace std;char s10;int main

55、()int l,r,ans=0;cinlr;for (int i=l; i=r; +i) sprintf(s,%d,i); l=strlen(s); for (int j=0; j=l-1; +j) if (sj=2) +ans;coutans;return 0;【算法分析2】枚舉L,R區(qū)間的所有整數,對于每個整數x: 先判斷x的最后一位是否為2(即 x%10=2),然后將x的最后一位刪除(即 x/=10),循環(huán)操作,直到x值為0。【參考程序2】#include #include #include using namespace std;int main() int l,r,ans=0; ci

56、nlr; for (int i=l; i0) if (x%10=2) +ans; x/=10; coutans; return 0;例5.18 數字反轉(Noip2011)【問題描述】 給定一個整數,請將該數各個位上數字反轉得到一個新數。新數也應滿足整數的常見形式,即除非給定的原數為零,否則反轉后得到的新數的最高位數字不應為零(參見樣例2)?!据斎搿?輸入文件名為reverse.in。 輸入共1 行,一個整數N?!据敵觥?輸出文件名為reverse.out。 輸出共1 行,一個整數,表示反轉后的新數?!据斎霕永?】 123【輸出樣例1】 321【輸入樣例2】 -380【輸出樣例2】 -83【數

57、據范圍】-1,000,000,000 N 1,000,000,000?!舅惴ǚ治?】 1.將整數N轉化成字符串s,可以用sprintf(s,%d,N)來實現;2.對字符串進行反轉操作;3.將字符串s轉換成數字N,可以用sscanf(s,%d,&N)來實現。4.輸出數字N。【參考程序1】#include #include #include using namespace std;char s100,c100; int main() int n,l; cinn; sprintf(s,%d,n); l=strlen(s); for (int i=0; i=l-1; +i) cl-i-1=si; if (n0) cout-; sscanf(c,%d,&n); coutn; return 0;【算法分析2】判斷數字是否為負數,如果是則先輸出符號,并將數字取絕對值;將數字從后往前轉換成字符串;去掉前導0,然后輸出

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論