永发信息网

pascal输入两个最大位数不超过127位的长正整数A和B求A+B的和

答案:5  悬赏:0  手机版
解决时间 2021-05-07 19:01

就这道题。

还有,为什么一拿到关于循环或数组的题目我就无从下手,头脑一片空白?

过后老师将了源程序我确挺理解的。为什么?为什么?

最佳答案

其实吧,pascal关键就是多练习,自己编程,编出来再看答案,再看看与标准答案的区别,进一步优化


找经典例题(例:八皇后、快排)看透之后自己整个的编出来,多练练就好了

全部回答
var a,b,c:longint; begin read(a,b); c:=a+b; writeln(c); end.

典型的高精度正整数加法(我初中生)

因为整形变量没那么大的范围

所以用字符串(string),最高255位

主要三个步骤(就是跟小学竖式计算一样):对位(即在位数少的数前添0),相加(个位和个位加,十位和十位加,依此类推),进位(当某位数大于9,则用j的值表示进位)

程序如下:

var s1,s2,s3:string; l1,l2:integer; i,j,k:integer; begin readln(s1);readln(s2); l1:=length(s1);l2:=length(s2); if l1>l2 then for i:=1 to l1-l2 do s2:='0'+s2 else for i:=1 to l2-l1 do s1:='0'+s1; j:=0;s3:=''; for i:=length(s1) downto 1 do begin k:=ord(s1[i])-ord('0')+ord(s2[i])-ord('0')+j; if k>9 then begin k:=k-10; j:=1; end else j:=0; s3:=chr(ord('0')+k)+s3 end; if j=1 then s3:='1'+s3; writeln(s3); end.

这题数据范围太大,要用高精度做;

program sum; var s,s1,s2:string; a,b,c:array [1..260] of integer; i,l,k1,k2:integer; begin write('input s1:');readln(s1); write('input s2:');readln(s2); l:=length(s1); k1:=260; for i:=l downto 1 do begin a[k1]:=ord(s1[i])-48; k1:=k1-1; end; k1:=k1+1;

l:=length(s2); k2:=260; for i:=l downto 1 do begin b[k2]:=ord(s2[i])-48; k2:=k2-1; end; k2:=k2+1;

if k1>k2 then k:=k2 else k:=k1; y:=0; for i:=260 downto k do begin x:=a[i]+b[i]+y; c[i]:=x mod 10; y:=x div 10; end; if y<>0 then begin k:=k-1;c[k]:=y; end; for i:=k to 260 do write(c[i]); writeln; end.

优化:

以上的方法的有明显的缺点: (1)浪费空间:一个整型变量(-32768~32767)只存放一位(0~9); (2)浪费时间:一次加减只处理一位;

针对以上问题,我们做如下优化:一个数组元素存放四位数;(integer的最大范围是327

67,5位的话可能导致出界)。具体方法: l:=length(s1); k1:=260; repeat {————有关字符串的知识} s:=copy(s1,l-3,4); val(s,a[k1],code); k1:=k1-1; s1:=copy(s1,1,l-4); l:=l-4; until l<=0; k1:=k1+1; 而因为这个改进,算法要相应改变: (1)运算时:不再逢十进位,而是逢万进位(mod 10000; div 10000); (2)输出时:最高位直接输出,其余各位,要判断是否足够4位,不足部分要补0;例如:

1,23,2345这样三段的数,输出时,应该是100232345而不是1234567。

改进后的算法: program sum; var s1,s2:string; a,b,c:array [1..260] of integer; i,l,k1,k2,code:integer;

begin write('input s1:');readln(s1); write('input s2:');readln(s2); l:=length(s1); k1:=260; repeat {————有关字符串的知识} s:=copy(s1,l-3,4); val(s,a[k1],code); k1:=k1-1; s1:=copy(s1,1,l-4); l:=l-4; until l<=0; k1:=k1+1; l:=length(s2); k2:=260; repeat s:=copy(s2,l-3,4); val(s,b[k2],code); k2:=k2-1; s2:=copy(s2,1,l-4); l:=l-4; until l<=0; k2:=k2+1;

if k1<k2 then k:=k1 else k:=k2; y:=0; for i:=260 downto k do begin x:=a[i]+b[i]+y; c[i]:=x mod 10000; y:=x div 10000; end; if y<>0 then begin k:=k-1;c[k]:=y;end;

write(c[k]); for i:=k+1 to 260 do begin ----if c[i]<1000 then write('0'); ----if c[i]<100 then write('0'); ----if c[i]<10 then write('0'); ----write(c[i]); end; writeln; end.

所谓的高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类 型(整型,实型)能表示的范围的运算。例如,求两个200位的数的和。这时,就要用到高

精度算法了。在这里,我们先讨论高精度加法。高精度运算主要解决以下三个问题:

基本方法

1、加数、减数、运算结果的输入和存储 运算因子超出了整型、实型能表示的范围,肯定不能直接用一个数的形式来表示。在Pasc

al中,能表示多个数的数据类型有两种:数组和字符串。 (1)数组:每个数组元素存储1位(在优化时,这里是一个重点!),有多少位就需要多

