每日打卡一小时(第十九、二十天)
一.问题描述
6-3 【CPP0024】设计并实现大数类BigNum
定义一个整数型大数类,要求能够完成100位以内的较大整数的加法和减法计算,main(void)函数完成对其的测试。
BigNum类结构说明:
BigNum类的数据成员包括:
①私有数据成员:数值域num(char []型)。
BigNum类成员函数包括:
①有参构造函数BigNum(char c[])和拷贝构造函数BigNum(const BigNum &),其中有参构造函数参数默认值为"+0",输出信息"BigNum Constructor run",拷贝构造函数输出信息"BigNum CopyConstructor run"
②析构函数,析构函数输出信息"BigNum Destructor run"
③公有函数成员void setNum(char c[])和char const *getNum(void) const分别返回和设置数值域。
④重载“+”运算符,实现两个BigNum对象相加的运算
⑤重载“-”运算符,实现两个BigNum对象相减的运算
⑥公有成员函数void show() const用于显示BigNum对象的信息,显示格式为:BigNum(<数值域>)
建议:大数存储时专门存储符号位且低位存储在前,高位存储在后。这样便于运算实现。
二.设计思路
1.注意构造和设置值时位数倒置
2.注意计算时同号和异号带来的转换
3.注意每个数的位数高低
4.注意减法时数的大小比较方式(先比较位数再比较去符号后数的大小)
三.代码实现
#include <iostream> using namespace std; #define N 100 #include<cstring> class BigNum { private: char num[N]; public: BigNum(char c[N] = "+0"); BigNum(const BigNum& p); ~BigNum() { cout << "BigNum Destructor run" << endl; } void setNum(char c[N]); char const* getNum(void) const; BigNum operator + (const BigNum& a); BigNum operator - (BigNum& b); void show() const; }; BigNum::BigNum(char c[N]) { int i, j, a = strlen(c); if (c[0] != '-') { num[0] = '+'; if (c) { for (i = strlen(c), j = 0; i >= 1; i--, j++)//输入的数据倒置 { num[i] = c[j]; } } num[a + 1] = '\0'; } else { num[0] = c[0]; for (i = strlen(c) - 1, j = 1; i >= 1; i--, j++) { num[i] = c[j]; } num[a] = '\0'; } cout << "BigNum Constructor run" << endl; } BigNum::BigNum(const BigNum& p) { int i = 0; for (i; p.num[i] != '\0'; i++) { num[i] = p.num[i]; } num[i] = '\0'; cout << "BigNum CopyConstructor run" << endl; } void BigNum::setNum(char c[N]) { int i, j, a = strlen(c); if (c[0] != '-') { num[0] = '+'; if (c) { for (i = strlen(c), j = 0; i >= 1; i--, j++) { num[i] = c[j]; } } num[a + 1] = '\0'; } else { num[0] = c[0]; for (i = strlen(c) - 1, j = 1; i >= 1; i--, j++) { num[i] = c[j]; } num[a] = '\0'; } } char const* BigNum::getNum(void) const { return num; } BigNum BigNum::operator + (const BigNum& a) { if (num[0] == '+' && a.num[0] == '-')////如果异号将加法转为减法 { BigNum s2(a); s2.num[0] = '+'; return (*this) - s2; } if (num[0] == '-' && a.num[0] == '+') { BigNum s2(a); num[0] = '+'; return s2 - (*this); } BigNum s; int i; char s2[N]; for (i = 0; a.num[i] != '\0'; i++) { s2[i] = a.num[i]; } s2[i] = '\0'; int len1 = strlen(num); int len2 = strlen(s2); int Max = 0; if (len1 > len2)//先比较位数大小 { Max = len1; num[len1] = '0'; for (i = len2; i <= len1; i++) { s2[i] = '0'; } } else { if (len1 < len2) { Max = len2; s2[len2] = '0'; for (i = len1; i <= len2; i++)//将位数小的数的再高的位数全置为‘0‘ { num[i] = '0'; } } else { Max = len1; s2[len2] = '0'; num[len1] = '0'; } } if ((num[0] == '+' && s2[0] == '+') || (num[0] == '-' && s2[0] == '-'))//进行计算 { for (i = 1; i <= Max; i++) { int c = ((num[i] - '0') + (s2[i] - '0')); if (c >= 10)//满十进一 { c -= 10; s.num[i] = char(c + '0'); s2[i + 1]++; } else { s.num[i] = char(c + '0'); } } s.num[i] = '\0'; if (num[0] == '+' && s2[0] == '+')//符号判断 { s.num[0] = '+'; } if (num[0] == '-' && s2[0] == '-') { s.num[0] = '-'; } } return s; } BigNum BigNum::operator - (BigNum& b) { if (num[0] == '+' && b.num[0] == '-')//将异号转化为加法 { BigNum s2(b); s2.num[0] = '+'; return (*this) + s2; } if (num[0] == '-' && b.num[0] == '+') { BigNum s2(b); s2.num[0] = '-'; return (*this) + s2; } BigNum s; int i; char s2[N]; for (i = 0; b.num[i] != '\0'; i++) { s2[i] = b.num[i]; } s2[i] = '\0'; int len1 = strlen(num); int len2 = strlen(s2); int Max = 0; if (len1 > len2) { Max = len1; num[len1] = '0'; for (i = len2; i <= len1; i++) { s2[i] = '0'; } } else { if (len1 < len2) { Max = len2; s2[len2] = '0'; for (i = len1; i <= len2; i++) { num[i] = '0'; } } else { Max = len1; s2[len2] = '0'; num[len1] = '0'; } } if ((num[0] == '+' && s2[0] == '+') || (num[0] == '-' && s2[0] == '-')) { if (num[0] == '-' && s2[0] == '-') { s2[0] = '+'; num[0] = '+'; for (i = 0; num[i] != '\0'; i++) { char ch; ch = num[i]; num[i] = s2[i]; s2[i] = ch; } } char s1[N]; char s3[N]; int j; for (i = Max, j = 0; i > 0; j++, i--) { s1[j] = num[i]; } s1[j] = '\0'; for (i = Max, j = 0; i > 0; j++, i--) { s3[j] = s2[i]; } s3[j] = '\0'; if (strcmp(s1, s3) > 0) { s.num[0] = '+'; for (i = 1; i <= Max; i++) { int c = ((num[i] - '0') - (s2[i] - '0')); if (c < 0) { c += 10; s.num[i] = char(c + '0'); num[i + 1]--; } else { s.num[i] = char(c + '0'); } } s.num[i] = '\0'; } else { if (strcmp(s1, s3) < 0) { s.num[0] = '-'; for (i = 1; i <= Max; i++) { int c = ((s2[i] - '0') - (num[i] - '0')); if (c < 0) { c += 10; s.num[i] = char(c + '0'); s2[i + 1]--; } else { s.num[i] = char(c + '0'); } } s.num[i] = '\0'; } else { s.num[0] = '+'; s.num[1] = '0'; s.num[2] = '\0'; } } } return s; } void BigNum::show() const { char ch[N] = "+0"; char c[N] = "+00"; if (strcmp(ch, num) == 0 || strcmp(c, num) == 0) { cout << "BigNum(" << ch << ")" << endl; } else { cout << "BigNum(" << num[0]; int i; int flag; for (i = strlen(num) - 1; i >= 0; i--) { if (num[i] != '0') { flag = i; break; } } for (i = flag; i >= 1; i--) { cout << num[i]; } cout << ")" << endl; } } int main(void) { char c[100], op; cin >> c; BigNum b1(c), b2(b1); b1.show(); cin >> c; b2.setNum(c); b2.show(); cin >> op; if (op == '+') (b1 + b2).show(); if (op == '-') (b1 - b2).show(); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现