中文字幕精品无码一区二区,成全视频在线播放观看方法,大伊人青草狠狠久久,亚洲一区影音先锋色资源

[教案]pascal教程(整理版)

資源下載
  1. 二一教育資源

[教案]pascal教程(整理版)

資源簡介

TOC \o \h \z HYPERLINK \l "_Toc20129722" 第一章 簡單程序 2
HYPERLINK \l "_Toc20129723" 第一節 Pascal 程序結構和基本語句 2
HYPERLINK \l "_Toc20129724" 第二節 順序結構程序與基本數據類型 6
HYPERLINK \l "_Toc20129725" 第二章 分支程序 10
HYPERLINK \l "_Toc20129726" 第一節 條件語句與復合語句 10
HYPERLINK \l "_Toc20129727" 第二節 情況語句與算術標準函數 12
HYPERLINK \l "_Toc20129728" 第三章 循環程序 16
HYPERLINK \l "_Toc20129729" 第一節 for 循環 16
HYPERLINK \l "_Toc20129730" 第二節 repeat 循環 22
HYPERLINK \l "_Toc20129731" 第三節 While 循環 27
HYPERLINK \l "_Toc20129732" 第四章 函數與過程 32
HYPERLINK \l "_Toc20129733" 第一節 函數 32
HYPERLINK \l "_Toc20129734" 第二節 自定義過程 35
HYPERLINK \l "_Toc20129735" 第五章 Pascal的自定義數據類型 40
HYPERLINK \l "_Toc20129736" 第一節 數組與子界類型 40
HYPERLINK \l "_Toc20129737" 第二節 二維數組與枚舉類型 48
HYPERLINK \l "_Toc20129738" 第三節 集合類型 56
HYPERLINK \l "_Toc20129739" 第四節 記錄類型和文件類型 60
HYPERLINK \l "_Toc20129740" 第五節 指針類型與動態數據結構 67
HYPERLINK \l "_Toc20129741" 第六章 程序設計與基本算法 73
HYPERLINK \l "_Toc20129742" 第一節 遞推與遞歸算法 73
HYPERLINK \l "_Toc20129743" 第二節 回溯算法 80
HYPERLINK \l "_Toc20129744" 第七章 數據結構及其應用 86
HYPERLINK \l "_Toc20129745" 第一節 線性表 86
HYPERLINK \l "_Toc20129746" 第二節 隊列 90
HYPERLINK \l "_Toc20129747" 第三節 棧 93
HYPERLINK \l "_Toc20129748" 第四節 數組 97
HYPERLINK \l "_Toc20129749" 第八章 搜索 100
HYPERLINK \l "_Toc20129750" 第一節 深度優先搜索 100
HYPERLINK \l "_Toc20129751" 第二節 廣度優先搜索 111
HYPERLINK \l "_Toc20129752" 第九章 其他常用知識和算法 115
HYPERLINK \l "_Toc20129753" 第一節 圖論及其基本算法 115
HYPERLINK \l "_Toc20129754" 第二節 動態規劃 122
第一章 簡單程序
無論做任何事情,都要有一定的方式方法與處理步驟。計算機程序設計比日常生活中的事務處理更具有嚴謹性、規范性、可行性。為了使計算機有效地解決某些問題,須將處理步驟編排好,用計算機語言組成“序列”,讓計算機自動識別并執行這個用計算機語言組成的“序列”,完成預定的任務。將處理問題的步驟編排好,用計算機語言組成序列,也就是常說的編寫程序。在Pascal語言中,執行每條語句都是由計算機完成相應的操作。編寫Pascal程序,是利用Pascal語句的功能來實現和達到預定的處理要求。“千里之行,始于足下”,我們從簡單程序學起,逐步了解和掌握怎樣編寫程序。
第一節 Pascal 程序結構和基本語句
在未系統學習Pascal語言之前,暫且繞過那些繁瑣的語法規則細節,通過下面的簡單例題,可以速成掌握Pascal程序的基本組成和基本語句的用法,讓初學者直接模仿學習編簡單程序。
[例1.1]編程在屏幕上顯示“Hello World!”。
Pascal程序:
Program ex11;
Begin
Writeln(‘Hello World!’);
ReadLn;
End.
這個簡單樣例程序,希望大家的程序設計學習能有一個良好的開端。程序中的Writeln是一個輸出語句,它能命令計算機在屏幕上輸出相應的內容,而緊跟Writeln語句后是一對圓括號,其中用單引號引起的部分將被原原本本地顯示出來。
[例1.2]已知一輛自行車的售價是300元,請編程計算a輛自行車的總價是多少?
解:若總售價用m來表示,則這個問題可分為以下幾步處理:
①從鍵盤輸入自行車的數目a;
②用公式 m=300*a 計算總售價;
③輸出計算結果。
Pascal程序:
Program Ex12; {程序首部}
Var a,m : integer; {說明部分}
Begin {語句部分}
Write(‘a=’);
ReadLn(a); {輸入自行車數目}
M := 300*a; {計算總售價}
Writeln(‘M=’,m); {輸出總售價}
ReadLn; {等待輸入回車鍵}
End.
此題程序結構完整,從中可看出一個Pascal 程序由三部分組成:
(1)程序首部
由保留字Program開頭,后面跟一個程序名(如:Exl1);其格式為:
Program 程序名;
程序名由用戶自己取,它的第一個字符必須是英文字母,其后的字符只能是字母或數字和下劃線組成,程序名中不能出現運算符、標點符和空格。
(2)說明部分
程序中所用的常量、變量,或類型、及過程與自定義函數,需在使用之前預先說明,定義數據的屬性(類型)。[例1.2] 程序中 Var S,R,C: Real; 是變量說明,此處說明S,R,C三個變量均為實數類型變量。只有被說明為某一類型的變量,在程序中才能將與該變量同類型的數值賦給該變量。變量說明的格式為:
Var 變量表:類型;
(3)語句部分
指由保留字 Begin (開始)至 End. (結尾)之間的語句系列,是解決問題的具體處理步驟,也是程序的執行部分。
Pascal程序不管是哪部分,每句末尾都必須有分號(;),但允許最接近 End 的那個語句末尾的分號省略;程序結束的End末尾必須有圓點(. ),是整個程序的結束標志。
程序中花括號“{ }”之間的部分為注釋部分。
Pascal程序結構可歸納用如下的示意圖來表示:
Program 程序名; 程序首部
標號說明; (Label)
常量說明; (Const) 說明部分
類型說明; (Type)
變量說明; (Var)
過程或函數說明;
Begin 程序體 (主程序)
語句系列; 語句部分
End.
圖1.1 Pascal程序的結構
把處理問題的步驟編成能從上到下順序執行的程序,是簡單程序的基本特征。再來分析下面兩道例題的Pascal程序結構和繼續學習基本語句。
[例1.3]編程計算半徑為R的圓的面積和周長。
解:這是一個簡單問題,按數學方法可分以下幾步進行處理:
① 從鍵盤輸入半徑的值R; { 要求告訴圓的半徑R }
② 用公式 S=πR2 計算圓面積;
③ 用公式 C=2πR 計算圓周長;
④ 輸出計算結果。
Pascal程序:
Program Ex13; {程序首部 }
Var R,S,C: Real; {說明部分 }
Begin {語句部分 }
Write ('R= ');
Readln(R); {輸入半徑 }
S:=Pi*R*R; {圓面積公式S=πR2}
C:=2*Pi*R; {圓周長公式C=2πR}
Writeln('S=',S); {輸出結果 }
Writeln('C=',C);
Readln {等待輸入回車鍵}
End.
程序中Pi是Pascal提供的標準函數,它返回圓周率的近似值:3.1415926…。
(:=)是賦值符號,賦值語句的格式為:
變量:=表達式;
賦值語句的作用是將:=右邊表達式的值記錄到左邊的變量中。
Writeln是輸出語句,輸出語句有三種格式:
① Write (輸出項1,輸出項2) ; {執行輸出后光標不換行}
② Writeln (輸出項1,輸出項2) ; {執行輸出后光標換到下一行}
③ Writeln {僅輸出空白且光標換到下一行}
Writeln語句后面的圓括號以內部分均為輸出項,可以是多項,各項間用逗號分隔; 對單引號里的內容按照引號內的原樣(字符)輸出顯示。如果輸出項是表達式,則只輸出表達式的值,而不是表達式本身。
[例1.4] 輸出兩個自然數相除的商和余數。
解:設被除數、除數、商和余數,分別為A,B,C,D,均為變量,且都是整數類型。題中未給出具體的自然數A、B,可采用鍵盤輸入方式。
① 給出提示,從鍵盤輸入a, b;
② 顯示兩數相除的數學形式;
③ 求出a除以b的商c;
④ 求出a除以b的余數d;
⑤ 緊接等式后面輸出顯示商和余數。
Pascal程序:
Program Ex14;
Var a,b,c,d : integer;
Begin
Write('INPUT A,B:'); {給出提示信息}
Readln(a,b); {輸入a,b}
Writeln; {輸出一空行}
Write(a,'/',b,'='); {輸出等式之后不換行}
c:=a div b; {整除運算,取商的整數部分}
d:=a mod b; {相除求余運算,取商的余數部分}
Writeln(C,'…',d); {輸出后自動換行 }
Readln {等待輸入回車鍵 }
End.
執行本程序中第一個Write語句,輸出其引號以內的一串提示信息,是給緊接著的輸入語句提供明確的提示(要求),有“一目了然,人機對話”之效果。
Readln是一個特殊的輸入語句,要求輸入一個回車(換行)才能往下執行。
Readln是輸入語句,它的一般格式為:
① Read (變量1,變量2);
② Readln (變量1,變量2);
③ Readln
前兩種格式均要從鍵盤給變量輸入數據,輸入時,所鍵入的數據之間以空格為分隔,以回車為輸入結束。若多輸入了數據(即數據個數超過變量個數),Read語句讀完數據之后,能讓后續的讀語句接著讀取多下來的數據;而Readln 語句對本行多輸入的數據不能讓后續語句接著讀取多下來的數據。為了防止多輸入的數據影響下一個輸入語句讀取數據,建議盡量使用Readln語句輸入數據。第三種格式不需輸入數據,只需按入一個回車鍵。
[例1.5]自然數的立方可以表示為兩個整數的平方之差,比如43=102-62,請輸出自然數1996的這種表示形式。(這里的43用自乘三次的形式4*4*4表示;102也用自乘二次的形式10*10表示)
解:此題沒有現成的計算公式能直接利用,但可以自行推出處理方法或構建適當的運算公式,按著構想的處理方案編排出各步驟。
設這個自然數為N,兩個平方數分別為X,Y, 將問題表示為求 N3=X2—Y2
① 先找出X的值,仔細觀察題中的示例,用數學方法歸納可得出X=N*(N+1)/2;(構成本題可用的計算公式)
② 再仔細觀察,發現Y值比X小一個N值,即 Y=X—N;
③ 輸出等式 N3=X2—Y2 或N*N*N=X*X—Y*Y
Pascal程序:
Program Ex15;
Const N=1996; {常量說明 }
Var X,Y: Longint; {變量說明,此題計算中的數值較大,用長整型 }
Begin
X:=N*(N+1) div 2; { div 是整除運算 }
Y:=X-N;
Writeln(N,'*',N,'*', N,'=', X,'*', X,'—',Y,'*',Y); { 輸出結果 }
Readln
End.
本程序中N是常量,X,Y是變量,為長整數類型(Longint); 程序中的div 是整除運算,其結果只取商的整數部分;
[例1.6] 求一元二次方程x2+3x+2=0的兩個實數根。
解:方程的系數是常量,分別用a,b,c表示,可運用數學上現成的求根公式求方程的根,采取如下方法:
① 先求出d=b2-4ac;(求根公式中需用開方運算的那部分)
② 再用求根公式算出x1,x2的值。(x1,x2 = )
③ 輸出x1,x2.
Pascal程序:
program Ex16;
Const a=1; {常量說明 }
b=3;
c=2; {a,b,c表示方程系數}
Var d : integer; {d為整型變量}
X1,X2: Real; {X1,X2為實型變量}
Begin
d:=b*b-4*a*c;
x1:=(-b+sqrt(d))/(2*a); {求方程的根}
x2:=(-b-sqrt(d))/(2*a);
Writeln('X1=',X1,'?':6,'X2=',X2);{輸出結果}
Readln {等待輸入一個回車鍵}
End.
本程序中的a,b,c均為常量;變量d是整數類型,而變量x1,x2則是實數類型,因為運算式中的Sqrt(d)開平方運算和(/)除法運算使結果為實數。Sqrt( ) 是開平方函數,是Pascal系統的一個標準函數。
習題1.1 模仿例題編程
1. 加法計算器:編程由鍵盤輸入兩個整數a和b,計算出它們的和并輸出到屏幕上。
2. 某梯形的上底、下底和高分別為8,12,9,求該梯形的面積。
( 梯形面積公式為 S=
3. 求右圖所示邊長為5.6 的正立方體表面積。
4. 已知圖園柱體的高為12,底面園的半徑為7,求園柱體表面積。
5. 計算某次考試語文、數學、英語和計算機等四科的總成績與平均成績。
(請用輸入語句從鍵盤輸入各科成績分)
第二節 順序結構程序與基本數據類型
前面的簡單程序已體現出處理問題步驟、思路的順序關系,這就是順序結構程序。
[例1.7]交換兩個變量的值:由鍵盤輸入兩個正整數A和B,編程交換這兩個變量的值。
解:交換兩個變量的值,可以想象成交換兩盒錄音帶(稱為A和B)的內容,可以按以下步驟處理:
步驟①:拿一盒空白錄音帶C為過渡,先將A翻錄至C;
步驟②:再將B翻錄至A;
步驟③:最后將C翻錄至B。
這樣操作,可達到題目要求。
Pascal程序:
Program Exam17;
Var a,b,c : integer;
Begin
Write(‘A,B=’);
Readln(a,b);
C:= A; {等價于步驟1}
A := B; {等價于步驟2}
B := C; {等價于步驟3}
Writeln(A,B);
End.
[例1.8] 分錢游戲。甲、乙、丙三人共有24元錢,先由甲分錢給乙、丙兩人,所分給的數與各人已有數相同;接著由乙分給甲、丙,分法同前;再由丙分錢給甲、乙,分法亦同前。經上述三次分錢之后,每個人的錢數恰好一樣多。 求原先各人的錢數分別是多少
解:設甲、乙、丙三人的錢數分別為A,B,C。用倒推(逆序)算法, 從最后結果入手,按反相順序,分步驟推算出每次各人當時的錢數:(在每個步驟中,各人錢數分別存在A、B、C中)
步驟①: A=8 B=8 C=8 {這是最后結果的錢數,三人都一樣多 }
步驟②: A=A/2 (=4) B=B/2 (=4) C=A+B+C(=16) { A,B未得到丙分給的錢時,只有結果數的一半;C應包含給A,B及本身數三者之和 }
步驟③: A=A/2 (=2) C=C/2 (=8) B=A+B+C(=14) {A,C未得到乙分給的錢時,只有巳有數的一半;B應包含給A,C及本身數三者之和 }
步驟④: B=B/2 (=7) C=C/2 (=4) A=A+B+C(=13)
C未得到甲分給的錢時,只有巳有數的一半;A應包含給B,C及本身數三者之和 }
步驟⑤: 輸出A(=13)B(=7)C(=4){此時的A,B,C 就是三人原先的錢數 }
Pascal程序:
Program Exam18;
Var a,b,c: integer;
Begin
a:=8; b:=8; c:=8; {對應于步驟①}
a:=a div 2; b:=b div 2; c:=a+b+c; {對應于步驟②}
a:=a div 2; c:=c div 2; b:=a+b+c; {對應于步驟③}
b:=b div 2; c:=c div 2; a:=a+b+c; {對應于步驟④}
Writeln('a=',a,' ': 4,'b=',b,' ': 4,'c=',c) ;  {輸出}
Readln
End.
細心觀察,會發現本程序語句的順序很關鍵。此例用反推順序(逆序),按步驟正確推算出各變量的值。當然,有的問題可按正序步驟編程,這類程序都稱為順序程序。
本程序Writeln語句的輸出項含有( ' ' : 4 ),這里的冒號用來指定該項顯示所占寬度,此處是輸出4個空格即(空格項占4格)。
[例1.9] 有雞兔同籠,頭30,腳 90,究竟籠中的雞和兔各有多少只
解:設雞為J只,兔為T只,頭為H,腳為F,則:
J+T=30 ①
2*J+4*T=90 ②
解此題暫不必采用數學上直接解方程的辦法,可采用“假設條件與邏輯推理”的辦法:
假設籠中30 個頭全都是兔,那么都按每頭4只腳計算,總腳數為(4*H),與實際腳數 ( F )之差為(4*H—F),如果這個差=0,則籠中全是兔(即雞為0只);如果這個差值 >0,說明多計算了腳數,凡是雞都多給算了兩只腳,用它除以2就能得到雞的只數,處理步驟為:
① J=(4*H—F)/2 {先用腳數差值除以2算出雞的只數}
② T=H—J {再用總頭數減雞數算出免的只數}
按此方法,這兩步運算必須注意先后順序才會符合運算邏輯。
Pascal程序:
Program Exam16;
Const H=30; {常量說明 }
F=90;
Var J,T: byte; {為字節類型的整數 }
Begin
J:=(4*H-F) div 2; {整除運算 }
T:=H-J
Writeln ('J=',J,' ': 6,'T= ',T ) ;
Readln
End.
本程序中H,F為常量,變量J,T為byte類型,屬于整數類型。
Pascal定義了五個標準整數類型,如下表所示:
類型 取值范圍 占字節數 格式
Shortint(短整型) -128..127 1 帶符號8位
Integer (整型) -32768..32767 2 帶符號16位
Longint(長整型) -2147483648..2147483647 4 帶符號32位
Byte (字節型) 0..255 1 無符號8位
Word  (字型) 0..65535 2 無符號16位
在前面程序中常用的數據類型除整數類型,還有實數類型。Pascal 還定義了五個標準實數類型,列表所示如下:
類型 取值范圍 占字節數 有效數字
Real 2.9×10-39~1.7×1038 6 7~8位
Single 1.5×10-45~3.4×1038 4 11~12位
Double 5.0×10-324~1.7×10308 8 15~16位
Extended 1.9×10-4951~1.1×104932 10 19~20位
Comp -263+1~238-1 8 19~20位
在Turbo Pascal 中實數的表示用科學記數法,可認為由三部分組成:
# . ## E +## 或 # . ## E -##
① #.##表示有效數字; ② E表示以10為底的冪; ③ +##或-##是指數部分,+號可省略。
例如: 1.7E+38 可寫成1.7E38 (等同于1. 7×1038 )。
在實數類型定義下,即使是整數,在程序執行時系統也將自動轉換成科學記數形式,試請運行下面程序并注意觀察運行結果:
Program Exam17;
Var x: real; {x為實數類型 }
Begin
X:=180; {把整數180賦給實數類型變量X}
Writeln ('x=',x) ;     {輸出的x自動表示成實數形式 }
Readln
End.
習題1. 2
1.已知△ABC中的三邊長分別為25.76,74.03,59.31,求△ABC的面積。
( 計算公式: S= 。 其中P = )
2.某車棚存有自行車和三輪車共65輛,它們的輪子數合計為150個。求該棚內存有的自行車和三輪車各是多少輛?
3.甲、乙、丙三人分別有磁帶36,48,64盒。先由甲把自己的磁帶平均分為三份,分給乙、丙各一份,自己留下一份;接著是乙,最后是丙,都按甲的方法處理。編程輸出甲、乙、丙在上述過程中各人的磁帶數分別是多少 (輸出所有的中間結果)
4.五位好朋友相聚。第一位朋友帶來了很多糖塊贈送給各位朋友,使每人的糖塊在各自原有的基礎上翻了一倍;接著第二位好友也同樣向每人贈送糖塊,他同樣使每人的糖塊在各人已有的數量上翻了一倍;第三、第四、第五位好友都照此辦理。經過這樣的贈送之后,每人的糖塊恰好都為32塊。問各位好友原先的糖塊數分別是多少
第二章 分支程序
在程序設計中,許多問題是在一定條件下才選擇某種處理方式的,這就需要用條件判斷語句或情況選擇語句進行處理。程序執行中將出現選擇(分支),根據條件只選擇執行部分語句,不一定都是按原順序從頭到尾地執行所有語句,這樣的程序稱為分支程序。
第一節 條件語句與復合語句
[例2.1] 某服裝公司為了推銷產品,采取這樣的批發銷售方案:凡訂購超過100 套的,每套定價為50元,否則每套價格為80元。編程由鍵盤輸入訂購套數,輸出應付款的金額數。
解:設X為訂購套數,Y為付款金額,則:
① 輸入X;
② 判斷 X 值;
③ 根據判斷結果選擇符合條件的那種方法計算Y值;
④ 輸出計算結果。
Pascal程序:
Program Exam21;
Var x,y: integer;
Begin
Write('X=') ;Readln(x) ; { 輸入X}
if x >100 then y:=50*X else y:=80*X; {條件判斷與選擇 }
Writeln('y=',y) ;
Readln
End.
程序中的 if 語句常稱為條件語句,它的一般格式為:
(1) if 條件 then 語句;
(2) if 條件 then 語句1 else 語句2;
IF 語句的功能是按條件在兩種可能中選擇其中一種。習慣上把if 后面的表達式稱為條件,then 后面的語句稱為真項,else 后面的語句稱為假項。若條件成立(為真)就執行真項,然后執行if語句的后繼語句;若條件不成立(為假)就跳過真項而執行假項,然后執行后繼語句。而第一種格式只有真項,沒有假項,當條件不成立(為假)就什么也不需做,直接往下去執行后繼語句。
[例2.2] 讀入三個不同的數,編程按由小到大的順序排列打印出來。
解:設讀入的三個數為a,b,c,為了把較小的數排在前面,可作如下處理:
① 如果a>b就交換a、b的值,將較大的值換至后面;
② 如果a>c就交換a、c的值,將較大的值換至后面;
③ 如果b>c就交換b、c的值,將較大的值換至后面;
④ 輸出處理后的a,b,c。
Pascal程序:
Progranm Exam22;
Var a,b,c,t: Real;
Begin
Write('Input a, b,c=');
Readln(a,b,c);
if a>b then
begin {復合語句}
t:=a; a:=b; b:=t {交換a,b}
end;
if a>c then
begin {復合語句}
t:=a; a:=c; c:=t {交換a,c}
end;
if b>c then
begin {復合語句}
t:=b; b:=c; c:=t {交換b,c}
end;
Writeln('a,b,c:',a:6, b:6, c:6);
Readln
End.
if 語句規定它的真項或假項位置上只能是一個基本語句,如果需要寫一組語句,就應當使用復合語句。本程序中有三處用到復合語句。每個復合語句的范圍是從Begin開始到與它相對應的End為止。復合語句的地位和一個基本語句相同;其一般格式為:
Begin
語句系列
End;
習題2. 1
1.假設郵局規定寄郵件時若每件重量在1公斤以內(含1公斤),按每公斤1.5元計算郵費,如果超過1公斤時,其超出部分每公斤加收0.8元。請編程序計算郵件收費。
2.輸入三個正整數,若能用這三個數作為邊長組成三角形,就計算并輸出該三角形的面積,否則輸出Can't。(組成三角形的條件為:任意兩邊之和大于第三邊)
3.輸入一個三位數的整數,將數字位置重新排列,組成一個盡可大的三位數。例如:輸入213,重新排列可得到盡可能大的三位數是321。
第二節 情況語句與算術標準函數
如果有多種(兩種或兩種以上)選擇,常用情況語句編程。
將前面[例2.1]改成用如下方法來處理。根據題意,付款計算可分為兩種情況:
① Y=50*X (X>100)
② Y=80*X (X<=100)
顯然,情況①與②的選擇取決于X值。假設用N表示“情況值”,暫且先讓N=2;
如果X>100則N=1;(此題中N的值只是1或2,且取決于X值)
Pascal 程序:
Program Exam21_1;
Var X,Y,N: integer;
Begin
Write('X=') ;readln(x) ; n:=2; { 先讓n=2 }
if X>100 then n:=1; {如果X>100則 n=1 }
Case n of { 關于情況處理 }
1: Y:=50*X;
2: Y:=80*X;
end;
Writeln('Y=',Y) ;
Readln
End.
程序中的 Case─end 語句為情況語句,是多路分支控制,一般格式為:
Case 表達式 of
情況常量表1: 語句1;
情況常量表2: 語句2;
: :
情況常量表n: 語句n
end;
執行情況語句時,先計算Case后面表達式的值,然后根據該值在情況常量表中的“對應安排”,選擇其對應的語句執行,執行完所選擇語句后就結束Case語句;如果常量表中沒有一個與表達式值對應的語句,則什么也不做就結束本Case語句。
Case 語句的另一種應用格式為:
Case 表達式 of
情況常量表1: 語句1;
情況常量表2: 語句2;
: :
情況常量表n: 語句n;
else 語句 n+1
end;
這種格式的前面部分是相同的,所不同的是:如果常量表中沒有一個與表達式值對應的語句,則執行與else對應的語句,然后結束Case語句。
[例2.2] 對某產品征收稅金,在產值1萬元以上征收稅5%;在1萬元以下但在5000元
以上的征收稅3%;在5000元以下但在1000元以上征收稅2%;1000元以下的免收稅。編程計算該產品的收稅金額。
解:設x為產值,tax為稅金,用P表示情況常量各值,以題意中每1000元為情況分界:
P=0: tax=0 (x<1000 )
P=1,2,3,4: tax=x*0.02 (1000<=x<5000 )
P=5,6,7,8,9: tax=x*0.03 (5000P=10: tax=x*0.05 (x> 10000 )
這里的P是“情況”值,用產值x除以1000的整數值作為P,如果P>10也歸入P=10的情況。Pascal語言用P=trunc(x/1000)取整計算,
Pascal程序:
Program Exam22;
Var x,p : integer;
Tax : real;
Begin
Write('Number=') ; readln(x) ;
P:=trunc(x/1000) ;
if P>9 then P:=10;
Case P of
0 : tax:=0;
1,2,3,4 : tax:=x*0.2;
5,6,7,8,9 : tax:=x*0.3;
10 : tax:=x*0.5
end;
Writeln('tt=',tt:5:2) ;
Readln
End.
情況表達式的計算必須考慮到“全部”情況,不要有遺漏。如果情況常量表的“值”在某范圍內是連續的,可將常量表寫成:
n1.. n2:語句;
因此,上面程序中的情況常量表可以寫成如下程序中表示形式:
Program Exam22_1;
Var x,p: integer;
tax: real;
Begin
Write('Number=') ; readln(x) ;
P:=trunc(x/1000) ;
if P>9 then P:=10;
Case P of
0 : tax:=0;
1..4 : tax:=x*0.2; { 從1至4作為同一情況處理 }
5..9 : tax:=x*0.3; { 從5至9作為同一情況處理 }
10 : tax:=x*0.5
end;
Writeln('tt=',tt:5:2) ;
Readln
End.
程序中的trunc(x)為取整函數,是Pascal的算術標準函數之一。Pascal常用的算術標準函數有19個:
(1) abs(x) 求x的絕對值(|x|);
(2) exp(x) 求ex的值; (e為無理數2.71828…)
(3) frac(x)求x的小數部分;
(4) int(x) 求x的整數部分(不舍入,函數值為實型);
(5) ln(x) 求以e為底的x的對數(log ex );
(6) odd(x) 判斷x的奇偶數(當x為奇數時odd(x)值為true,否則為false);
(7) ord(x) 求x的序號,結果為整型(x為有序類型量);
(8) pi π值(3.1415926535897932…);
(9) pred (x) 求x(有序類型)的前趨值;
(10) succ(x) 求x(有序類型)的后繼值;
(11) random 隨機函數,產生0~1的隨機值;
(12) random(n)產生0~n的隨機數(n為word類型,先執行randomize, 才能得到隨機整數);
(13) round(x) 求x的四舍五入整數;
(14) trunc(x) 求x的整數部分(截掉小數部分,結果為整型);
(15) sqr(x) 求x的平方值(x2 );
(16) sqrt(x) 求x的開平方根值( );
(17) sin(x) 求x的正弦函數(x為弧度);
(18) cox(x) 求x的余弦函數(x為弧度);
(19) arctan(x) 正切的反三角函數(x為數值);
習題2.2
1.運輸公司計算運費時,距離(S)越長,每公里運費越低,標準如下:
如果S<250公里;運費為標準運價的100%
如果250公里<=S<500公里,運費為標準運價的98%;
如果500公里<=S<1000公里,運費為標準運價的95%;
如果1000公里<=S<2000公里,運費為標準運價的92%;
如果2000公里<=S<3000公里,運費為標準運價的90%;
如果S=>3000公里,運費為標準運價的85%;。請編計算運費的程序。
2. 輸入考試成績,如果獲85分以上為 A等,獲60分~84分為B等,60分以下為C等,編程輸出考試等級。
3. 某車間按工人加工零件的數量發放獎金,獎金分為五個等級:每月加工零件數N < 100者獎金為10元;100 < = N < 110者獎金為30元;110 < = N <120 者獎金為50元;120 < = N <130 者獎金為70元;N > 130者為80元。
請編程,由鍵盤輸入加工零件數量,顯示應發獎金數。
第三章 循環程序
在編程中經常遇到需要多次規律相同的重復處理,這就是循環問題。Turbo Pascal采用不同的循環方式來實現,常用的環循有三種: for、repeat、while.
第一節 for 循環
for循環是一種自動計數型循環。
[例3.1] 試打印出1~20的自然數。
解:① 用a代表1~20各數,同時也用a兼作計數,以控制循環次數;
② 讓a從1開始;
③ 輸出a;
④ a自動計數(加1),如果未超越所規定的循環范圍則重復步驟③,否則結束循環。
Pascal程序:
Program Exam12;
Var a: byte;
Begin
for a:=1 to 20 do
Writeln (a);
Readln
End.
程序中 for a:=1 to 20 do Writeln (a); 是for循環語句。
for 循環語句有兩種格式:
(1) for 循環變量:=初值 To 終值 do 語句;
(2) for 循環變量:=初值 downto 終值 do 語句;
第(1)種格式的初值小于等于終值,循環變量值按自動加1遞增變化;
第(2)種格式的初值大于或等于終值,循環變量值按自動減1遞減變化。for 循環是 (以遞增1或以遞減1) 計數型循環。
比如: 若將[例3.1]程序改為倒計數(遞減)循環,則輸出20~1的自然數數:
Program Exam31;
Var a: byte;
Begin
for a:=20 downto 1 do
Writeln(a) ;
Readln
End.
[例3.2]打印出30至60的偶數。]
解:
方法一:
①設a表示30至60的所有的數,可用for循環列出;
②用式子 a mod 2=0 篩選出其中的偶數并輸出。
Pascal程序:
Program ex32;
Var a : integer;
Begin
For a := 30 to 60 do
If (a mod 2=0) then writeln(a);
Readln;
End.
在這個程序中,for循環后的循環語句是一個條件分支語句。
方法二:我們知道,在式子a=2*n中,若n取自然數1、2、3、…,時,則a依次得到偶數2、4、6、…。因此要想得到30至60的偶數,就可以讓上面式子中的n取15至30的自然數就可以了。所以本題還可以按以下步驟處理:
①設n表示15至30的所有自然數,可用for循環列出;
②用式子 a := 2*n 求出其中的偶數;
③將結果輸出至屏幕。
Pascal程序:
Program ex32;
Begin
For n := 15 to 30 do
Begin
a := 2*n;
Writeln(a);
End;
Readln;
End.
[例3.3]自然數求和:編一個程序,求從1至100的自然數的和。
解:① 令S=0;
② 令a表示1至100的自然數,用循環列出;
③ 將這些自然數用公式S:=S+a 逐一累加到S中去;
④ 循環結束后,S即為1至100的自然數的和,輸出即可。
Pascal程序:
Program ex33;
var s,a : integer;
Begin
S := 0;
For a := 1 to 100 do
S := S+a;
Writeln(‘S=’,S);
Readln;
End.
[例3.4]一個兩位數x,將它的個位數字與十位數字對調后得到一個新數y,此時y恰好比x大36,請編程求出所有這樣的兩位數。
解:① 用for循環列舉出所有的兩位數,x為循環變量;
② 用公式a:= x div 10分離出x的十位數字;
③ 用公式b:= x mod 10分離出x的個位數字;
④ 用公式y:= b*10+a合成新數y;
⑤ 用式子y-x=36篩選出符合條件的數x并輸出。
Pascal程序:
Program ex34;
Begin
For x := 10 to 99 do
Begin
a := x div 10;
b := x mod 10;
y := b*10+a;
if y-x=36 then writeln(x);
End;
Readln;
End.
[例3.5] 把整數3025從中剪開分為30和25兩個數,此時再將這兩數之和平方,(30+25)2=3025計算結果又等于原數。求所有符合這樣條件的四位數。
解:設符合條件的四位數為N,它應當是一個完全平方數,用(a*a)表示。
① 為了確保N=(a*a)在四位數(1000~9999)范圍內,可確定a在32~99循環;
② 計算N=a*a;將四位數N拆分為兩個數n1和n2;
③ 若滿足條件(n1+n2)*(n1+n2)=N 就輸出 N 。
Pascal程序:
Program Exam35;
Var N,a, x,n1,n2: Integer;
Begin
for a:=32 to 99 do
begin
N:=a*a;
n1:= N div 100; {拆取四位數的前兩位數}
n2:= N-n1*100; {拆取四位數的后兩位數}
X:=n1+n2;
if x*x=N then writeln (N);
end;
Readln
End.
[例3.6]用“*”號打印出如下的長方形圖案。
  *********
