procedure insertbelementype iinteger var ninteger var vvtype begin
procedure insert(b:elementype; i:integer; var n:integer; var v:vtype); begin if n≥m {上溢} then writeln(‘overflow’) else if (i<1)or(i>n+1) then writeln(‘without’) else begin for j:=n downto i do v[j+1]←v[j]; {v[i]‥v[n]向后 移动一个位置} v[i]←b; n←n+1; {b插入i位置,v数组的长度+1} end;{else} end; {insert}
加法运算a←a+b(a、b为numtype类型) procedure plus(var a:numtype;b:numtype);{a←a+b} var i,x:byte; begin if la≥lb then x←la{确定两数中的最大位数} else x←lb; for i← 1 to x do{逐位相加} begin a[i] ←a[i]+b[i]; a[i+1] ←a[i+1]+a[i] div 10; a[i] ←a[i] mod 10 end;{for} while a[x+1]≠ 0 do x←x+1;{和的最高位进位} la←x-1; end;{ plus }
减法运算a←a-b(a、b为numtype类型,a>b) procedure minus(var a: atype; var la: integer; b: atype);{计算a=a-b,返回差a及其长度la} var i:integer; begin for i← 1 to la do{逐位相减} begin if a[i]<b[i] {借位} then begin dec(a[i+1]); a[i]←a[i]+10; end; {then} a[i]←a[i]-b[i];{计算差的第i位} end;{for} while a[la]=0 do dec(la);{计算差的实际长度} end;{minus}
乘法运算a←a*b(a、b为numtype类型) for j← 1 to la do {a←a*b} for k← 1 to lb do inc(a 1[j+k-1],a[j]*b[k]); a 1←a; for j← 1 to la+lb-1 do begin{按照由底位到高位的顺序处理进位} inc(a[j+1],a[j] div 10);{计算进位} a[j] ← a[j] mod 10;{将第j位规整为 10进制数} end;{for} if a[la+lb]<>0) {修改有效位数} then inc(la,lb) else inc(la,lb-1);
作业:麦森数 【问题描述】形如2 P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个 素数,2 P-1不一定也是素数。到 1998年底,人们已找到了37个麦森数。最大的一个是P=3021377, 它有909526位。麦森数有许多重要应用,它与完全数密切相关。 任务:从文件中输入P(1000<P<3100000),计算 2 P-1的位数和最后500位数字(用十进制高精度数 表示) 【输入格式】文件中只包含一个整数P(1000<P<3100000) 【输出格式】第一行:十进制高精度数 2 P-1的位数。第 2 -11行:十进制高精度数 2 P-1的最后500位 数字。(每行输出 50位,共输出 10行,不足 500位时高位补 0)不必验证2 P-1与P是否为素数。 【输入样例】 1279 【输出样例】 386 00000000000000000000000000000000000000000000000000104079321946643990819252403273640855 38615262247266704805319112350403608059673360298012 23944173232418484242161395428100779138356624832346 49081399066056773207629241295093892203457731833496 61583550472959420547689811211693677147548478866962 50138443826029173234888531116082853841658502825560 46662248318909188018470682222031405210266984354887 32958028878050869736186900714720710555703168729087
栈的基本运算 • 过程push(s,x,t)—往栈s中压入一个值为x的表目 procedure push (var s:stack; x:stype; var t:integer); begin if t=m then writeln(‘overflow’) {上溢} else begin t←t+1;s[t]←x;end;{else} {x入栈} end;{Push} • 函数pop(s,t)—从栈中弹出一个表目 function pop (var s:stack; var t:integer):stype; begin if t=0 then writeln (‘underflow’) {下溢} else begin pop←s[t]; t←t-1; end;{else} {栈顶元素出栈} end;{pop} 函数top(s,t)—读栈顶元素 function top (s:stack; t:integer):stype; begin if t=0 then writeln (‘stack empty’) else top←s[t]; {返回栈顶元素} end;{top}
队列的基本运算 • 过程ADD(q,x,r)—在队列q的尾端插入元素x procedure ADD(var q: equeue; x:qtype; var r:integer); begin if r=m then writeln (‘overflow’) {上溢} else begin{后移队尾指针并插入元素x} r←r+1; q[r]←x; end;{else} end;{ADD} • 过程DEL(q,y,f,r)—取出q队列的队首元素y procedure DEL(var q:equeue; var y:qtype; var f:integer); begin if f=r then writeln (‘under flow’) {下溢} else begin {后移队首指针并取出队首元素} f←f+1; y←q[f]; end;{else} end;{DEL}
循环队列的运算 • 过程ADD 2(q,x,r)—在循环队列q中插入一个新元素x procedure ADD 2 (var q:equeue; x:qtype; var r:integer); begin t←r mod m+1;{计算插入位置} if t=f then writeln(‘full’) {队列满} else begin {新元素x插入队尾} r←t; q[r]←x; end;{else} end;{ADD 2} • 过程DEL 2(q,y,f)—从循环队列q中取出队首元素y procedure DEL 2 (var q:equeue; var y:qtype; var f:inteqer); begin if f=r then writeln (‘empty’) {队列空} else begin f←f mod m+1;y←q[f];{取出队首元素} end;{else} end;{DEL 2}
模式串的前缀函数(Prefix Function) 前缀函数 Type nexttype=array[1. . 255]of integer; Var next:nexttype; {t的前缀函数} 我们通过get_next过程计算模式串t中每个字 符的next值 procedure get_next(t : string; var next: nexttype); if (k=0) or (t[j]=t[k]) { 若不存在可匹配的子 串或比较相等,则next[j+1]←next[j]+1} then begin var j,k : integer; j←j+1; k←k+1; next[j]←k; begin end {then} j← 1; k← 0; next[1]← 0; {初始化} else k←next[k];{否则依次类推找更短的 子串} while j<=length(t) do {循环,求每一个字 符的next值} end; {get_next}
利用next计算模式串t在主串s中的位置 function index(s,t :string):integer;{利用模式串t的next函数值求模式串t 在主串s中位置} var i,j:integer; begin i← 1;j← 1; while (i<= length(s))and(j<= length(t))do if (j=0)or (s[i]=t[j]) then begin i←i+1;j←j+1; end{then} else j←next[j]; if j> length(t) then index←i- length(t) else index← 0; end;{index} 显然,如果模式串t的串长为n,则index函数的时间复杂度为W(n)
单链表的操作 • 动态建立单链表 Procedure creat-Link(var head: pointer); begin head←nil;{建立一个空表} for i:=n downto 1 do begin new(p); p↑.data←ai; {生成一个值为ai的结点} p↑.next←head; head←p; {将新结点插入单链表第 1个结 点之前} end;{for} new(p); p↑. next←head; head←p;{加“哨兵”} end;{creak_link} 插入操作(在单链表的第i个 结点前插入元素x) pocedure insert_Link (x:elemenetype; i: integer; var head:pointer); begin new(s); s↑.data←x;{生成值为x的结点 } p←head;j← 0;{p指向“哨兵”} while(p<>nil)and(j<i-1)do{寻找单链表中 第i-1个结点} begin p←p↑. next; j←j+1; end; {while} if p<>nil then begin {第i-1个结点后插入元素x} s↑. next←p↑. next; p↑. next←s; end{then} else writeln (‘without’);{i>表长} end;{insert_Link}
• 删除单链表的第i个结 • 读取单链表的第i个元 素值 点) Procedure delet_Link(i: integre; var head:pointer); begin p←head;j← 0;{p指向“哨兵”} while (p↑.next<>nil)and(j<i-1)do{寻 找第i-1个结点p} begin p←p↑.next; j←j+1; end; {while} if p↑.next=nil {i>表长} then writeln (‘without’) else begin {删除第i个结点q} q←p↑.next;p↑.next←p↑ .next↑.next; dispose(q); end;{else} end;{delet_Link} function get_Link(i:integer; var head: Pointer):elementype; begin p←head↑.next;j← 1;{p指向表中 第 1个结点} while (p<>nil)and(j<i)do{顺next指针 往后寻找第i个结点p} begin p←p↑.next; j←j+1; end;{while} if p=nil{i>表长} then writeln(‘without’) else get_Link←p↑.data;{取得表 中第i个结点值} end;{get_Link}
输出多项式 输出“哨兵”为h的单链表对应的多项式 procedure outpoly (h:link); begin p←h↑.next; while p<>nil do begin 输出p↑.coef和p↑.exp; p←p↑.next; end;{while} end;{outply}
和运算 procedure polyadd (pa, pb: link; var pc: link); begin p←pa↑.next;q←pb↑.next;{p,q分别指 向A多项式链表和B多项式链表的第一个结 点} s←pa;pc←pa;{s指向A多项式链表的哨兵 } while(p<>nil)and(q<>nil)do{若A表和B表均 未结束,则循环} if p↑.exp<q↑.exp then begin s←p; p←p↑.next;end{then} {p指针后移} else if p↑.exp>q↑exp{q结点插在p结点之 前,q指针后移} then begin u←q↑.next;q↑.next←p;s↑. next←q;s←q;q←u; end{then} else begin x←p↑.coef+q.coef; if x<>0 then begin p↑.coef←x; s←p;{修改p结 点的系数域} end;{then} else begin {删除p结点} s↑. next←p↑. next; dispose(p); end;{else} p←s↑.next; u←q; q←q↑.next; dispose(u); end;{else} if q<>nil then s↑.next←q;{将多项 式B中剩余结点链入和多项式c中} dispose(pb); {释放多项式B的哨兵} end;{polyadd}
插入操作 双向循环链表的哨兵指针为la。在该链表的第i个元素之 前插入元素x: procedure insert_dulist (x: elementype; i: integer; var la: dupointer); begin {生成新结点s,寻找双向循环链表中的第i个结点p} new(s);s↑.data←x;p←qet_dulist(i,la); if p<>nil then begin p↑.priou↑.next←s;{在结点p 前插入结点s} s↑.priou←p↑.priou; p↑.priou←s; s↑.next←p; end;{then} else write in (‘without’); end; {insert_dulist}
删除操作 双向循环链表的哨兵为la。删除该链表中的第i个结点q procedure delet_dulist (i:integer;var la:dupointer); begin p←get_dulist (i,la);{寻找双向循环链表中的第i个结点p} if p<>nil then begin{从双向循环链表中删除结点p } p↑.priou↑.next←p↑.next; p↑.next↑.priou←p↑.priou;dis. Pose(p); end else writeln (‘without’); end;{delet_dulist}
计算初始结点 由于报数从s开始。因此首先必须在以la为首结点的双 向循环链表中计算出第s个结点的地址。 function get_dulist(s: integer;la: pnode): pnode; var p: pnode;j: integer; begin p←la;j← 1; while (p^. next[0]<>la)and(j<s) do begin p←p^. next[0];j←j+1;end; if j=s then get_dulist←p else get_dulist←nil; end;{ get_dulist }
var k,n,i,j:integer; a:array[1. . 100]of boolean;{N盏灯的状态} begin readln (n);{读入灯的数目} for i:=1 to n do a[i]:=false;{初始时所有灯打开} for i:=1 to n do {依次进行n次操作} begin j:=i;{从第i号队员出发进行第i次操作} while j<=n do begin a[j]:=not(a[j]);j:=j+i;{将凡是i的倍数的灯作取反处理} end;{while} end;{for} for i:=1 to n do write(ord(a[i]));writeln;{输出n次操作后的结果} end. {main}
var a: array[1. . 100] of integer;{序列} i, j, k, t, n: integer; begin readln(n);{输入序列的元素个数} for i: =1 to n do read(a[i]);{输入序列} for i: =1 to n-1 do{依次确定递增序列中第 1个元素…第n-1个元素} begin k: =i;{计算ai……an中的最小元素k} for j: =i+1 to n do if a[j]<a[k] then k: =j; if i<>k{ak与ai互换位置} then begin t: =a[i];a[i]: =a[k];a[k]: =t;end;{then} end;{for} for i: =1 to n do write(a[i]: 6);{输出递增序列} end. {main}
- Slides: 84