C語言高級語言程序設(shè)計(一)第三章 程序設(shè)計方法問題分析_第1頁
C語言高級語言程序設(shè)計(一)第三章 程序設(shè)計方法問題分析_第2頁
C語言高級語言程序設(shè)計(一)第三章 程序設(shè)計方法問題分析_第3頁
C語言高級語言程序設(shè)計(一)第三章 程序設(shè)計方法問題分析_第4頁
C語言高級語言程序設(shè)計(一)第三章 程序設(shè)計方法問題分析_第5頁
已閱讀5頁,還剩50頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、高級語言程序設(shè)計高級語言程序設(shè)計(一一)(c programming)第三講:程序設(shè)計方法第三講:程序設(shè)計方法-問題分析問題分析本章目標本章目標n了解一般程序設(shè)計過程了解一般程序設(shè)計過程n通過實例重點掌握問題分析方法通過實例重點掌握問題分析方法l精度計算;精度計算;l輸入數(shù)據(jù)處理;輸入數(shù)據(jù)處理;l字符串操作字符串操作程序設(shè)計過程程序設(shè)計過程n程序設(shè)計過程就是解決問題的過程。程序設(shè)計通程序設(shè)計過程就是解決問題的過程。程序設(shè)計通常包括如下五個步驟:常包括如下五個步驟:問題問題分析分析編碼編碼算法設(shè)計算法設(shè)計程序設(shè)計步驟程序設(shè)計步驟測試測試調(diào)試調(diào)試有問題有問題無問題無問題分析問題:分析問題:功能功能

2、:需要弄清楚軟件要完成的功能;輸入輸入:如果問題有輸入,分析輸入是什么及輸入數(shù)據(jù)的類型; 處理處理:對輸入數(shù)據(jù)做什么處理; 輸出輸出:如果有輸出,輸出什么數(shù)據(jù)及輸出數(shù)據(jù)的格式;對于復(fù)雜問題,可將問題分解為若干子對于復(fù)雜問題,可將問題分解為若干子問題,然后再進行上面的分析。問題,然后再進行上面的分析。算法設(shè)計:算法設(shè)計: 設(shè)計解決問題的具體方案(步驟)。編碼:編碼: 將算法用高級語言實現(xiàn)。測試:測試: 運行編譯連接后得到的執(zhí)行程序,以驗證程序是否按要求 解決了問題,并沒有產(chǎn)生副作用。即程序是否做了該做的事,同時沒有做不該做的事。調(diào)試:調(diào)試: 如果程序經(jīng)測試發(fā)現(xiàn)問題,則通過調(diào)試手段找到產(chǎn)生錯誤的代

3、碼并修復(fù)它。算法算法n任何計算問題的解決都是按指定的順序執(zhí)行一系任何計算問題的解決都是按指定的順序執(zhí)行一系列動作的結(jié)果。解決問題的步驟列動作的結(jié)果。解決問題的步驟(動作及動作之間動作及動作之間的順序的順序)稱為算法(稱為算法(algorithm)。)。算法表示算法表示n算法既可以用自然語言表述算法既可以用自然語言表述(如前如前),也可用用半結(jié),也可用用半結(jié)構(gòu)化語言或結(jié)構(gòu)化圖形表示,如:構(gòu)化語言或結(jié)構(gòu)化圖形表示,如:read 學生成績值學生成績值if 成績值成績值 = 60print “pass”elseprint “fail”讀學生成績值讀學生成績值成績值成績值 = 60輸出輸出”fail”輸

4、出輸出”pass”真真假假流程圖流程圖問題問題3.1: 計算計算e值值【問題描述問題描述】e(自然對數(shù)自然對數(shù))值計算公式為值計算公式為 1 + 1/1! + 1/2! + + 1/n!。輸入一個整數(shù)。輸入一個整數(shù)n(0=n=30),計算相應(yīng)),計算相應(yīng)e近似值近似值 ?!据斎胄问捷斎胄问健繌目刂婆_輸入整數(shù)從控制臺輸入整數(shù)n(0=n=30)。)?!据敵鲂问捷敵鲂问健靠刂婆_輸出計算結(jié)果,要求小數(shù)點后保留控制臺輸出計算結(jié)果,要求小數(shù)點后保留10位。位?!緲永斎霕永斎?】12【樣例輸出樣例輸出1】2.7182818283【樣例輸入樣例輸入2】13【樣例輸出樣例輸出2】2.7182818284問題