*********
*********
*********
解:① 上面給出的圖例共有4行,我們可以用一個循環控制行的變化;
② 在每行中又有9列,我們可以在前面控制行的循環中再套一個循環來控制列的變化。
Pascal程序:
Program ex36;
Begin
For a := 1 to 4 do {外循環控制行的變化}
Begin
For b := 1 to 9 do {內循環控制列的變化}
write(‘*’);
Writeln; {輸出一行的“*”后換行}
End;
Readln;
End.
程序中的循環對于a的每個值都包含著一個b=(1~9)次的內循環。外循環for a 將內循環for b 包含在里面,稱為for循環的嵌套。嵌套形式如:
for a:=n1 to n2 do
for b:=m1 to m2 do 循環體語句;
[例3.7] 打印出九九乘法表:
解:設a為被乘數,范圍為1~9;b為乘數,范圍為1~a;乘式為a*b=(a,b的乘積),則
a=1: b=1~a 1*1=1
a=2: b=1~a 2*1=2 2*2=4
a=3: b=1~a 3*1=3 3*2=6 3*3=9
a=4: b=1~a 4*1=4 4*2=8 4*3=13 4*4=16
: :
a=9 b=1~a 9*1=9 9*2=18 … 9*9=81
⑴從上面分解的橫行中看到共有9行,這里的“行”數變化與a的變化從1~9相同,可用a控制“行”的循環;
⑵每“行”里面相乘的次數與b的范圍相關,由b控制每“行”里面的“內部”循環;
⑶內循環被包含在最里層,執行完每“行”的內部循環,就到下一“行”去執行新“行”里面的循環,每“行”都擁有形式相同的( b=1~a )內循環。
即每到一“行”都要執行該“行”的內循環。這里所指的“行”可以理解成抽象的行,不一定是實際上具體對應的行,可以是一個處理“塊”。
Pascal程序:
Program Exam37;
Var a,b: byte;
Begin
for a:=1 to 9 do {外循環 }
begin
for b:=1 to a do {內循環 }
write(a,’* ’,b,’= ’,a*b,’ ’:3);
writeln
end;
Readln
End.
根據這種格式還可以實現多層循環嵌套,例如:
for a:=n1 to n2 do
for b:=m1 to m2 do
for c:=k1 to k2 do 循環體語句;
[例3.8]從七張撲克牌中任取三張,有幾種組合方法?請編程輸出所有組合形式。
解:設每次取出三張分別為a,b,c。用三重循環分別從1~7的范圍里取值;為了排除取到重號,用(a-b)*(b-c)*(a-c) < >0進行判斷。
Pascal程序:
program Exam38;
const n=7;
var a,b,c,t: integer;
Begin
t:=0;
for a:=1 to n do
for b:=1 to n do
for c:=1 to n do
if (a-b) * (b-c) * (a-c) < >0 then
Begin
inc (t);
writeln (a:3, b:3, c:3)
End;
writeln ( total:, t :5);
readln
End.
[例3.9] 數學上把除了1和它本身,沒有別的數能夠整除它的自然數叫做素數(或質數)。現在由鍵盤輸入一個自然數N,編程判斷N是否是素數,是則輸出“Yes”,否則輸出“No”。
解:根據定義,對于給定的自然數N,只需判斷除1和它本身外,還有沒有第三個自然數即可。
① 令K從1循環至N;
② 根據N mod K是否為0可統計K的約數的個數;
③ 若N的約數的個數超過2個,則判定N不是素數。
Pascal程序:
Program Exam39;
Var n,m,k,t: integer;
Begin
write(‘N=’);
ReadLn(N);
t:=0;
for k:=1 to N do {外循環 }
if N mod k=0 then t := t+1; {如果N是奇數 }
if t>2 then writeln(‘No’)
else writeln(‘Yes’);
Readln;
End.
程序中的變量yse為布爾(或邏輯)類型(Boolean)。布爾值只有兩個:
True(真) False(假)
布爾值與條件判斷結果為真(條件成立)或為假(條件不成立)的作用相同,常用于條件語句和循環語句中。
上面程序中用 if yes and (t mod 7=0) then writeln;實現每行打印七個素數換行,程序中布爾變量yes為真,在邏輯上表示是素數;關系式(t mod 7=0) 的值為真時,表示該行輸出素數巳是7個;用and將這兩個“條件”連起來是作一種布爾(邏輯)運算。
Pascal 共有四種邏輯運算符:
① and (與) 兩條件都為True時,其結果值為True;否則為False;
② or (或) 兩條件中只要有一個為True ;其結果值為True;否則為False;
③ xor (異或) 兩條件的邏輯值不相同時,其結果值為True;否則為False;
④ not (非) 條件為True時,其結果值為False;否則為True;(取反)
習題3.1:
1.打印出1至20的平方數表。
2.打印出100至200之間的奇數。
3. 雞兔同籠(用for循環程序完成)
4.一輛快車和一輛慢車開往同一地點,快車票價為18元,慢車票價為13. 5元,共售出400張,共計5940元,求快車票和慢車票各多少張 .
5.求出能被5整除的所有四位數的和。
6.在下面式子中的二個□內填入一個合適的同樣的數字,使等式成立。
□3*6528=3□*8256
7.有一個三位數,它的各位數字之和的11倍恰好等于它自身,請編程求出這個三位數。
8.在自然數中,如果一個三位數等于自身各位數字之立方和,則這個三位數就稱為是水仙花數。如:153=13+53+33,所以153是一個水仙花數。求所有的水仙花數。
9.編程序打印出下列圖案:
平行四邊形 等腰三解形      菱形
  ****** *   *
