题目要求
涉及知识点:数组、流程控制、函数等
要求:用整型数组表示10进制大整数(超过2^32的整数),数组的每个元素存储大整数的一位数字,实现大整数的加减法。
题目解析
主体思路如下:
由于要求使用数组存储,首先使用字符串输入函数读取大整数,用数组的第一位存储正负符号。当输入的数据存在负数时,我们的想法便是将其转换为两个正数的加减。这样事实上只需要考虑正整数的加法和正整数的减法即可。
细节提示:
- 字符数组s中的字符转换为整型数组a中的数字。特别注意当大整数为负数时,字符数组中下标为0和下标为1的字符(s[0]和s[1]),一起转换存储到整型数组下标为0的单元(a[0]) 。 a[0]=-(s[1]-‘0’)
- 两个大整数相加时,分情况处理:
①两个大整数符号相反。比如负数+正数或者正数+负数,调用两个大整数相减的函数。
②两个大整数符号相同。比如负数+负数或者正数+正数。先对负数+负数的情况做处理,把两个大整数的负号去掉,转换为正数+正数的情况,按正数+正数的情况计算结果,最后结果再加上负号;然后对于正数+正数的情况,从个位开始模拟十进制加法并将结果倒序保存在另一个整型数组中;最后将倒序结果转为顺序。 - 两个大整数相减时,分情况处理:
①两个大整数符号相反。把第二个大整数的符号取反,然后调用两个大整数相加的函数。
②两个大整数中存在某个数为0的情况。
③两个大整数符号相同。
第一种情况:负数-负数的情况,转换为正数-正数。
第二种情况:正数-正数。先比较两个正大整数的大小,如果小-大,改为大-小,结果加上负号;如果相等,返回0;如果大-小,从个位数开始模拟十进制减法,并将结果倒序保存到另一个整型数组中,要注意是否高位要借位,也就是是否需要-1,本位结果如果为负数需要+10,并把高一位-1。
代码实现
#include<stdio.h>
#include<string.h>
int Positive(char s1[],char s2[],char math[],int len1,int len2,int n,int t)
{
int num[1001]={0},num1[1000]={0},num2[1000]={0}; //存储转换后的整形数字
int count=0;//用于比较同位数时,两个数字的大小
if(len1>len2){n=len1;}
else if(len1<len2){n=len2;t=1;}
else if(len1==len2){n=len1;t=2;} //为下面输出计算完成后的数字做准备
//printf("%d\n",t); //检验t是否正确
for(int i=0,j=len1-1;i<len1,j>=0;i++,j--){
num1[i]=s1[j]-'0';
}
for(int i=0,j=len2-1;i<len2,j>=0;i++,j--){
num2[i]=s2[j]-'0';
}//数据转换
if(math[0]=='+'){
for(int i=0;i<n;i++){
num[i]=num1[i]+num2[i];
}
for(int i=0;i<n;i++){
if(num[i]>=10){
num[i]-=10;
num[i+1]++;
}
}//进行运算
if(num[n]!=0){
for(int i=n;i>=0;i--){
printf("%d",num[i]);
}
}
else{
for(int i=n-1;i>=0;i--){
printf("%d",num[i]);
}
}//倒序输出
}//case1.1:正整数相加
else if(math[0]=='-'&&t==0){
for(int i=0;i<n;i++){
num[i]=num1[i]-num2[i];
}
for(int i=0;i<n;i++){
if(num[i]<0){
num[i]=num[i]+10;
num[i+1]--;
}
}//进行运算
if(num[n-1]!=0){
for(int i=n-1;i>=0;i--){
printf("%d",num[i]);
}
}
else{
for(int i=n-2;i>=0;i--){
printf("%d",num[i]);
}
}//倒序输出
}//case1.2.1:正整数相减(位数大减位数小)
else if(math[0]=='-'&&t==1){
for(int i=0;i<n;i++){
num[i]=num2[i]-num1[i];
}
for(int i=0;i<n;i++){
if(num[i]<0){
num[i]=num[i]+10;
num[i+1]--;
}
}//进行运算
printf("-");
if(num[n-1]!=0){
for(int i=n-1;i>=0;i--){
printf("%d",num[i]);
}
}
else{
for(int i=n-2;i>=0;i--){
printf("%d",num[i]);
}//倒序输出
}
}//case1.2.2:正整数相减(位数小减位数大)
else if(math[0]=='-'&&t==2){
for(int i=0;i<n;i++){
if(s1[i]>s2[i]){
count=0;break;
}
else if(s1[i]<s2[i]){
count=1;break;
}
else count=2;
}//用于比较同位数时,两个数字的大小
if(count==2){
printf("0");
}//case1.3.1:两个数字大小相同
else if(count==0){
for(int i=0;i<n;i++){
num[i]=num1[i]-num2[i];
}
for(int i=0;i<n;i++){
if(num[i]<0){
num[i]=num[i]+10;
num[i+1]--;
}
}//进行运算
int flag=0;
for(int i=n;i>=0;i--){
if(num[i]==0){
flag++;
}
else break;
}
for(int i=n-flag;i>=0;i--){
printf("%d",num[i]);
}//倒序输出 //case1.3.2:大减小
}
else if(count==1){
for(int i=0;i<n;i++){
num[i]=num2[i]-num1[i];
}
for(int i=0;i<n;i++){
if(num[i]<0){
num[i]=num[i]+10;
num[i+1]--;
}
}//进行运算
printf("-");
if(num[n-1]!=0){
for(int i=n-1;i>=0;i--){
printf("%d",num[i]);
}
}
else{
for(int i=n-2;i>=0;i--){
printf("%d",num[i]);
}//倒序输出 //case1.3.3:小减大
}
}
}//case1.3:正整数相减(位数相同)
return 0;
}
int Negative(char s1[],char s2[],char math[],int len1,int len2,int n,int t)
{
if(len1>len2){n=len1;}
else if(len1<len2){n=len2;t=1;}
else if(len1==len2){n=len1;t=2;} //为下面输出计算完成后的数字做准备
char temp1[1000]={0},temp2[1000]={0};
int l1=len1-1,l2=len2-1;
for(int i=0;i<l1;i++){
temp1[i]=s1[i+1];
}
for(int i=0;i<l2;i++){
temp2[i]=s2[i+1];
}//舍去负号,转存新数组
if(math[0]=='+'){
printf("-");
Positive(temp1,temp2,math,l1,l2,n,t);//转换为正整数相加
}//case2.1:负整数相加
char tmath[2];tmath[0]='-'; int tn=0,tt=0;
if(l2>l1){
tn=l2;
}
else if(l2<l1){tn=l1;tt=1;}
else if(l2==l1){tn=l1;tt=2;}//将两个负数相减转换为正数减负数
if(math[0]=='-'){
Positive(temp2,temp1,tmath,l2,l1,tn,tt);
}//case2.2:负整数相减
}//负数做加减
int PandN(char s1[],char s2[],char math[],int len1,int len2,int n,int t)
{
char temp[1000];
for(int i=0;i<len2-1;i++){
temp[i]=s2[i+1];
}//数组舍弃负号
char tmath[2];int l2=len2-1;
if(len1>l2){n=len1;t=0;}
else if(len1=l2){n=len1;t=2;}
else if(len1<l2){n=len2;t=1;}
if(math[0]=='+'){
tmath[0]='-';
Positive(s1,temp,tmath,len1,l2,n,t);
}//正数加负数,转化为正数减正数
else if(math[0]=='-'){
tmath[0]='+';
Positive(s1,temp,tmath,len1,l2,n,t);
}//正数减负数,转化为正数加正数
}
int main()
{
char s1[1000],s2[1000],math[2];
printf("请输入第一个数字\n"); scanf("%s",s1);
printf("请输入运算符 +/-\n"); scanf("%s",math);
printf("请输入第二个数字\n"); scanf("%s",s2); //读取数字和运算方式
int len1,len2;
len1=strlen(s1);len2=strlen(s2); //为数据转换做准备
//printf("%d %d\n",len1,len2);//检验len1和len2是否正确
int n;//printf("%d\n-------------\n",n);//检验n是否正确
int t=0;//两个数都是正数时,用于判断位数
char temp[1000];temp[0]='-';//case3.2.2中转换负数减正数为负数加负数时使用
if(s1[0]=='0'&&s2[0]=='0') {printf("0");}//0加0
else if(s1[0]=='0'&&math[0]=='+'&&s2[0]=='-'){
printf("-");
for(int i=1;i<len2;i++){
printf("%d",s2[i]-'0');
}
}//0加负数
else if(s1[0]=='0'&&math[0]=='-'&&s2[0]=='-'){
for(int i=1;i<len2;i++){
printf("%d",s2[i]-'0');
}
}//0减负数
else if(s2[0]=='0'&&math[0]=='+'&&s1[0]=='-'){
printf("-");
for(int i=1;i<len1;i++){
printf("%d",s1[i]-'0');
}
}//负数加0
else if(s2[0]=='0'&&math[0]=='-'&&s1[0]=='-'){
printf("-");
for(int i=1;i<len1;i++){
printf("%d",s1[i]-'0');
}
}//负数减0
//0和数字相加减
else if(s1[0]!='-'&&s2[0]!='-'){
Positive(s1,s2,math,len1,len2,n,t);
}//case1:两个正数做加减
else if(s1[0]=='-'&&s2[0]=='-'){
Negative(s1,s2,math,len1,len2,n,t);
}//case2:两个负数做加减
else if(s1[0]!='-'&&s2[0]=='-'){
PandN(s1,s2,math,len1,len2,n,t);
}//case3.1:正数在前,负数在后
else if(s2[0]!='-'&&s1[0]=='-'&&math[0]=='+'){
int m=len1;len1=len2;len2=m;
PandN(s2,s1,math,len1,len2,n,t);
}//case3.2.1:负数在前,正数在后(加法)
else if(s2[0]!='-'&&s1[0]=='-'&&math[0]=='-'){
math[0]='+';len2=len2+1;
for(int i=1;i<len1+1;i++){
temp[i]=s2[i-1];
}
Negative(s1,temp,math,len1,len2,n,t);
}
//case3:正数和负数做加减
return 0;
}
总共写了三个子函数,Negative是两个负数进行计算,Positive是两个正数进行计算,PandN是一个负数和一个正数。
剩下的解释在代码中应该都有注释,可能变量名字比较多比较复杂2333,反正我写的时候差点眼花
代码有些长了…主要还是因为我菜,大伙将就着看…
据听说有只写了几十行的…球球大佬别骂我…