5、問題3.1:問題分析:問題分析n輸入:一個整數(shù)(輸入:一個整數(shù)(整型)整型);n處理:計算處理:計算 公式公式1 + 1/1! + 1/2! + + 1/n! ;n輸出:以輸出:以%.10f格式輸出格式輸出(小數(shù)后保留小數(shù)后保留10位位)n變量:變量:l一個整型變量一個整型變量, 用于存儲所讀入的整數(shù)用于存儲所讀入的整數(shù), 如如, int n;l一個雙精度浮點變量一個雙精度浮點變量(why?), 用于存儲計算結(jié)果用于存儲計算結(jié)果, 如如double e; 問題問題3.1:算法設(shè)計:算法設(shè)計n解決問題解決問題3.1的解決過程(算法一):的解決過程(算法一):設(shè)計算結(jié)果保存在變量設(shè)計算結(jié)果保存在變

6、量e e中;中;讀入一個整數(shù)到變量讀入一個整數(shù)到變量n;n;for(i=0; i=n; i+)for(i=0; i=n; i+) e = e + 1/i!;e = e + 1/i!;輸出輸出e e值值; ; e=1 + 1/1! + 1/2! + + 1/n!/11ieeii問題問題3.1:代碼實現(xiàn):代碼實現(xiàn)#include int fact(int n)int f, i;f = 1;for(i=2;i=n;i+) f *= i;return f;int main()int n,i;double e=0.0;scanf(%d,&n);for(i=0;i=n;i+) e += 1.0/f

7、act(i);printf(%.10f,e);return 0;問題問題3.1:測試:測試n測試數(shù)據(jù)的考慮測試數(shù)據(jù)的考慮1.首先選取輸入數(shù)據(jù)區(qū)間(首先選取輸入數(shù)據(jù)區(qū)間(0=n=30)的正常值)的正常值,如問題如問題3.1中所提供的輸入樣例;中所提供的輸入樣例;輸入:輸入:12期望(正確)輸出:期望(正確)輸出: 2.7182818283輸入:輸入:13期望(正確)輸出:期望(正確)輸出: 2.71828182842.選取輸入數(shù)據(jù)區(qū)間邊界附近的值,本例中可選選取輸入數(shù)據(jù)區(qū)間邊界附近的值,本例中可選取:?。簂n=0, 期望輸出:期望輸出:1.0000000000ln=1, 期望輸出:期望輸出:2.