****** *** ***
****** ***** *****
****** ******* ***
****** ********* *
10.編程打印出如下圖案:
1
222
33333
4444444
555555555
11.有三種明信片:第一種每套一張,售價2元;第二種每套一張,售價4元; 第三種每套9張,售價2元。現用100元錢要買100張明信片,要求每種明信片至少要買一套,問三種明信片應各買幾套?請輸出全部購買方案。
12.某人想把一元錢換成伍分、貳分、壹分這樣的零錢, 在這三種零錢中每種零錢都至少各有一個的情況下,共有多少種兌換方案。并打出這些方案。
13.
14. 輸出100 以內的全部素數,要求每行顯示5 個。
15.A、B兩個自然數的和、差、積、商四個數加起來等于243,求A、B兩數。
16.百錢買百雞:今有錢100元,要買100只雞,公雞3元一只,母雞1元一只,小雞1元3只,若公雞、母雞和小雞都至少要買1只,請編程求出恰好用完100元錢的所有的買雞方案。
第二節 repeat 循環
Repeat循環是直到型循環。
試將上一節的例3.1(打印出1~20的平方數表)程序改為 repeat 循環:
Program Exam31_1;
Var a: byte;
Begin
a:=1; writeln ( ' a ' : 8 , ' a*a ' : 8 ) ;
repeat
writeln ( a :8,a*a : 8);
inc(a); {改變a的值 }
Until a>20;
Readln
Emd.
程序中的Repeat循環格式為:
repeat
循環體語句;
until 條件表達式; {直到條件為真}
Repeat循環首先執行由Repeat和Until括起來的循環體語句,然后檢查Until后面的條件表達式:如果表達式結果為假,則繼續執行循環體,接著繼續檢查Until后面的條件表達式,如此反復執行直到這個表達式結果為真時結束循環。Repeat循環體語句必須有能改變Until后面條件表達式值的語句,并最終使這個條件表達式的值為真,使循環自動結束。
程序中inc (a) 指令相當于a : =a+1,常用的同類指令格式如下:
(1) inc(x) 等同 x:=x+1;
(2) inc(x, n) 等同 x:=x+n;
(3) dec(x) 等同 x:=x—1;
(4) dec(x,n) 等同 x:=x—n;
[例3.10]求兩個自然數M和N的最大公約數。
解:若自然數a既是M和約數,又是N的約數,則稱a為M和N的公約數,其中最大的稱為最大公約數。為了求得最大公約數,可以從最大可能的數(如M或N)向下尋找,找到的第一個公約數即是最大公約數。
Pascal程序:
Program ex310;
Begin
a := N+1;
Repeat
a := a-1;
Until (M mod a=0) and (N mod a=0);
writeln(a);
Readln;
End.
[例3.11]校體操隊到操場集合,排成每行2人,最后多出1人;排成每行3人,也多出1人;分別按每行排4,5,6人,都多出1人;當排成每行7人時,正好不多。求校體操隊至少是多少人
解:①設校體操隊為X人,根據題意X應是7的倍數,因此X的初值為7,以后用inc(x,7)改變X值;
②為了控制循環, 用邏輯變量yes為真(True) 使循環結束;
③如果諸條件中有一個不滿足, yes 的值就會為假(false),就繼續循環。
Pascal程序:
program Exam311;
var x: word; yes : boolean;
begin
x:=0;
repeat
yes :=true; inc(x,7);
if x mod 2 < > 1 then yes:=false;
if x mod 3 < > 1 then yes:=false;
if x mod 4 < > 1 then yes:=false;
if x mod 5 < > 1 then yes:=false;
if x mod 6 < > 1 then yes:=false;
until yes; {直到yes的值為真 }
writeln('All =', x) ; readln
end.
程序中對每個X值,都先給Yes 賦真值,只有在循環體各句對X進行判斷時,都得到“通過”(此處不賦假值)才能保持真值。
[例3.12]從鍵盤輸入一個整數X(X不超過10000),若X的各位數字之和為7的倍數,則打印“Yes”,否則中打印“No”。
解:本題考察的是數字分離的方法,由于X的位數不定,所以以往的解法不能奏效,這是介紹一種取余求商法。
(1)用X mod 10分離出X的個位數字;
(2)用X div 10將剛分離的個數數字刪除,并將結果送回給X;
(3)重復(1)(2)直到X=0。
Pascal程序:
Program ex12;
var x,a,s : integer;
begin
s := 0;
repeat
a := x mod 10;
x := x div 10;
s := s+a;
until x=0;
if s mod 7=0 then writeln(‘Yes’)
else writeln(‘No’);
Readln;
end;
[例3.13]求1992個1992的乘積的末兩位數是多少?
解:積的個位與十位數只與被乘數與乘數的個位與十位數字有關,所以本題相當于求1992個92相乘,而且本次的乘積主下一次相乘的被乘數,因此也只需取末兩位參與運算就可以了。
Pascal程序:
Program ex313;
var a,t : integer;
Begin
a := 1;
t := 0;
repeat
t := t+1;
a := (a*92) mod 100;
until t=1992;
writeln(a);
Readln;
End.
[例3.14]尼科徹斯定理:將任何一個正整數的立方寫成一組相鄰奇數之和。
如: 33=7+9+11=27 43=13+15+17+19=64
解:從舉例中發現:
(1) n3正好等于n個奇數之和;
(2) n個奇數中的最小奇數是從1開始的奇數序列中的第m個奇數,與 n 的關系為: m=n (n —1) / 2+1。
(3) 奇數序列中第m個奇數的值為x,且 x= 2m—1,比如: n=3時,m=3(3-1)/2+1=4,即3個奇數中最小的奇數是奇數序列中的第4個,它的值為x=(2m-1)=7, 所以:33=7+9+11。
(4) 從最小的奇數值x開始,逐個遞增2,連續n個,用t從1開始計數,直到t=n為止。
Pascal程序:
Program Exam35;
Var n,m,x,t,s : integer;
Begin
write(’input n:’); readln(n); {輸入N }
m:=(n*(n-1) div 2)+1; {找到第m個奇數 }
x:=2*m-1; t:=1; {算出第m個奇數的值x,是所求的第一個}
write(n’*’,n,’*’,n,’=’,x);{輸出第一個}
s:=x; {用S計算和 }
if n>1 then
Repeat
inc(x,2); { 計算下一個奇數 }
write (’+ ’,x) ; {加上下一個奇數 }
inc (t ); inc (s,x); { 計個數并累加和 }
Until t=n; {直到n個 }
Writeln (’= ’,s ) ;
Readln
End.
[例3.15]猜價格:中央電視臺的“幸運52”欄目深受觀眾喜愛,其中的“猜商品價格”的節目更是膾炙人口,現在請你編一個程序模擬這一游戲:由計算機隨機產生200至5000之間的一個整數,作為某件商品的價格,然后由你去猜是多少,若你猜的數大了,則計算機輸出提示“Gao”,若你猜的數小了,則計算機輸出提示“Di”,然后你根據提示繼續猜,直到你猜對了,計算機會提示“Ok”,并統計你猜的總次數。
解:本題的游戲規則大家都清楚,要完成程序,必須把處理步驟理清:
  (1)用隨機函數Random產生200至5000之間的一個整數X;