少个数组元素; 用数组表示数的优点:每一位都是数的形式,可以直接加减;运算时非常方便 用数组表示数的缺点:数组不能直接输入;输入时每两位数之间必须有分隔符,不符合数

值的输入习惯;

(2)字符串:字符串的最大长度是255,可以表示255位。 用字符串表示数的优点:能直接输入输出,输入时,每两位数之间不必分隔符,符合数值

的输入习惯; 用字符串表示数的缺点:字符串中的每一位是一个字符,不能直接进行运算,必须先将它

转化为数值再进行运算;运算时非常不方便;

(3)因此,综合以上所述,对上面两种数据结构取长补短:用字符串读入数据,用数组存

储数据: var s1,s2:string; a,b,c:array [1..260] of integer; i,l,k1,k2:integer; begin write('input s1:');readln(s1); write('input s2:');readln(s2); {————读入两个数s1,s2,都是字符串类型} l:=length(s1);{求出s1的长度,也即s1的位数;有关字符串的知识。} k1:=260; for i:=l downto 1 do begin a[k1]:=ord(s1[i])-48;{将字符转成数值} k1:=k1-1; end; k1:=k1+1; {————以上将s1中的字符一位一位地转成数值并存在数组a中;低位在后(从第2

60位开始),高位在前(每存完一位,k1减1)}

对s2的转化过程和上面一模一样。

2、运算过程 在往下看之前,大家先列竖式计算35+86。 注意的问题: (1)运算顺序:两个数靠右对齐;从低位向高位运算;先计算低位再计算高位; (2)运算规则:同一位的两个数相加再加上从低位来的进位,成为该位的和;这个和去掉

向高位的进位就成为该位的值;如上例:3+8+1=12,向前一位进1,本位的值是2;可借助

MOD、DIV运算完成这一步; (3)最后一位的进位:如果完成两个数的相加后,进位位值不为0,则应添加一位; (4)如果两个加数位数不一样多,则按位数多的一个进行计算; if k1>k2 then k:=k1 else k:=k2; y:=0; for i:=260 downto k do begin x:=a[i]+b[i]+y; c[i]:=x mod 10; y:=x div 10; end; if y<>0 then begin k:=k-1;c[k]:=y; end;

3、结果的输出 按运算结果的实际位数输出 for i:=k to 260 do write(c[i]); writeln;

楼上的高精度过不了万位的,我有压位高精度,更快速的,虽然现在对于你来说没什么用,还是贴上吧。

program df; type arr=array [0..50000] of longint; var a,b,c:arr; x,y:ansistring; procedure chuli(x:ansistring; var a:arr); var l,y,i,v:longint; s:string; begin l:=length(x); y:=l div 4; for i:=1 to y do begin s:=copy(x,l-4*i+1,4); val(s,a[i],v); end; a[0]:=y; if l mod 4<>0 then begin s:=copy(x,1,l mod 4); val(s,a[y+1],v); a[0]:=a[0]+1; end; end; procedure cheng; var i,j,l:longint; s:string; begin for i:=1 to a[0] do for j:=1 to b[0] do begin inc(c[i+j-1],a[i]*b[j]); inc(c[i+j],c[i+j-1] div 10000); c[i+j-1]:=c[i+j-1] mod 10000; end; if c[a[0]+b[0]]<>0 then c[0]:=a[0]+b[0] else c[0]:=a[0]+b[0]-1; write(c[c[0]]); for i:=c[0]-1 downto 1 do begin str(c[i],s); l:=length(s); if l<4 then for j:=1 to 4-l do write(0); write(c[i]); end; end;

begin readln(x); chuli(x,a); readln(y); chuli(y,b); cheng; end.

我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
拒绝别人的爱情是不是也有错?
AU的 音乐微章多少钱
宜城市襄樊山东瓜籽南街店地址在哪里啊
大家一起来猜字
吞咽不适是怎么回事?
Chanel和Gucci那个香水好。
荣誉到多少工名才升级
谁有姐妹头像和兄弟头像、越多越好。速度啊
歌词“再一次用孩子的眼睛,再看一看这个世界
农历11月25日公历1月12日出生的人是什么星座
魔域怎么刷经验球最快!
我的显卡是不坏了啊?
九个月---一岁的小孩的饮食怎么搭配
自己马上大三了 而且自己上的三本 自己的专业
梁山仁和医院地址在什么地方,想过去办事
推荐资讯
襄汾中医院怎么去啊,有知道地址的么
有什么好看的动漫么???(是可爱型或帅哥、
什么叫林火发生率
高家山村怎么去啊,有知道地址的么
求这个皮肤的代码?
林俊杰何时出道的?
浦东高桥哪里有收14~15的孩子工作的
身份证丢了怎么办啊?
泥塑浮雕怎么做,怎么能在墙上做浮雕?! 10分
直接回复飞信短信怎么计费?
按钮开关怎么接,怎么接 感应开关
qq超人是不是在手机上只收一次钱吗?
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?