BUAA大一下数据结构题解(超长正整数的减法)

【问题描述】
编写程序实现两个超长正整数(每个最长80位数字)的减法运算。
 
【输入形式】

从键盘读入两个整数,要考虑输入高位可能为0的情况(如00083)。
1. 第一行是超长正整数A;
2. 第二行是超长正整数B;
 
【输出形式】
输出只有一行,是长整数A减去长整数B的运算结果,从高到低依次输出各位数字。要求:若结果为0,则只输出一个0;否则输出的结果的最高位不能为0,并且各位数字紧密输出。
 【输入样例】
 
234098
134098703578230056
 
【输出样例】
 -134098703577995958

【样例说明】
进行两个正整数减法运算, 234098 -134098703578230056 = -134098703577995958。

解题思路:这个整数过长,明显超出int的范围,因此采用处理字符串的方法进行处理,将这个数字用字符的形式读入之后再转换为整数的形式,然后采用我们所学得列竖式计算的方法对其进行处理。需要注意的是,题目中给出输入的整数最高位可能为0,我们要将最高位的0给去除。

参考代码:

#include <stdio.h>
#include <string.h>
char shuzi1[100],shuzi2[100];//用于使用字符串的形式读入两个数
int num1[100],num2[100];//用于储存将字符串形式转换为整数
int mark,flag1,flag2,l1,l2;//mark用于判断第一个数和第二个数谁大,flag1和flag2表示输入的数的第一个不为零的数的位置,l1代表第一个数字的位数,l2同理
int cunfang(int len1,int len2)
{
    int i;
    for(i=0;i<len1;i++)
        num1[i]=shuzi1[l1-i-1]-'0';//将第一个数字中的有效数字存入num1中
    for(i=0;i<len2;i++)
        num2[i]=shuzi2[l2-i-1]-'0';//将第二个数字中的有效数字存入num2中
}
int xiangjian(int len)
{
    int i;
    if(mark==1)//说明第一个数字大
    {
        for(i=0;i<len;i++)
        {
            if(num1[i]<num2[i])
            {
                num1[i]=num1[i]+10;
                num1[i+1]=num1[i+1]-1;
            }//如果较小就借一位数字
            num1[i]=num1[i]-num2[i];
        }
        for(i=len-1;i>=0,len>0;i--)
        {
            if(num1[i]==0)
                len--;
            else
                break;
        }//将数字中的无效的0去掉
        for(i=len-1;i>=0;i--)
            printf("%d",num1[i]);//输出结果
    }
    else//说明第二个数字大(要用第二个数字减去第一个数字然后加上负号)
    {
       for(i=0;i<len;i++)
        {
            if(num2[i]<num1[i])
            {
                num2[i]=num2[i]+10;
                num2[i+1]=num2[i+1]-1;
            }//如果较小就借一位数字
            num2[i]=num2[i]-num1[i];
        }
        for(i=len-1;i>=0,len>0;i--)
        {
            if(num2[i]==0)
                len--;
            else
                break;
        }//将无效的0去掉
        if(len==0)
            printf("0");
        else
        {
            printf("-");
            for(i=len-1;i>=0;i--)
                printf("%d",num2[i]);
        }
    }
}

int main()
{
    int len1,len2,i=0;
    scanf("%s%s",shuzi1,shuzi2);//读取数字
    len1=strlen(shuzi1);
    l1=len1;
    len2=strlen(shuzi2);
    l2=len2;//判断数字的长度
    for(i=0;i<len1;i++)
    {
        if(shuzi1[i]!='0')
        {
            flag1=i;
            break;
        }
    }//判断数字头有多少个无效的0
    for(i=0;i<len2;i++)
    {
        if(shuzi2[i]!='0')
        {
            flag2=i;
            break;
        }
    }//判断数字头有多少个无效的0
    len1=len1-flag1;
    len2=len2-flag2;//得到有效的长度
    if(len1>len2||strcmp(shuzi1,shuzi2)>0&&len1==len2)//第一个数大于第二个数
    {
        mark=1;
        cunfang(len1,len2);
        xiangjian(len1);
    }
    else//第一个数小于等于第二个数
    {
        mark=2;
        cunfang(len1,len2);
        xiangjian(len2);
    }
}

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值