8、0000000000ln=30,期望輸出:,期望輸出: 2.7182818285 問題問題3.1:常見問題分析:常見問題分析n以整型計算以整型計算n!,即函數(shù),即函數(shù)fact返回整數(shù)(觀察現(xiàn)象返回整數(shù)(觀察現(xiàn)象what happened?)n=13實際輸出:實際輸出: 2.7182818288(期望輸出:期望輸出:2.7182818284)why? 如何調(diào)試如何調(diào)試?數(shù)據(jù)范圍與精度數(shù)據(jù)范圍與精度nint類型數(shù)據(jù)范圍類型數(shù)據(jù)范圍(對于對于ia32結(jié)構(gòu)的計算機結(jié)構(gòu)的計算機): -232-1 - 232-1 - 1 (即即-2147483648 2147483647 )12! int最大值最大值 1

9、3!n修改方法:修改方法:將保存階乘結(jié)果的變量將保存階乘結(jié)果的變量改為改為double類型,并將類型,并將fact的返回類型也改為的返回類型也改為double 0!11!12!23!64!245!1206!7207!50408!403209!36288010!362880011!3991680012!47900160013!1932053504(error!, 溢出溢出)(正確應(yīng)為正確應(yīng)為:6227020800)14!1278945280(error!, 溢出溢出)(正確應(yīng)為正確應(yīng)為:87178291200)問題問題3.1:修改后的程序:修改后的程序#include double fact(i

10、nt n) int i; double f=1.0; for(i=1; i=n; i+) f *= i; return f; int main() int n,i; double e = 0.0; scanf(“%d”, &n); for(i=0; i=n; i+) e += 1.0/fact(i); printf(“%.10f”, e); return 0;n 計算結(jié)果為計算結(jié)果為float類型,即類型,即float e; (觀察現(xiàn)象(觀察現(xiàn)象what happened?)n=12實際輸出:實際輸出: 2.7182819841(期望輸出:期望輸出:2.7182818283)n dou

11、ble類型比類型比float類型有更高的精度類型有更高的精度float尾數(shù):尾數(shù):23位,指數(shù):位,指數(shù):8位位double尾數(shù):尾數(shù):52位,指數(shù):位,指數(shù):11位位問題問題3.1:常見問題分析(續(xù)):常見問題分析(續(xù))問題問題3.1:另一種方法:另一種方法n觀察計算觀察計算 公式公式1 + 1/1! + 1/2! + + 1/n!,可知:,可知:若前一次迭代若前一次迭代1/(n-1)!計算結(jié)果為計算結(jié)果為fn-1,則本次迭代的結(jié)果則為,則本次迭代的結(jié)果則為fn = fn-1 /n因此,因此,沒有必要每次迭代都重新計算沒有必要每次迭代都重新計算n!,顯然效率會更高,顯然效率會更高。n具體算法

12、(解題步驟)為:具體算法(解題步驟)為:給雙精度浮點變量給雙精度浮點變量e和和 f 賦初值賦初值 1.0;for(i=1; i=n; i+) f = f/i; e = e+f;輸出輸出e問題問題3.1:另一種方法(代碼):另一種方法(代碼)#include int main() int n,i; double e ,f e = f = 1.0; scanf(“%d”, &n); for(i=1; i=n; i+) f = f/i; e += f; printf(“%.10f”, e); return 0;考慮為什么循環(huán)從考慮為什么循環(huán)從i=1開始,而開始,而不從不從i=0開始?開始?1

13、7問題問題3.2:簡易計算器:簡易計算器【問題描述問題描述】 編程實現(xiàn)簡單的交互式計算器,能進行整數(shù)的編程實現(xiàn)簡單的交互式計算器,能進行整數(shù)的 + - * / 運算。運算?!据斎胄问捷斎胄问健?從鍵盤讀入如下形式的輸入行,數(shù)據(jù)與運算符之間可以從鍵盤讀入如下形式的輸入行,數(shù)據(jù)與運算符之間可以用一個或用一個或多個空格分隔多個空格分隔: 120 + 350【輸入形式輸入形式】對于對于+,-及及*運算,輸出形式如下:運算,輸出形式如下:120+350=470對于對于/運算,輸出形式如下(小數(shù)后保留兩位):運算,輸出形式如下(小數(shù)后保留兩位): 5/2=2.50 18問題問題3.2:問題分析:問題分析n

14、如何讀入數(shù)據(jù)及運算符?如何讀入數(shù)據(jù)及運算符?l方法一方法一int data1,data2;char op;scanf ( “%d%c%d”, &data1, &op, &data2 );l方法二方法二int data1, data2;char op;scanf(“%d”, &data1);getchar();op = getchar();scanf(“%d”, &data1);不足:數(shù)據(jù)與運算符之間只能有一個空格分隔不足:數(shù)據(jù)與運算符之間只能有一個空格分隔輸入時,數(shù)據(jù)輸入時,數(shù)據(jù)與字符之間不與字符之間不能有空格,否能有空格,否則空格作為字則空格作為字符輸

15、入。符輸入。19問題問題3.2:問題分析:問題分析n如何讀入數(shù)據(jù)及運算符?如何讀入數(shù)據(jù)及運算符?l方法三方法三int data1, data2;char op;scanf(“%d %c %d”, &data1, &op, &data2);好處:數(shù)據(jù)與運算符之間可以有多個空格分隔好處:數(shù)據(jù)與運算符之間可以有多個空格分隔空格使得跳過兩次非空格使得跳過兩次非空白輸入間的所有空空白輸入間的所有空白字符。白字符。20問題問題3.2:算法設(shè)計:算法設(shè)計int data1,data2, result1;float result2;char op;從標準輸入中讀入整數(shù)從標準輸入中讀入整

16、數(shù)data1,運算符,運算符op及整數(shù)及整數(shù)data2;判斷判斷op:若為若為+,則,則result1 = data1 + data2;若為若為-,則,則result1 = data1 - data2;若為若為*,則,則result1 = data1 * data2;若為若為/,則,則result2 = data1 / data2;若若op為為+,-或或*,輸出結(jié)果,輸出結(jié)果result1;若若op為為/,輸出結(jié)果,輸出結(jié)果result2;op值加運算+減運算乘運算 除運算-*/多路選擇多路選擇注意:由于注意:由于data1和和data2為整為整數(shù),結(jié)果仍為整數(shù)。要用數(shù),結(jié)果仍為整數(shù)。要用強制

17、強制類型類型轉(zhuǎn)換才能得到小數(shù)位。轉(zhuǎn)換才能得到小數(shù)位。result2 = (float)data1/data2;多路選擇,可使用多路選擇,可使用if-else if語句實現(xiàn)。在此語句實現(xiàn)。在此,更適合,更適合switch語句。語句。21問題問題3.2:代碼實現(xiàn):代碼實現(xiàn)/c3_2.c#include int main()int data1,data2, result1;float result2;char op;scanf(“%d %c %d”, &data1, &op, &data2);switch ( op ) case +: result1 = data1+data

18、2; break;case -: result1 = data1-data2; break;case *: result1 = data1*data2; break;case /: result2 = (float)data1/data2; break;default: printf(input error!n); break;if(op = + | op = - | op = *) printf(%d%c%d=%dn“, data1,op,data2,result1); else if(op = /) printf(%d%c%d=%.2fn“, data1,op,data2,result2)

19、;return 0;測試數(shù)據(jù)測試數(shù)據(jù):120 + 35012 1235 * 23 / 2123+12123 + 12123 & 1222問題問題3.2:思考(一):思考(一)n本問題程序一次運行只能計算一次。若要能進行多次計算,并用本問題程序一次運行只能計算一次。若要能進行多次計算,并用ctrl+c退出退出程序,如何實現(xiàn)?程序,如何實現(xiàn)?/c3_2c.c#include int main()int data1,data2, result1; float result2;char op;for(; ;)scanf(%d %c %d, &data1, &op, &d

20、ata2);switch ( op ) case +: result1 = data1+data2; break;case -: result1 = data1-data2; break;case *: result1 = data1*data2; break;case /: result2 = (float)data1/data2; break;default: printf(input error!n); continue;if(op = /)printf(%d%c%d=%.2fn, data1,op,data2,result2);elseprintf(%d%c%d=%dn, data1,

21、op,data2,result1);return 0;無窮循環(huán),可用無窮循環(huán),可用ctrl+c退出,實際上可退出,實際上可以利用以利用ctrl+c終止任何控制臺終止任何控制臺c程序的程序的執(zhí)行。執(zhí)行。continue語句語句,跳到下一次,跳到下一次循環(huán)。循環(huán)。n本問題程序一次運行只能進行單運行符計算。若要本問題程序一次運行只能進行單運行符計算。若要使程序能支持多運算符的使程序能支持多運算符的混合運算混合運算,并輸入等號(,并輸入等號(=)結(jié)束輸入,如,)結(jié)束輸入,如,1+2-3*5/2-3/2=,如何實現(xiàn)?難點:,如何實現(xiàn)?難點:l如何讀入數(shù)據(jù)及運算符?如何讀入數(shù)據(jù)及運算符?l如何保證計算時運