(2)你猜一個數A;
(3)若A>X,則輸出“Gao”;
(4)若A<X,則輸出“Di”;
(5)若A=X則輸出“Ok”;
(6)重復(2)(3)(4)(5)直到A=X。
Pascal程序:
Program ex315;
Var t,X,a : integer;
Begin
Randomize;
X := Random(4800)+200;
t := 0;
Repeat
t := t+1;
write(‘[‘,t,’] Qing cai yi ge zheng shu : ‘);
readln(a);
if a>x then writeln(‘Gao’);
if aif a=x then writeln(‘Ok’);
Until A=X;
Readln;
End.
習題3.2
1.求兩個自然數M和N的最小公倍數。(如果求三個或更多個數的最小公倍數呢?應如何解決)
2.小會議室里有幾條相同的長凳,有若干人參加開會。如果每條凳子坐6人,結果有一條凳子只坐有3人;如果每條凳子坐5人,就有4人不得不站著。求會議室里有多少人開會,有多少條長凳
3.某動物飼養中心用1700元專款購買小狗(每只31元)和小貓(每只21元)兩種小動物。要求專款專用,正好用完, 應當如何購買 請輸出所有方案。
4.某整數X加上100就成為一個完全平方數,如果讓X加上168 就成為另一個完全平方數。求X
5.某次同學聚會,老同學見面個個喜氣洋洋,互相握手問好。參加此次聚會者每人都與老同學握了一次手,共握903次,試求參加聚會的人數?
6.用自然數300,262,205,167分別除以某整數A,所得到的余數均相同。求出整數A以及相除的余數?
7.1600年前我國的一部經典數學著作中有題:“今有物,不知其數,三三數之,剩二;五五數之,剩三;七七數之,剩二,問物幾何。”求最小解。
8.編程求出所有不超過1000的數中,含有數字3的自然數,并統計總數。
9.阿姆斯特朗數:如果一個正整數等于其各個數字的立方和,則該數稱為阿姆斯特朗數(也稱自戀數),如407=43+03+73,試編程求出1000以內的所有阿姆斯特朗數。
第三節 While 循環
While循環是當型循環。
[例3.8] 前面第一章[例1.2]的雞兔同籠,頭30,腳90, 求雞兔各幾只?在此用下面方法編程求解。
解: 設雞為J只,兔為T只。已知頭為H, 腳為F。
  ①讓雞的只數逐次加1進行遞推計算,初始時J=0;
