当前位置:文档之家› 第15讲_高精度计算

第15讲_高精度计算


10
#include <stdio.h> #include <string.h> #define MAX_LEN MAX LEN 110 int an1[MAX_LEN]; int an2[MAX_LEN]; char szLine1[MAX_LEN]; char szLine2[MAX_LEN]; int Substract( int nMaxLen, int * an1, int * an2) { //两个最多nMaxLen位的大整数an1减去an2, an1保证大于an2 int nStartPos = 0; for( int i = 0;i < nMaxLen ; i ++ ) { an1[i] -= an2[i]; //逐位减 if( an1[i] 1[i] < 0 ) { //看是否要借位 an1[i] += 10; an1[i+1] [ ] --; ; //借 借位 } if( an1[i] ) nStartPos = i; //记录最高位的位置 } return nStartPos; //返回值是结果里面最高位的位置 }
有两行,每行是一个不超过200位的非负整数,没有多余的前导0
输出要求
一行,即相加后的结果。结果里不能有多余的前导 , 余 导0, ,即如果结 果是342,那么就不能输出为0342

输入样例
22222222222222222222 33333333333333333333

输出样例
55555555555555555555
3. 下面的语句调用几次构造函数
Test * pArray[4] = { new Test(4), new Test(1,2) }; A 4 B 3 C 2 D 0 A. B. C. D. Test Array[4] = {Test(4), Test(1,2) };
3
课堂问题(2)
4 4. 指出下列各题中的错误,并说明如何改正 指出下列各题中的错误 并说明如何改正 class Time { private: int hour = 12; int minute = 0, second = 0; }; int Time::Time(int nHour, int nMin, int nSec); class l student{ t d t{ string name; public: void showName(){} } void showName(){ cout<<name<<endl; }
9
例题: POJ2736 大整数减法
输入样例 2 9999999999999999999999999999999999999 9999999999999 540965677509785089568705679806897093454654657567676867843 5435345 1 输出样例 9999999999999999999999990000000000000 540965677509785089568705679806897093454654657567676867843 5435344
13
解题思路
用unsigned i d an1[200] 1[200]和unsigned i d an2[200] 2[200]分别存放两个乘数,用 分别存放两个乘数 用 aResult[400]来存放积。计算的中间结果也都存在aResult中。aResult 长度取400是因为两个200位的数相乘,积最多会有 位的数相乘 积最多会有400位。 位 an1[0], an2[0], aResult[0]都表示个位。 一个数的第i位和另一个数的第j位相乘所得的数,一定是要累加 到结果的第(i+j)位上。这里i, j都是从右往左,从0开始数。 计算的过程基本上和小学生列竖式做乘法相同。为编程方便,并 不急于处理进位,而将进位问题留待最后统一处理。
5
解题思路
1) 用字符型或整型数组来存放大整数
an[0]存放个位数,an[1]存放十位数,an[2]存放百位数……
2) 模拟小学生列竖式做加法,从个位开始逐位相加, 超过或达到 超过或 到10则进位
用unsigned an1[201]保存第一个数,用unsigned an2[200]表示第 二个数,然后逐位相加,相加的结果直接存放在 个数,然后逐位相加,相加的结果直接存放在an1中 要注意处理进位
11
int main(){ int n; scanf("%d", ( &n); ) while(n -- ) { scanf("%s", szLine1); scanf("%s", szLine2); int i, j; memset( an1, 0, sizeof(an1)); memset( an2, 0, sizeof(an2)); //下面将 将szLine1中存储的字符串形式的整数转换到an1中去, 中去 //an1[0]对应于个位 int nLen1 = strlen( szLine1); f (j = 0, for(j 0 i = nLen1 L 1 - 1;i 1 i >= > 0 ; i --) ) an1[j++] = szLine1[i] - '0'; int nLen2 = strlen(szLine2); for( j = 0, 0 i = nLen2 - 1;i >= 0 ; i --) ) an2[j++] = szLine2[i] - '0'; int nStartPos = Substract( MAX_LEN, an1,an2); for( i = nStartPos; i >= 0; i -- ) printf("%d", an1[i]); printf("\n"); } return 0; } 12
1. 构造函数和析构 函数不能有返回类 型; 2. 成员属性不能在 类定义时初始化 3. 类定义时必须以 “;”结束 4. 成员函数不能重 复定义 5. 在类外定义成员 函数时要加类名和 域作用符
4
例题: POJ2981大整数加法 (P159)

问题描述
求两个不超过200位的非负整数的和

输入数据
例题: POJ2736 大整数减法
问题描述
求2个大的正整数相减的差
输入数据
第1行是测试数据的组数n,每组测试数据占2行,第1行是被减 数a,第2行是减数b(a ( > b) )。每组测试数据之间有一个空行,每行 每 有 个 ,每 数据不超过100个字符
输出要求
n行,每组测试数据有一行输出是相应的整数差
程序设计实习(II): 算法设计
第十五讲 高精度计算
通 知

ACM校内赛 推迟1小时开赛 每周上机练习( (2小时限时) 大作业——四色图

3人 人一组 组,不允许单人参加 不允许单人参加 1次练习+4次比赛
Name 第四次比赛(权重40) 第三次比赛(权重30) 第二次比赛(权重20) 第 次比赛(权重10) 第一次比赛(权重 练习赛(不计成绩) Game fourcolours(No.4) fourcolours(No.4) fourcolours(No.4) f l (N 4) fourcolours(No.4) fourcolours(No.4) Start Time 2012-06-02 2012 06 02 22:00 2012-05-26 22:00 2012-05-19 22:00 2012 05 12 22:00 22 00 2012-05-12 2012-05-05 22:00
15
再下来算4×3。此处4×3的结果代表12个100,因此要 aResult[2]+= 12,变为: aResult[2]+ 变为:
最后算 4×8。此处 此处4×8的结果代表 32个1000,因此要 因此要 aResult[3]+= 32,变为:
16
乘法过程完毕。接下来从 aResult[0]开始向高位逐位处理进 位问题。aResult[0]留下5,把4加到aResult[1]上,aResult[1] 变为51后,应留下1,把5加到aResult[2]上……最终使得 aResult里的每个元素都是1位数,结果就算出来了:

课堂问题(1)
1 C 1. C++类支持哪些访问权限? 每个访问权限的关 键字在类定义中可以出现几次? 2. 如果类定义中没有使用 private, protected或 public 关键字,则所有成员 关键字 则所有成员
A. 都是 public 成员 C. 都是 private 成员 B. 都是 protected 成员 D. 不一定
14
现以 835×49为例来说明程序的计算过程: 先算835×9。5×9得到45个1,3×9得到27个10,8×9 得到72个100。由于不急于处理进位,所以835×9算完后 ,aResult如下: 如
接下来算4×5。此处 此处4×5的结果代表20个10,因此要 因此要 aResult[1]+=20,变为:
6
7
#include <stdio.h> #include <string.h> #define MAX_LEN 201 int an1[MAX_LEN+10]; int an2[MAX_LEN+10]; char szLine1[MAX_LEN+10]; szLine1[MAX LEN+10]; char szLine2[MAX_LEN+10]; int Add(int nMaxLen , int * an1, int * an2) { //将长度最多为 nMaxLen 的大整数 an1和an2 相加,结果放在 相加 结果放在an1, an1 //an1[0], an2[0]对应于个位 int nHighestPos = 0; f (i t i = 0; for(int 0 i < nMaxLen; M L i ++ ) { an1[i] += an2[i]; //逐位相加 if( an1[i] >= 10 ) { //看是否要进位 an1[i] -= 10; an1[i+1] ++; //进位 } if( an1[i] ) nHighestPos = i; //记录最高位的位置 } return nHighestPos; }
相关主题