22、算符的優(yōu)先級?如何保證計算時運算符的優(yōu)先級?n更進一步,若要程序支持圓括號來改變計算次序,更進一步,若要程序支持圓括號來改變計算次序,如,如,(1+2-3)*(5-3)/2=,如何實現(xiàn)?如何實現(xiàn)?n如果出現(xiàn)錯誤的輸入,例如輸入:如果出現(xiàn)錯誤的輸入,例如輸入:4+r=,如何過濾,如何過濾掉錯誤輸入,繼續(xù)程序的運行?掉錯誤輸入,繼續(xù)程序的運行?23問題問題3.2:思考(二):思考(二)利用利用scanf的返回值的返回值為了保證運算符的優(yōu)先級,其為了保證運算符的優(yōu)先級,其算法分析算法分析:當前當前datai opi datai+1 是否進行是由是否進行是由opi+1決定。當決定。當 opi+1為為+

23、,-,=時,立即進行當前運算,否則先進行下一步運算,以時,立即進行當前運算,否則先進行下一步運算,以此迭代。部分偽代碼如下:此迭代。部分偽代碼如下:scanf(“%d %c”, &data1, &op1);while(op1 != =) scanf(“%d %c”, &data2, &op2); while(op2 = * | op2 = /) scanf(“%d %c”, &data, &op); data2 = data2 op2 data; op2 = op; data1 = data1 op1 data2; op1 = op2;其它方法其

24、它方法?輸入串可表示為輸入串可表示為data1 op1 datai opi opi為為+,-,*,/,=因此可采用如下方式讀入數(shù)據(jù)和運算符因此可采用如下方式讀入數(shù)據(jù)和運算符:scanf(“%d %c”, &data1, &op1);while(op != =) . scanf(“%d %c”, &data2, &op2); 格式化輸入函數(shù)格式化輸入函數(shù)int scanf ( “.”, )n該函數(shù)根據(jù)格式化字符串中的格式控制字符,將該函數(shù)根據(jù)格式化字符串中的格式控制字符,將輸入流中的信息轉(zhuǎn)換成相應(yīng)的數(shù)據(jù)類型;輸入流中的信息轉(zhuǎn)換成相應(yīng)的數(shù)據(jù)類型;n返回返回成功轉(zhuǎn)換并

25、賦值的輸入項個數(shù)成功轉(zhuǎn)換并賦值的輸入項個數(shù);n若格式完全匹配失敗,則返回若格式完全匹配失敗,則返回0;n若遇到輸入結(jié)束,則返回若遇到輸入結(jié)束,則返回eof;n將過濾掉出現(xiàn)的空白字符(空格、制表符、換行將過濾掉出現(xiàn)的空白字符(空格、制表符、換行符)。符)。n一次性讀入所有數(shù)據(jù):一次性讀入所有數(shù)據(jù):num = scanf( “%d %c %d”,&data1, &op, &data2);根據(jù)根據(jù)num的值判斷各種情況。的值判斷各種情況。n利用利用getchar輸入函數(shù)循環(huán)讀入一行字符,逐個分輸入函數(shù)循環(huán)讀入一行字符,逐個分析各個字符進行數(shù)據(jù)組裝和判斷;析各個字符進行數(shù)據(jù)組裝