②計算兔的只數T=H-J;
③當總腳數(4*T+2*J) < > F就做 (J=J+1,T=H-J);
④當4*T+2*J=F時,說明所推算的J和T是正確的,應結束循環,并輸出T, J。
Pascal程序:
Program Exam38;
Const H=30;
F=90;
Var J,T : integer;
Begin
J:=0; T:=H-J; {初始時讓J從0開始計算 }
While 4*T+2*J<>F do {當條件為真就做do后面的循環體 }
begin
inc(J);    { 遞推改變J值 }
T:=H-J   {計算兔的只數 }
end;
Writeln('T=',T,' ':6, 'J=', J ) ;
Readln
End.
程序中采用While當型循環,While循環語句的格式為:
While 條件式 do 語句;
其中do后面的“語句”是被重復執行的,稱為循環體;若循環體是多個語句, 必須用begin--end包起來成為復合語句。
While循環首先判斷條件式,當條件式的值為真就執行do 后面的語句(循環體)。
While的循環體內也必須包含能改變控制變量取值語句, 影響條件式的值, 最終使條件式為false (假), 才能結束循環。
[例3.9] 輸入任一的自然數A, B, 求A , B的最小公倍數。
解:這里采用適合計算機查找的方法: 設D是它們的最小公倍數。先找出A, B當中的較大者并存放在A中, 將較小者存放在B中, 讓D=A, 當D能夠整除B時, 則D是所求的最小公倍數;當D不能整除B,就逐次地讓D增加A。例如:A=18, B=12, 步驟如下:
① 讓D=A (D=18)
② 當(D mod B)<>0 為真時 ( D不能整除B ) 就做 D=D+A, 重復②;
③ 當(D mod B)<>0 為假時結束循環,并輸出D。
Pascal程序:
program Exam39;
var a,b,d,t : word;
begin
write('input a,b: '); readln(a , b);
if abegin
t:=a; a:=b; b:=t
end;
d:=a;
while d mod b < >0 do {當條件為真時就做do后面的語句 }
inc(d,a);
writeln('[', a, ' , ' , b, ']=', d) ;
readln
End.
Pascal語言的三種基本循環方式, for循環對循環范圍有明確規定, 且循環變量只能是遞增加1或遞減1自動計數控制; 而repeat--until循環和while--do循環比較靈活, 只要對條件表達式的值能控制滿足一定要求就能組成循環, 但在循環體中必須有改變循環變量值的語句, 使條件判斷(邏輯值)最終為True或flase, 讓循環能夠終止。
[例3.10]求自然數A, B的最大公約數。
解:采用如下方法步驟:
(1)求A除以B的余數;
(2)當余數<>0就做n=a; a=b; b=n mod b, 重復(1)和(2);
(3)當余數=0就結束循環,并輸出b值。
比如a=18, b=12時,處理步驟為:
(1) = ,得余數為6;
(2) 此余數不為零 ,讓a = 12, b = 6;
(3) 重復 = , 得余數為0;
(4) 結束循環,輸出6(余數為零時的b值即是所求的最大公約數)。
此方法稱為輾轉相除法求最大公約數。
Pascal程序:
program Exam310;
var a,b, n : word;
begin
write('input a,b: '); readln (a,b);
write('(', a, ' , ' , b, ')=' ) ;
while a mod b < > 0 do
begin
n:=a; a:=b; b:=n mod b;
end;
writeln(b);
readln
End.
[例3.11]將一根長為369cm的鋼管截成長為69cm和39cm兩種規格的短料。在這兩種規格的短料至少各截一根的前提下, 如何截才能余料最少。
解:設兩種規格的短料分別為:
規格為69cm的x根,可在1至(369-39)/69范圍循環取值;
規格為39cm的y根,用y = (369-69*X)/39)計算;
余料R=369-69*X-39*Y。
①設最小余料的初始值min=369;
②在X循環范圍內,每一個X值都計算出對應的Y和R;
③如果R<min, 就將R存入min, x存入n, y存入m,記錄余料最小時的x和y ;
④重復步驟②,當x值超出 ((369—39)/ 69) 時結束循環。
Pascal程序:
program exam311;
var x,y,r,min,n,m,a: integer;
begin
min:=369;
a:=(369-39) div 69; x:=1;
while x<=a do
begin
y:=(369-69*x) div 39;
r:=369-69*x-39*y;
if rbegin
min:=r; n:=x; m:=y
end;
inc(x);
end;
writeln('min=', min, ' x=', n, ' y=', m) ;
readln
end.
在有些情況中, 三種循環方法可以互相換用。
[例3.12]甲、乙、丙三人都是業余射擊愛好者, 在一次練習中他們槍槍中靶: 甲射了八發子彈,取得225環成績,乙射了七發,也取得225環;丙只射了六發,同樣取得225環。下面是成績表,請編程完成下表中空項的填數。
射子彈數 中50環有幾發 中35環有幾發 中25環有幾發 成績(環)
甲 8 225
乙 7 225
丙 6 225
解:①設N為發射子彈數, 只有8, 7, 6三個數字, 正好又可用來代表甲、乙、丙;
②設A為中50環的子彈數, 最小為0, 最大為(225 div 50=4);
B為中35環的子彈數, 最小為0, 最大為(225 div 35=6);
C為中25環的子彈數, C=N-A-B, 但必須C>0才可能正確;
③先讓N=8, A取值(0~4), B取值 (0~6)用循環逐個選定, 在C>0的情況下若能滿足條件A*50+B*35+C*25=225就能確定一組填數。然后選N的下一數值,重復同樣的過程。
Pascal程序:
program exam312;
var a,b,c,n,s : integer;
begin
writeln('n':3, 'a':3, 'b':3, 'c':3, 's':5) ;
n:=8;
while n<=6 do
begin
a:=0;
while a < = 4 do
begin
b:=0;
while b < = 6 do
begin
c:=n-a-b;
if c>0 then
begin
s:=50*a+35*b+25*c;
if s=225 then writeln(n:3,a:3,b:3,c:3,s:5);
end;
inc(b);
end;
inc(a);
end;
dec(n);
end;
readln
end.
程序運行結果獲得兩組填數答案。如果改用for循環,程序將更加簡明:
Program Exam312_1;
Var a,b,c,n,s : Integer;
Begin
Writeln('N':3, 'A':3, 'B':3, 'C':3, 'S':5) ;
for n:=8 downto 6 do {N取值8,7,6,并分別代表甲、乙、丙 }
for a:=0 to 4 do {中50環的可能范圍 }
for b:=0 to 6 do {中30環的可能范圍 }
begin
c:=n-a-b; { 計算中25環的子彈數 }
if c>0 then begin {如果不是負數 }
s:=50*a+35*6+25*c; {計算總成績 }
if s=225 then writeln(n:3,a:3,b:3,c:3,s:5);
end
end;
readln
End.
習題3.3
1.求S= 1-1/2 +1/3-1/4+1/5-1/6+ ……(求前N項的和)
2. Faibonacci數列前幾項為: 0,1,1,2,3,5,8,…,其規律是從第三項起, 每項均等于前兩項之和。求前30項, 并以每行5個數的格式輸出。
3.小球從100高處自由落下,著地后又彈回高度的一半再落下。求第20次著地時, 小球共通過多少路程
4.某登山隊員第一天登上山峰高度的一半又24米; 第二天登上余下高度的一半又24米;每天均如此。到第七天,距山頂還剩91米。求此山峰的高度
5.給出某整數N,將N寫成因數相乘的形式。如: N=12,輸出: 12=1*2*2*3.
6.出售金魚者決定將缸里的金魚全部賣出。第一次賣出全部金魚的一半加二分之一條;第二次賣出剩余的三分之一加三分之一條金魚;第三次賣出余下金魚的四分之一加四分之一條;第四次賣出余下的五分之一加五分之一條金魚。還剩下11條金魚。當然,出售金魚時都是整數條,不能有任何破損。求缸里原有的金魚數
7.外出旅游的幾位朋友決定次日早晨共分一筐蘋果。天剛亮,第一個人醒來,他先拿了一個,再把筐里的八分之一拿走;第二個人醒來,先拿兩個,再把筐里的八分之一拿走;第三個人醒來,先拿三個,再拿走筐里的八分之一;…每個人依次照此方法拿出各人的蘋果,最后筐里的蘋果全部拿完,他們每人所拿到的蘋果數正巧一樣多。求原先筐里的蘋果數和人數。
8.圖中由6個圓圈構成三角形,每條邊上有三個圈, 將自然數1--6 不重復地填入各圓圈位置上,使每條邊圓圈上的數字之和相等,請編程輸出所有的填法。
9.請編程顯示出下面數字金字塔圖形:
第四章 函數與過程
程序中往往需要把主要任務分成若干個子任務,每個子任務只負責一個專門的基本工作。每個子任務就是一個獨立的子程序。Turbo Pascal 可以把函數和過程作為子程序調用。
第一節 函數
Pascal允許用戶在程序中自己說明定義所需要的函數并在程序中調用這些函數。
[例4.1]編程找出由鍵盤任意輸入五個整數中的最大整數。
解:設輸入的五個整數為n1、n2、n3、n4、n5,為了便于處理,引入一個中間變量t1,按如下步驟處理:
①令t1=n1;
②將t1與n2比較,將兩者中較大的數放入t1;
③將t1與n3比較,將兩者中較大的數放入t1;
④將t1與n4比較,將兩者中較大的數放入t1;
⑤將t1與n5比較,將兩者中較大的數放入t1;
⑥經過以上5步處理后,t1即為5個數中最大者。
從上面規劃的步驟看來,從步驟②到步驟⑤需處理的目標是相同的,因此我們可以設計一段子程序Max(x1,x2),以找出x1和x2中最大的值并返回。
Pascal程序:
Program Exam41_a;
Var n1,n2,n3,n4,n5,t1 : integer;
Function max(x1,x2 : integer) : integer;
Begin
If x1>x2 then Max := x1
Else Max := x2;
End;
Begin
Write(‘Input 5 numbers : ‘);
Readln(n1,n2,n3,n4,n5);
T1 := n1;
T1 := Max(t1,n2);
T1 := Max(t1,n3);
T1 := Max(t1,n4);
T1 := Max(t1,n5);
Writeln(‘Max number : ‘,t1);
End.
從上例看出,引入函數實際上是將一個復雜的問題劃分成若干個易于處理的子問題,將編程化簡的一種有效辦法,而化簡的方法是多種多樣的,如前面已經做過求三個數中的最大數,所以可定義一個專門求三個數中最大數的函數(Max)。第一次用這個函數求出n1,n2,n3三個數中的最大數t1;第二次調用這個函數求出t1與n4,n5三個數中的最大數,也就是前三個數的最大數(已在t1中)和后面二個數再求一次,就得到五個數的最大數。因此,需要兩次使用“求三個數中的最大數”,步驟如下:
①調用函數Max ( n1, n2, n3), 求出n1,n2,n3中的最大者 t1;
②調用函數Max ( t1, n4, n5 ),求出t1, n4, n5中的最大者t2;
③輸出最大數 t2。
Program Exam41_b;
Var n1,n2,n3,n4,n5,t1: integer;
function Max(x1,x2,x3: integer): integer; {自定義函數Max}
Var XX: integer; {函數內部變量說明}
begin {函數體}
if X1>X2 then XX:=X1
else XX:=X2;
if X3>XX then XX:=X3;
Max:=XX
end;
Begin {主程序}
Write('Input 5 numb:');
Readln(n1,n2,n3,n4,n5); {輸入五個數}
t1:=Max(n1,n2,n3); {用函數求n1, n2, n3的最大數}
t1:=Max(n4,n5,t1); {用函數求n4, n5, t1 的最大數}
Writeln('Max Number :', t1);
Readln
End.
主程序中兩次調用自定義函數。自定義函數的一般格式為:
function 函數名(形式參數表): 類型; {函數首部}
局部變量說明部分;
begin
語句系列; {函數體 }
end;
函數中的形式參數接受調用函數時所傳入的值,用來參與函數中的運算。
[例4.2]求任意輸入的五個自然數的最大公約數。
解:⑴自定義一個專門求兩自然數的最大公約數的函數GCD;
⑵調用自定義函數,第一次求前兩個數的最大公約數;從第二次開始,用每次求得的最大公約數與下一個數再求兩個數最大公約數,直到最后。本題共四次“求兩個數的最大公約數”, 設輸入的五個自然數分別是a1,a2,a3,a4,a5,采用如下步驟:
①求a1, a2兩個數的最大公約數 → 存入a1;
②求a1, a3兩個數的最大公約數 → 存入a1;
③求a1, a4兩個數的最大公約數 → 存入a1;
④求a1, a5兩個數的最大公約數 → 存入a1;
⑤ 輸出 a1,此時的a1已是五個數的最大公約數。
Pascal程序:
Program Exam42;
Var a1,a2,a3,a4,a5: integder;
function GCD(x,y: integer): integer; {自定義函數 }
Var n:integer;
begin
While x mod y <>0 do
begin
n:=x; x:=y; y:=n mod y
end;
GCD:=y
end;
Begin {主程序 }
Write('input 5 Numper:');
readln(a1,a2,a3,a4,a5); {輸入五個數}
Write('(',a1,',',a2,',',a3,',',a4,',',a5,')=');
a1:=GCD(a1,a2); {調用函數GCD }
a1:=GCD(a1,a3);
a1:=GCD(a1,a4);
a1:=GCD(a1,a5);
Writeln(a1);
readln
End.
函數的結果是一個具體的值, 在函數體中必須將所得到的運算結果賦給函數名;主程序通過調用函數得到函數的運算結果。調用函數的一般格式為:
函數名 (實在參數表)
調用函數時, 函數名后面圓括號內的參數必須有確定的值, 稱為實在參數。調用時即把這些實際值傳送給函數形參表中的相應形參變量。函數不是單獨的語句, 只能作為運算賦值或出現在表達式中。
習題4.1
1. 數學上把從 1 開始的連續自然數相乘叫做階乘。例如 把1*2*3*4*5 稱作5的階乘, 記為5!。 編寫一個求n!的函數, 調用此函數求: D=
2.求從鍵盤輸入的五個自然數的最小公倍數。
3.哥德巴赫猜想的命題之一是:大于6 的偶數等于兩個素數之和。編程將6~100所有偶數表示成兩個素數之和。
4.如果一個自然數是素數,且它的數字位置經過對換后仍為素數,則稱為絕對素數,例如13。試求出所有二位絕對素數。
第二節 自定義過程
自定義函數通常被設計成求一個函數值,一個函數只能得到一個運算結果。若要設計成能得到若干個運算結果,或完成一系列處理,就需要自定義“過程”來實現。
[例4.3] 把前面[例2.2 ](輸入三個不同的整數,按由小到大排序)改為下面用自定義過程編寫的Pascal程序:
Program exam43;
Var a,b,c: integer;
Procedure Swap (var x,y: integer); {自定義交換兩個變量值的過程 }
Var t : integer;
Begin {過程體}
t:=x; x:=y; y:=t {交換兩個變量的值
end;
Begin {主程序}
Write('input a,b,c=');
Readln(a,b,c);
if a>b then swap (a,b); {調用自定義過程}
if a>c then swap (a,c);
if b>c fhen swap (b,c);
Writeln (a:6, b:6, c:6);
Readln
End.
程序中Procedure Swap是定義過程名,從作用來看,過程與函數是相似的,都能將復雜的問題劃分成一些目標明確的小問題來求解,只不過函數有值返回而過程則沒有。自定義過程的一般格式如下:
Procedure 過程名 (形式參數表); {過程首部}
局部變量說明部分;
begin
語句部分; {過程體部分}
end;
[例4.4]如果一個自然數除了1和本身,還有別的數能夠整除它, 這樣的自然數就是合數。例如15,除了1和15,還有3和5能夠整除,所以15是合數。14,15,16是三個連續的合數,試求連續十個最小的合數。
解:從14,15,16三個連續合數中可看出,它們正好是兩個相鄰素數13和17 之間的連續自然數,所以求連續合數問題可以轉化為求有一定跨度的相鄰兩個素數的問題。因此,求連續十個最小的合數可用如下方法:
①從最小的素數開始,先確定第一個素數A;
②再確定與A相鄰的后面那個素數B;(作為第二個素數);
③檢查A,B的跨度是度否在10 以上,如果跨度小于10,就把B 作為新的第一個素數A,重復作步驟②;
④如果A、B跨度大于或等于10,就打印A、B之間的連續10個自然數,即輸出 A+1, A+2, A+3 …, A+10。
Pascal程序:
Program exam44;
var a,b,s,n: integer;
yes: boolean;
procedure sub(x: integer;var yy: boolean); {過程:求x是否為素數 }
var k,m: integer; { 用yy邏輯值轉出 }
begin
k:=trunc(sqrt(x));
for m:=3 to k do
if odd(m) then
if x mod m=0 then yy:=false;
end;
begin {主程序 }
b:=3;
repeat
a:=b; {a 為第一個素數 }
repeat
yes:=true;
inc(b,2); {b是a后面待求的素數}
sub(b,yes); {調用SUB過程來確認b是否為素數 }
if yes then s:=b-a; {如果b是素數,則求出跨度s }
until yes;
until s > = 10;
for n:=a+1 to a+10 do
write(n:6);
writeln;
readln
end.
程序中的過程SUB,用來確定b是否為素數。過程名后面圓括號內的變量是形式參數,簡稱為形參。過程SUB(x: integer; Var yy: boolean) 中的x是值形參,而前面冠有Var的yy是變量形參。值形參只能從外界向過程傳入信息,但不能傳出信息;變量形參既能傳入又能傳出信息。本程序過程SUB中的x是由調用過程的實在參數b傳入值,進行處理后,不需傳出;而yy是把過程處理結果用邏輯值傳出,供調用程序使用。
試把[例4.3]程序中的過程 SWAP(Val x,y: integer),將x,y前面的Var去掉,就變成了純粹的值形參,就不能將過程所處理的結果傳出去,也就無法得到處理后的結果,通過運行程序比較,可以非常明顯地看到值形參和變量形參的區別。
調用過程的格式為: 過程名(實在參數表) ;
調用過程名后面圓括號內的實在參數與定義過程的形參表必須相對應,調用過程相當于一個獨立語句,可單獨使用。
[例4.5]將合數483的各位數字相加(4+8+3)=15,如果將483分解成質因數相乘: 483=3*7*23,把這些質因數各位數字相加(3+7+2+3),其和也為15。即某合數的各位數字之和等于它所有質因數的各數字之和。求500以內具有上述特點的所有合數。
解:①設n為所要求的合數,讓n在1~500間循環做以下步驟;
②用t1,t2分別累計合數n及n的質因數的各位數字之和,初值均為0;
③調用過程SUB3進行非素數判定,以布爾變量yes的真假值判定是否,yes的初值為true,如果為 (not true)非素數,就做步驟④,⑤,⑥;否則取新的n值,重復步驟③;
④調用SUB1,求n的各數字之和,傳送給t1;
⑤調用SUB2,求n的各質因數,對于每個質因素都通過SUB1求它各位數字之和,將所有各質因數字傳送給t2。
⑥如果t1=t2(各位數字之和等于它所有質因數的各數字之和),則輸出此n。
PASCAL程序:
program exam45;
var n,t1,t2,tatol: integer;
yes: boolean;
procedure sub1(x:integer; var t:integer); {過程:分離x的各位數字 }
begin {并求各位數字之和 }
repeat
t:=t+x mod 10;
x:=x div 10;
until x=0
end;
procedure sub2(x: integer; var t: integer); {過程:分解質因數 }
var xx,tt:integer;
begin
xx:=2;
while x>1 do
if x mod xx=0 then
begin
tt:=0;
sub1(xx,tt);
t:=t+tt;
x:=x div xx
end
else inc(xx)
end;
procedure sub3(x: integer;var yy: boolean); {過程:判斷x是否為素數 }
var k,m: integer;
begin
k:=trunc(sqrt(x));
for m:=2 to k do
if x mod m=0 then yy:=false;
end;
begin {主程序}
for n:=1 to 500 do
begin
t1:=0;t2:=0;
yes:=true;
sub3(n,yes); {調用過程求素數 }
if not yes then {如果非素數就… }
begin
sub1(n,t1); {調用過程求n的各位數字之和 }
sub2(n,t2); {調用過程求n的各質因數的數字之和 }
if t1=t2 then write(n:6); {打印合格的合數 }
end
end;
readln
end.
程序定義了三個過程SUB1,SUB2,SUB3,其中SUB2過程中又調用了SUB1。在過程中定義的變量或參數,只在本過程內部使用有效。這些變量稱為局部變量。如SUB2中的xx只在SUB2中使用,屬于局部變量。
習題:4.2
1.輸入自然數n,求前n個合數(非素數),其素因子僅有2,3,或5。
2.自然數a的因子是指能整除a的所有自然數,但不含a本身。例如12的因子為:1,2,3,4,6。若自然數a的因子之和為b,而且b的因子之和又等于a,則稱a,b為一對“親和數” 。求最小的一對親和數。
3.求前n個自然數的平方和,要求不用乘法。例如:3的平方不用3*3,可用3+3+3。
4.試用容積分別為17升、13升的兩個空油桶為工具,從大油罐中倒出15升油來,編程顯示出具體的倒油過程。
5.如果一個數從左邊讀和從右邊讀都是同一個數,就稱為回文數。例如6886就是一個回文數,求出所有的既是回文數又是素數的三位數。
6. 任何大于2的自然數都可以寫成不超過四個平方數之和。如:
8=22+22; 14=12+22+32
由鍵盤輸入自然數N(2 < N < 2000) ,輸出其不超過四個平方數之和的表示式。
第五章 Pascal的自定義數據類型
Pascal系統允許用戶自定義的數據類型有:數組類型、子界類型、枚舉類型、集合類型、記錄類型、文件類型、指針類型。
第一節 數組與子界類型
[例5.1]總務室在商店購買了八種文具用品,其數量及單價如下表:
序號 1 2 3 4 5 6 7 8
品名 圓珠筆 鉛筆 筆記本 訂書機 計算器 三角板 圓規 文件夾
件數 24 110 60 16 26 32 32 42
單價 1.18 0.45 1.8 8.8 78.50 3.28 4.20 2.16
編程計算各物品計價及總計價。
解:表中有兩組數據,設表示物品件數的一組為a,表示物品單價的一組為b。
a,b兩組數據以序號為關聯,具有相應的順序關系。按如下方法處理:
①定義s,a,b三個數組,按相應順序關系,給a,b賦值(件數和對應單價) ;
②每讀入一對數據(件數和對應單價),以同一序號的件數和對應單價計算出同一物品的計價:
s[ i ]=a[ i ]* b[ i ] ; { 用s[ i] 記入第i種物品的計價}
t = t + s[ i ] { 用簡單變量累加總計價 }
③循環做步驟②,做完后輸出s數組所記入的各物品計價及總計價t。
Pascal程序:
Program Exam51;
Var a: array[1..8] of integer; {a數組為整數型}
s,b: array[1..8] of real; {s和b數組為實數型}
t: real;
i: integer;
Begin
t:=0;
for i:=1 to 8 do {輸入并計算八種物品 }
begin
write('a[', i, ']=') ;
Readln(a[ i ]) ; {輸入單價}
write('b[', i, ']=') ;
readln(b[ i ]); {輸入件數}
s[ i ]:=a[ i ]* b[ i ]; t:=t+s[ i ]
end;
write('i':2, ' ':2);
for i:=1 to 8 do {打印物品序號}
write(i:8); {輸出項寬度為8}
writeln;
write('a':2, ' ':2); {輸出項寬度為2}
for i:=1 to 8 do {打印物品件數a數組}
write(a[ i ]:8); {輸出項寬度為8}
writeln; {換行}
write('b':2, ' ':2);
for i:=1 to 8 do {打印物品件數b數組}
write(b[ i ]:8:2); {輸出項寬度為8,小數2位}
writeln; {換行}
write('s':2, ' ':2);
for i:=1 to 8 do {打印物品計價s數組}
write(s[ i ]:8:2); {輸出項寬度為8,小數2位}
writeln; {換行}
writeln('Totol=', t:8:2); {打印總價t}
Readln
end.
輸出語句為 write(實數:n:m) 的形式時,則輸出該實數的總寬度為n,其中小數m位,此時的實數不以科學計數形式顯示。
程序中用來表示如物品件數和物品單價等屬性相同的有序數據,Pascal語言把它歸為數組。數組成員(分量)稱為數組元素。數組必須在說明部分進行定義:確定數組名,數組分量(元素)的個數及類型。一般格式有:
Var 數組名:array[下標類型] of 數組元素類型 ;
本程序中a數組和b數組中8個元素的數據都是已知數據,可當作常量,用常量說明語句給數組元素賦初值,所以上面的程序Exam51可改為如下形式:
Program Exam51_1;
const a: array[1..8] of integer
=(24,110,60,16,26,32,32,42); {給a數組賦初值}
b:array[1..8] of real
=(1.18,0.45,1.80,8.8,78.50,3.28,4.20,2.16); {給b數組賦初值}
Var s: array[1..8] of real;
t: real;
i: integer;
Begin
t:=0;
for i:=1 to 8 do
begin
s[ i ]:=a[ i ]* b[ i ]; t:=t+s[ i ]
end;
write('i':2, ' ':2);
for i:=1 to 8 do write(i:8);
writeln;
write('a':2, ' ':2);
for i:=1 to 8 do write(a[ i ]:8:);
writeln;
write('b':2, ' ':2);
for i:=1 to 8 do write(b[ i ]:8:2);
writeln;
write('s':2, ' ':2);
for i:=1 to 8 do write(s[ i ]:8:2);
writeln;
writeln('Totol=', t:8:2);
Readln
end.
數組常量說明格式為:
Const 數組名:array[下標類型]of 數組元素類型=(常量表);
程序中對數組的輸入、輸出處理,常用循環語句控制下標,進行有序地直接操作每個數組元素。
[例5.2]編程輸入十個正整數,然后自動按從大到小的順序輸出。
解:①用循環把十個數輸入到A數組中;
②從A[1]到A[10],相鄰的兩個數兩兩相比較,即:
A[1]與A[2]比,A[2]與A[3]比,……A[9]與A[10]比。
只需知道兩個數中的前面那元素的標號,就能進行與后一個序號元素(相鄰數)比較,可寫成通用形式A[ i ]與A[ i +1]比較,那么,比較的次數又可用1~( n - i )循環進行控制 (即循環次數與兩兩相比較時前面那個元素序號有關) ;
③在每次的比較中,若較大的數在后面,就把前后兩個對換,把較大的數調到前面,否則不需調換位置。
下面例舉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 3 7 3和7比較,交換位置,排成下行的順序;
6 5 4 7 3 經過(1~(5-1))次比較后,將3調到了末尾。
經過第一輪的1~ (N-1)次比較,就能把十個數中的最小數調到最末尾位置,第二輪比較1~ (N-2)次進行同樣處理,又把這一輪所比較的“最小數”調到所比較范圍的“最末尾”位置;……;每進行一輪兩兩比較后,其下一輪的比較范圍就減少一個。最后一輪僅有一次比較。在比較過程中,每次都有一個“最小數”往下“掉”,用這種方法排列順序,常被稱之為“冒泡法”排序。
Pascal程序:
Program Exam52;
const N=10;
Var a: array[1..N] of integer; {定義數組}
i,j: integer;
procedure Swap(Var x,y: integer); {交換兩數位置的過程}
Var t:integer;
begin
t:=x; x:=y; y:=t
end;
Begin
for i:=1 to N do {輸入十個數}
begin
write(i, ':');
Readln(a[ i ])
end;
for j:=1 to N-1 do {冒泡法排序}
for i:=1 to N-j do {兩兩相比較}
if a[ i ] < a[i+1] then swap(a[ i ], a[i+1]); {比較與交換}
for i:=1 to N do {輸出排序后的十個數}
write(a[ i ]:6);
Readln
end.
程序中定義a數組的下標類型為 1.. N ,這種類型規定了值域的上界和下界,是從一個有序類型范圍取出一個區段,所以稱為子界類型,子界類型也是有序類型。
例[5.3] 用篩法求出100以內的全部素數,并按每行五個數顯示。
解:⑴ 把2到100的自然數放入a[2]到a[100]中(所放入的數與下標號相同);
⑵ 在數組元素中,以下標為序,按順序找到未曾找過的最小素數minp,和它的位置p(即下標號);
⑶ 從p+1開始,把凡是能被minp整除的各元素值從a數組中劃去(篩掉),也就是給該元素值置 0;
⑷ 讓p=p+1,重復執行第②、③步驟,直到minp>Trunc(sqrt(N)) 為止;
⑸ 打印輸出a數組中留下來、未被篩掉的各元素值,并按每行五個數顯示。
用篩法求素數的過程示意如下(圖中用下劃線作刪去標志) :
① 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {置數}
② 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {篩去被2整除的數 }
③ 2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {篩去被3整除的數 }
……
2 3 4 5 6 7 8 9 10 11 12 13 14 15…98 99 100 {篩去被整除的數 }
Pascal程序:
Program Exam53;
const N=100;
type xx=1 .. N;      {自定義子界類型xx(類型名)}
Var a: array[xx] of boolean;
i,j: integer;
Begin
Fillchar(a,sizeof(a),true);
a[1] := False;
for i:=2 to Trunc(sqrt(N)) do
if a[I] then
for j := 2 to N div I do
a[I*j]:= False;
t:=0;
for i:=2 to N do
if a[i] then
Begin
write(a[ i ]:5); inc(t);
if t mod 5=0 then writeln
end;
readln
End.
程序中自定義的子界類型,在用法上與標準類型(如integer)相同,只是值域上界、下界在說明中作了規定,而標準類型的值域由系統內部規定,其上界、下界定義是隱含的,可直接使用。例如:
Type integer= -32768 ... 32768; Pascal系統已作了標準類型處理,不必再作定義。
[例5.4]在一次宴會上,有來自八個不同國家的賓客被安排在同一張圓桌就坐。A是中國人,會講英語;B是意大利人,他能講西班牙語;C是英國人,會講法語;D是日本人,能講漢語;E是法國人,會講德語;F是俄國人,懂意大利語;G是西班牙人,能講日語;最后一個是德國人,懂俄語。編程序安排他們的座位,使他們在各自的座位上能方便地跟兩旁的客人交談。
解:①根據題目提供條件與數據,建立如下關系代碼表:
國家名 中國 意大利 英國 日本 法國 俄國 西班牙 德國
賓客代碼 A B C D E F G H
語言代號 1 2 3 4 5 6 7 8
懂外語代號 3 7 5 1 8 2 4 6
總代碼 A13 B27 C35 D41 E58 F62 G74 H86
表中總代碼實際上是前三項代碼的歸納:第一個字母表示哪國人;第二個數字表示本國語代號;第三個數字表示懂哪國外語。如A13,A表示中國人,1表示漢語(本國語),3表示會說英語。所以每個賓客的情況均用總代碼(三個數據組成的字符串)表示;
②定義由8個元素組成的數組(NAME),元素類型為字符串類型(String);
③元素的下標號影響各人座位關系,必須滿足后一個元素的下標號應與前一個元素字符串中的第三個數據相同。例如:若第一個位置總代碼為A13,則第二個位置應根據A13中最后的3,安排C35。即A與C可以交談。以此類推。
用字符串處理函數COPY,截取字符串的第一個字母作為賓客代碼打印,再取第三個字符,用VAL將其轉換成數字,將這個數字作為下標號,把這個下標號的元素安排在旁邊(相鄰);
④重復步驟③的方法,安排其后的元素,直到八個數據全部處理完為止。
Pascal程序:
Program Exam54;
const name : array[1..8]of string {定義字串類型數組并賦常量}
=('A13','B27','C35','D41','E58','F62','G74','H86');
Var i, code: integer; {整數類型}
x: 1..8; {子界類型}
s : string; {字符串類型}
Begin 
s:=copy(name[1],1,1); {截取第一個元素字串的第一個字符}
write(s:4); {確定第一個位置}
s:=copy(name[1],3,1); {截取元素字串的第三個字符作為相鄰}
Val(s,x,code); {將字串s的值轉換成數字存入 x}
for i:=1 to 7 do {確定后面7個位置}
Begin
s:=copy(name[x],1,1); {找到相鄰者的代碼}
write(s:4); {打印相鄰者代碼}
s:=copy(name[x],3,1); {確定下一個相鄰元素}
Val(s,x,code);
end;
readln
End.
Pascal常用的字符串處理標準函數有7個:
設變量s,str,str1,str2均為字符串類型(string){多個字符};ch為字符類型(char){單個字符};
(1)copy(str,n,m)從字符串str的左邊第n個開始截取m個字符;
如:copy(' Pascal ' ,3,2)的結果為'sc ' ;
(2)concat(str1,str2)將兩個字串連接成為一個新的字串;
如:s:=str1+str2;同等于兩串字符相加
(3)Length(str)求字串str的長度(字符個數);
(4)chr(x) 求x(x為1…255整數)的ASII代碼對應的字符;
如:chr(65)結果為 'A'。
(5)ord(ch)求字符ch對應的ASCII代碼值;如 ord ( 'A' )結果為65;
(6)pos(str1,str2)求字串str1在字串中開始的位置;
如: pos('sca','pascal')結果為3;
(7)upcase(ch)將字符ch轉為大寫字母,如 upcase( 'a' )結果為'A' ;
Pascal常用的字符串處理標準過程有4個:
(1)Val(str,x,code)將數字型字串轉為數字并存入變量x中;
如:Val(‘768’,x,code),x值為768,code為檢測錯誤代碼,若code=0表示沒有錯誤;
(2)str(n,s)將數字n轉化為字串存入s中,如str(768,s)s的結果為 ' 768' ;
(3)insert(str1,str2,n)把字串str1插入在字串str2的第n個字符之前,結果在str2中;{此過程中的str2為變量形參,具有傳入傳出的功能};
(4)delete(str,n,m)從字串str的第n個開始,刪除m個字符,把剩余的字符存在str中,{此過程中的str為變量形參,具有傳入傳出的功能};
[例5.5]一個兩位以上的自然數,如果左右數字對稱,就稱為回文數,編程找出所有不超過6位數字的回文數,同時又是完全平方數的數。
如121是回文數,又是11的平方,所以是完全平方數。
解:①不超過6位數的完全平方數用循環在10~999范圍產生(for i:=10 to 999) ;
②將完全平方數 (i*i)轉成字串類型存入s中;
③逐個取s的左右字符,檢查是否相同(對稱),檢查對數不超過總長度的一半;
④如果是回文數,就調用打印過程(Print)。
Program Exam55;
Var n, k, j ,t : integer;
s : string; {字符串類型 }
i: longint; {長整數類型 }
Procedure Print; {打印過程(無形參)}
begin
write(s : 10); inc(t); {打印s, 用t 計數 }
if t mod 6=0 then writeln {打印6個換行 }
end;
Begin
t:=0;
for i:=10 to 999 do
begin
str(i*i,s); {將完全平方數轉換成字串 }
k:=length(s); {計算字串長度 }
n:=k div 2; {計算字串長度的一半 }
j:=1;
while j < = n do {取左右字符檢查是否對稱 }
if copy(s,j,1) < > copy(s,k+1-j,1) then j:=1000
else inc( j ) ; {若不對稱讓j=1000,退出循環 }
if j <1000 then Print { j <1000即是回文數,調打印 }
end;
writeln; writeln('Total=':8, t); {打印總個數 }
readln
End.
習題5.1
1.裴波那契數列:數列1、1、2、3、5、8、13、21…稱為裴波那契數列,它的特點是:數列的第一項是1,第二項也是1,從第三項起,每項等于前兩項之和。編程輸入一個正整數N,求出數列的第N項是多少?(N不超過30)。
2.下面的豎式是乘法運算,式中P表示為一位的素數,編程輸出此乘法豎式的所有可能方案。
3.節目主持人準備從N名學生中挑選一名幸運觀眾,因為大家都想爭當幸運觀眾,老師只好采取這樣的辦法:全體同學排成一列,由前面往后面依順序報數1,2,1,2,…,報單數的同學退出隊伍,余下的同學向前靠攏后再重新由前往后1,2,1,2,…報數,報單數者退出隊伍,如此下去最后剩下一人為幸運觀眾。編程找出幸運觀眾在原隊列中站在什么位置上?(N由鍵盤輸入,N < 255)。
4. 1267*1267=1605289,表明等式右邊是一個七位的完全平方數,而這七個數字互不相同。編程求出所有這樣的七位數。
5. 校女子100米短跑決賽成績如下表,請編程打印前八名運動員的名次、運動員號和成績。(從第一名至第八名按名次排列)
運動員號 017 168 088 105 058 123 142 055 113 136 020 032 089 010
成績(秒) 12.3 12.6 13.0 11.8 12.1 13.1 12.0 11.9 11.6 12.4 12.9 13.2 12.2 11.4
6. 求數字的乘積根。正整數的數字乘積這樣規定:這個正整數中非零數字的乘積。例如整數999的數字乘積為9*9*9,得到729;729的數字乘積為7*2*9,得到126;126的數字乘積為1*2*6,得到12;12從數字乘積為1*2,得到2。如此反復取數字的乘積,直至得到一位數字為止。999的數字乘積根是2。編程輸入一個長度不超過100位數字的正整數,打印出計算數字乘積根的每一步結果。輸出格式如下:
(N=3486784401)
3486784401
516096
1620
12
2
7. 有一組13個齒輪互相嚙合,各齒輪嚙合的齒數依次分別為6,8,9,10,12,14,15,16,18, 20,21,22,24, 問在轉動過程中同時嚙合的各齒到下次再同時嚙合時,各齒輪分別轉過了多少圈
8. 集合M的元素的定義如下:
(1) 數1屬于M;
(2) 若X屬于M, 則A=2X+1, B=3X+1, C=5X+1, 也屬于M;
(3) 再沒有別的數屬于M。(M={1,3,4,6,7,9,10,13,15,16...,如果M中的元素是按遞增次序排列的,求出其中的第201,202和203個元素。
9. 一個素數,去掉最高位,剩下的數仍是素數;再去掉剩下的數的最高位,余留下來的數還是素數,這樣的素數叫純粹素數。求所有三位數的純粹素數。
10. 自然數4,9,16,25等叫做完全平方數,因為22 =4, 32 =9, 42 =16,52 =25, 當某一對自然數相加和相減, 有時可各得出一個完全平方數。
例如: 8與17這對自然數: 17+8=25 17—8= 9
試編程,找出所有小于100的自然數對,當加和減該數對時,可各得出一個完全平方數。
第二節 二維數組與枚舉類型
[例5.6]假設四個商店一周內銷售自行車的情況如下面表一所示,
自行車牌號 永久牌 飛達牌 五羊牌
第一商店 35 40 55
第二商店 20 50 64
第三商店 10 32 18
第四商店 38 36 28
表一
幾種牌號自行車的單價如表二所示。求各店本周出售自行車的總營業額。
單價 元
永久牌 395
飛達牌 398
五羊牌 384
表二
解:①把表一看成是由行(每個店占一行)與列(每種牌號占一列)共同構成的數據組,按表格排列的位置順序,用A數組表一各數據表示如下:
A[1,1]=35 A[1,2]=40 A[1,3]=55 {第一行共三個數據}
A[2,1]=20 A[2,2]=50 A[2,3]=64 {第二行共三個數據}
A[3,1]=10 A[3,2]=32 A[3,3]=18 {第三行共三個數據}
A[4,1]=38 A[

展開更多......

收起↑

資源預覽

<pre id="tfb94"><li id="tfb94"></li></pre>

<bdo id="tfb94"><rt id="tfb94"></rt></bdo>
  • <menu id="tfb94"><dl id="tfb94"></dl></menu><i id="tfb94"><acronym id="tfb94"><sub id="tfb94"></sub></acronym></i>

    1. 主站蜘蛛池模板: 琼海市| 万山特区| 宁晋县| 平和县| 晋城| 依兰县| 海城市| 石景山区| 论坛| 景泰县| 台山市| 临汾市| 咸宁市| 格尔木市| 赤壁市| 富源县| 阳原县| 霞浦县| 谷城县| 天全县| 韩城市| 奎屯市| 嘉兴市| 吉林省| 大悟县| 永康市| 镇赉县| 阿克苏市| 深泽县| 康定县| 江西省| 洛隆县| 台前县| 新营市| 昌邑市| 隆回县| 个旧市| 化州市| 团风县| 淄博市| 金湖县|