26、和判斷;n利用利用gets函數(shù)讀入一行字符串,逐個分析各個字符函數(shù)讀入一行字符串,逐個分析各個字符進行數(shù)據(jù)組裝和判斷。進行數(shù)據(jù)組裝和判斷。問題問題3.2:其它讀取方法:其它讀取方法問題問題3.3 擴展字符擴展字符【問題描述問題描述】編寫程序?qū)⒑锌s記符號的字符串擴展為等價的完整字符串,例如將編寫程序?qū)⒑锌s記符號的字符串擴展為等價的完整字符串,例如將a-d擴展為擴展為abcd。該程序可以處理大小寫字母和數(shù)字,并可以處理。該程序可以處理大小寫字母和數(shù)字,并可以處理a-b-c、a-z0-9與與-a-z等等類似的情況。要求擴展符類似的情況。要求擴展符-兩邊的字符只要右邊的大于左邊就擴展(即兩邊的字符

27、只要右邊的大于左邊就擴展(即z-b情情況也要擴展),并且況也要擴展),并且-兩邊不能有空格。兩邊不能有空格。【輸入形式輸入形式】從鍵盤輸入包含擴展符的字符串,字符串中可以包含空格從鍵盤輸入包含擴展符的字符串,字符串中可以包含空格【輸出形式輸出形式】輸出擴展后的字符串輸出擴展后的字符串【輸入樣例輸入樣例1】a-c-u-b【輸出樣例輸出樣例1】abcdefghijklmnopqrstu-b【輸入樣例輸入樣例2】a-b-c a-a 0-4【輸出樣例輸出樣例2】abc a-a 01234【樣例說明樣例說明】擴展輸入擴展輸入a-c-u為:為:abcdefghijklmnopqrstu,而,而b比比u值小

28、,所以無法擴展,直值小,所以無法擴展,直接輸出。接輸出。27問題問題3.3 :問題分析:問題分析n如何讀入一個包含空格的字符串?(不能用如何讀入一個包含空格的字符串?(不能用scanf函數(shù),為什么?)函數(shù),為什么?)l方法一:方法一:char c, s512;for(i=0; (c=getchar() != n; i+) si = c;si = 0;l方法二(簡單):使用方法二(簡單):使用gets標準庫函數(shù)標準庫函數(shù)gets(s);注意注意:不要忘記加:不要忘記加字符串最后的結(jié)束字符串最后的結(jié)束符(符(0)!)!行輸入、輸出行輸入、輸出n行輸入函數(shù):行輸入函數(shù):char * gets ( c

29、har s )從標準輸入讀取完整的一行,將讀取的內(nèi)容存入從標準輸入讀取完整的一行,將讀取的內(nèi)容存入s字符數(shù)組中,并用字符數(shù)組中,并用字符串結(jié)束符字符串結(jié)束符0取代行尾的取代行尾的n。若讀取錯誤或遇到輸入結(jié)束則返回。若讀取錯誤或遇到輸入結(jié)束則返回null。n行輸出函數(shù)行輸出函數(shù)int puts ( char s )將字符數(shù)組將字符數(shù)組s中的內(nèi)容輸出到標準輸出上,并中的內(nèi)容輸出到標準輸出上,并自動自動在末尾添加一個換行符在末尾添加一個換行符。問題問題3.3 問題分析問題分析s1i-s1i+2s2if s1i+1=- & s1is1i+2先將要擴展的字符串讀到一個字符數(shù)組先將要擴展的字符串讀

30、到一個字符數(shù)組(s1)中;中;設(shè)另一個字符數(shù)組用于存放擴展后的字設(shè)另一個字符數(shù)組用于存放擴展后的字符串符串(s2);依次依次檢查所讀入字符串檢查所讀入字符串(s1)中字符;中字符;將將s1i原封不動的寫到原封不動的寫到s2中;中;當當s1i+1=- & s1i s1i+2時,時,將將s1i至至s1i+2之間的字符展開到之間的字符展開到s2中中問題問題3.3 算法算法設(shè)字符數(shù)組設(shè)字符數(shù)組s1用來讀入字符串,用來讀入字符串,s2用來存放擴展后字符串;用來存放擴展后字符串;從標準輸入中讀入字符串到從標準輸入中讀入字符串到s1中;中;while s1i != 0將將s1當前字符放到當前字符放到

31、s2中,即中,即s2j = s1i; if s1i+1=- & s1is1i+2將將s1i與與s1i+2區(qū)間字符寫到區(qū)間字符寫到s2中;中;將當前將當前s1讀位置移至讀位置移至s1i+2,即即i = i+2;否則否則i i加加1 1 ;給給s2置結(jié)束符,即置結(jié)束符,即s2j = 0;輸出字符串輸出字符串s2;i初始化為初始化為0;j初始化為初始化為0;問題問題3.3 程序?qū)崿F(xiàn)程序?qū)崿F(xiàn)#include #define maxline 512int main()char c,s1maxline,s2maxline;int i,j;i = j = 0;gets(s1);while(s1i !

32、= 0)s2j+ = s1i;if(s1i+1 = - & s1i s1i+2)for(c = s1i+1; c s1i+2; c+)s2j+ = c;i = i+2;else i+;s2j = 0;puts(s2);return 0;問題問題3.3 :測試:測試測試數(shù)據(jù)測試數(shù)據(jù)期望結(jié)果期望結(jié)果數(shù)據(jù)類型數(shù)據(jù)類型a-dabcd正常a-c-u-b abcdefghijklmnopqrstu-b 特殊特殊a-d d-aabcd d-a特殊特殊z-b z_ab 特殊特殊a-b-cabc邊界邊界-a-8-a-8非正常a-aa-a非正常問題問題3.3 :常見問題及分析:常見問題及分析n處理帶空格的

33、輸入串處理帶空格的輸入串l不要用不要用scanf來讀輸入串,建議用來讀輸入串,建議用getchar或或gets來讀輸入串;來讀輸入串;n字符串沒有結(jié)束標志字符串沒有結(jié)束標志l在用在用getchar讀入一個字符串及生成擴展字符串讀入一個字符串及生成擴展字符串s2時,一定要給字符串置一個結(jié)束符(時,一定要給字符串置一個結(jié)束符(0);(通過實例演示一下現(xiàn)象);(通過實例演示一下現(xiàn)象)問題問題3.3 :常見問題及分析(續(xù)):常見問題及分析(續(xù))n用用a-d, a-b, a-d-g作輸入觀察下面程序現(xiàn)象。作輸入觀察下面程序現(xiàn)象。如何調(diào)試?如何調(diào)試?/c3_3a.c#include #define max

34、line 512int main()char c,s1maxline,s2maxline;int i,j;i = j = 0;gets(s1);while(s1i != 0)s2j+ = s1i;if(s1i+1 = - & s1i s1i+2)for(c = s1i+1; c = s1i+2; c+)s2j+ = c;i = i+3;else i+;s2j = 0;puts(s2);return 0;問題問題3.3 :其它方法:其它方法n其實在上述代碼實現(xiàn)中,數(shù)組其實在上述代碼實現(xiàn)中,數(shù)組s2可以省略,如:可以省略,如:/c3_3b.c#include #define maxline

35、 512int main()char c,s1maxline;int i=0;gets(s1);while(s1i != 0)putchar(s1i);if(s1i+1 = - & s1i s1i+2)for(c = s1i+1; c s1i+2; c+)putchar(c);i = i+2;else i+;putchar(n);return 0;其它方法?其它方法?問題問題3.3 :思考:思考n若要求擴展符若要求擴展符-兩邊的字符為同類兩邊的字符為同類(即均為小寫即均為小寫字母、大寫字母或數(shù)字字符),即字母、大寫字母或數(shù)字字符),即 出現(xiàn)出現(xiàn)z-b、8-b這種情況將不擴展,程序如何修

36、改?這種情況將不擴展,程序如何修改?其實在擴展字符操作前其實在擴展字符操作前if(s1i+1 = - & s1i s1i+2)增加一個判斷擴展符兩邊的字符是否同類的函數(shù)即可。增加一個判斷擴展符兩邊的字符是否同類的函數(shù)即可。if(s1i+1 = - & s1i s1i+2 & iscongener(s1i,s1i+2) )判斷兩個字符是否是同類的函數(shù)實現(xiàn)如下:判斷兩個字符是否是同類的函數(shù)實現(xiàn)如下:int iscongener(char c1, char c2) if(isupper(c1) & isupper(c2) return 1; if(islower(c1

37、) & islower(c2) return 1; if(isdigit(c1) & isdigit(c2) return 1; return 0;isupper, islower, isdigit均為系統(tǒng)標準庫均為系統(tǒng)標準庫函數(shù)。使用前要加:函數(shù)。使用前要加:#include #includeint a1000,j;void expand( int s1000,int i ) int k; j=0; for(k=0;ki;+k)if(sk=-&sk-1sk+1) for(;aj-1sk+1;+j) aj=+sk-1; +k;else aj=sk; +j; main()

38、 int s1000,k,i; for(i=0; si-1!=n; +i)si=getchar(); - i; expand(s,i); for(k=0;k=0&=0&bufbuf i i=9)=0&=0&bufbuf i i=9)=9) n=n n=n* *10+buf10+bufi i-0;-0; i i+;+; 保存保存n n為系數(shù)或指數(shù);為系數(shù)或指數(shù); else else i i+;+; 54 8 2 6 7 3 25 1 78 0 問題問題3.4:問題分析(續(xù)):問題分析(續(xù))0 a0 1 a1 n-1 an-1 n an 54 8 2 6 7 3 2

39、5 1 78 0 a0 a1 a2 a3 an-2 an-1 an 0 1 2 3 n-2 n-1 n 將將an保存在下標為保存在下標為n的數(shù)組元素中,數(shù)組長度為的數(shù)組元素中,數(shù)組長度為51(050),即即arrayn = a;n如何保存輸入的多項式系數(shù)和指數(shù)?如何保存輸入的多項式系數(shù)和指數(shù)?問題問題3.4:算法設(shè)計:算法設(shè)計1.1.令:令:int array151,int array251;int array151,int array251;分別用來分別用來存儲第一個多項式和第二個多項式;存儲第一個多項式和第二個多項式;2.2.初始化數(shù)組初始化數(shù)組array1array1和和array2ar

40、ray2元素值均為元素值均為0 0;3.3.讀入第一行數(shù)據(jù)保存在數(shù)組讀入第一行數(shù)據(jù)保存在數(shù)組array1array1中;中;4.4.讀入第二行數(shù)據(jù)保存在數(shù)組讀入第二行數(shù)據(jù)保存在數(shù)組array2array2中;中;5.5.依次將數(shù)組依次將數(shù)組array1array1和和array2array2相應(yīng)元素相加,并將相應(yīng)元素相加,并將結(jié)果放到結(jié)果放到array1array1中,即中,即array1i=array1i+array2iarray1i=array1i+array2i;6.6.依次從后往前輸出數(shù)組依次從后往前輸出數(shù)組array1array1中不為中不為0 0的元素。的元素。用一個函數(shù)來分別讀入

41、用一個函數(shù)來分別讀入兩個多項式的系數(shù)和指兩個多項式的系數(shù)和指數(shù),如,數(shù),如,void getexp(int a );問題問題3.4:代碼實現(xiàn):代碼實現(xiàn)/c3_4.c#include #define length 51void getexp(int array);int main()int array1length,array2length,i;for(i=0; ilength; i+) array1i =0;for(i=0; ilength; i+) array2i =0;getexp(array1);getexp(array2);for (i=0;i=0;i- )if(array1i0) p

42、rintf(%d %d ,array1i, i );printf(n);void getexp(int array) int a,n; char c; do scanf(“%d%d%c”, &a, &n, &c); arrayn = a; while ( c != n);初始化數(shù)組初始化數(shù)組從標準輸入中讀從標準輸入中讀數(shù)據(jù)到數(shù)組中數(shù)據(jù)到數(shù)組中兩多項式相應(yīng)項兩多項式相應(yīng)項相加相加輸出多項式系數(shù)輸出多項式系數(shù)不為不為0的項。的項。問題問題3.4:測試:測試n正常數(shù)據(jù):正常數(shù)據(jù): 54 8 2 6 7 3 25 1 78 0 43 7 4 2 8 1 期望結(jié)果:期望結(jié)果: 5

43、4 8 43 7 2 6 7 3 4 2 33 1 78 0 n邊界數(shù)據(jù)邊界數(shù)據(jù)1: 105 50 23 49 46 25 12 1 57 0 203 50 22 48 21 25 13 2 9 1 200 0 期望結(jié)果:期望結(jié)果: 308 50 23 49 22 48 67 25 13 2 21 1 257 0 n 邊界數(shù)據(jù)邊界數(shù)據(jù)2: 12 50 25 0 期望結(jié)果:期望結(jié)果: 12 50 25 0 問題問題3.4:常見問題分析:常見問題分析n未初始化數(shù)組(未初始化數(shù)組(觀察下面用正常測試數(shù)據(jù)程序運行時現(xiàn)象,觀察下面用正常測試數(shù)據(jù)程序運行時現(xiàn)象,如何調(diào)試?)如何調(diào)試?)/c3_4a.c#i

44、nclude #define length 51void getexp(int array);int main()int array1length,array2length,i;getexp(array1);getexp(array2);for (i=0;i=0;i- )if(array1i0) printf(%d %d ,array1i, i );printf(n);問題問題3.4:常見問題分析(續(xù)):常見問題分析(續(xù))n最后一對數(shù)據(jù)沒有讀入,例如:(最后一對數(shù)據(jù)沒有讀入,例如:(觀察用正常測試數(shù)據(jù)程序觀察用正常測試數(shù)據(jù)程序運行時現(xiàn)象,如何調(diào)試?)運行時現(xiàn)象,如何調(diào)試?)/*c3_4b.c*

45、/void getexp(int array) int a,n,c; scanf(%d%d,&a,&n); while ( (c = getchar() !=n ) arrayn=a; scanf(%d%d,&a,&n); n 如何修改?修改方法一:修改方法一:void getexp(int array) int a,n,c; scanf(%d%d,&a,&n); while ( (c = getchar() !=n ) arrayn=a; scanf(%d%d,&a,&n); arrayn = a;修改方法二:修改方法二:voi

46、d getexp(int array) int a,n,c; scanf(%d%d,&a,&n); arrayn = a; while ( (c = getchar() !=n ) scanf(%d%d,&a,&n); arrayn=a; 問題問題3.4:思考:思考n其它輸入方法及算法?其它輸入方法及算法?例如:鏈表例如:鏈表n問題問題3.4實現(xiàn)了兩個多項式相加運算,如何實現(xiàn)兩實現(xiàn)了兩個多項式相加運算,如何實現(xiàn)兩個個多項式相乘多項式相乘?第三講:程序設(shè)計方法-問題分析50問題問題3.5:超長正整數(shù)加法:超長正整數(shù)加法【問題描述問題描述】編寫程序?qū)崿F(xiàn)兩個超長正整數(shù)

47、(每個最長編寫程序?qū)崿F(xiàn)兩個超長正整數(shù)(每個最長80位數(shù)字)的加法運算。位數(shù)字)的加法運算?!据斎胄问捷斎胄问健繌逆I盤讀入兩個整數(shù),不考慮輸入高位可能為從鍵盤讀入兩個整數(shù),不考慮輸入高位可能為0的情況。的情況。1. 第一行是超長正整數(shù)第一行是超長正整數(shù)a;2. 第二行是超長正整數(shù)第二行是超長正整數(shù)b;【輸出形式輸出形式】 輸出只有一行,是兩個長整數(shù)的運算結(jié)果,從高到低依次輸出各位數(shù)字。輸出只有一行,是兩個長整數(shù)的運算結(jié)果,從高到低依次輸出各位數(shù)字。各位數(shù)字緊密輸出。各位數(shù)字緊密輸出?!据斎霕永斎霕永?34098703578230056234098【輸出樣例輸出樣例】1340987035784

48、64154【樣例說明樣例說明】進行兩個正整數(shù)加法運算,進行兩個正整數(shù)加法運算,134098703578230056 + 234098 = 134098703578230056 + 234098 = 134098703578464154134098703578464154。第三講:程序設(shè)計方法-問題分析51問題問題3.5:問題分析:問題分析n如何讀入和存儲超長整數(shù)?(如何讀入和存儲超長整數(shù)?(為何不能用長整數(shù)類型為何不能用長整數(shù)類型long int n; scanf(“%ld”,&n);來存儲和讀入超長整數(shù)來存儲和讀入超長整數(shù)?)?)l方法一:用字符串方式來讀入和存儲超長整數(shù)方法一:用字

49、符串方式來讀入和存儲超長整數(shù)char intstr81;scanf(“%s”, intstr);l方法二:用整數(shù)數(shù)組來存儲超長整數(shù),用字符方式依次方法二:用整數(shù)數(shù)組來存儲超長整數(shù),用字符方式依次讀入超長整數(shù)的每位數(shù)字讀入超長整數(shù)的每位數(shù)字int lint80;char d,i=0;while(d=getchar()!= n) linti+ = d 0;l其它方法?其它方法?52問題問題3.5:解題思路:解題思路n在程序中在程序中數(shù)組是從左至右方式存儲的數(shù)組是從左至右方式存儲的,而,而整數(shù)相加是從右至左整數(shù)相加是從右至左(從低位到高(從低位到高位),同時由于被加數(shù)長短不一,造成計算和轉(zhuǎn)換非常不方

50、便。一種解決方位),同時由于被加數(shù)長短不一,造成計算和轉(zhuǎn)換非常不方便。一種解決方法是法是整數(shù)相加前將兩個整數(shù)位串首尾顛倒整數(shù)相加前將兩個整數(shù)位串首尾顛倒,與計算機存儲方式一致。,與計算機存儲方式一致。n如何進行超長整數(shù)加?如何進行超長整數(shù)加?無論以什么方式存儲超長整數(shù),每位相加結(jié)果和進位計算方式為:無論以什么方式存儲超長整數(shù),每位相加結(jié)果和進位計算方式為:dightdighti i = (digit1 = (digit1i i + digit2 + digit2i i + carry) % 10 + carry) % 10 (carrycarry為上一次計算產(chǎn)生的進位)為上一次計算產(chǎn)生的進位)carry = (digit1carry = (digit1i i + digit2 + digit2i i + carry) / 10 + carry) / 10 (得到新的進位)(得到新的進位)注意:注意:l 若以字符串方式存儲超長整數(shù),則在計算每位加和進位時,應(yīng)考慮若以字符串方式存儲超長整數(shù),則在計算每位加和進位時,應(yīng)考慮數(shù)字字符和整數(shù)字字符和整數(shù)數(shù)字之間的轉(zhuǎn)換數(shù)數(shù)字之間的轉(zhuǎn)

溫馨提示

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

評論

0/150

提交評論