大数减法——大数问题

大数减法的实现与加法基本类似,只不过减法要多考虑一些问题,首先要知道减法中的两个名词,“减数”与“被减数”(例如:5-3=2,5就是减数,3就是被减数,2就是结果),然后就是需要考虑在减的时候有可能是大数减小数得到负数(例如:3-5=-2),这样的问题就需要我们判断两个数的大小,根据大小进行相减操作,具体实现在代码中,还有一个问题,就是借位问题,在加法中,我们相加有时候需要进位,而在减法中,借位也是不可避免的,当减数的那一位数小于被减数那一位的数时,减数的那一位就需要向前一位借1;(例如:23-5=18,减数个位3  减  被减数个位5,3<5,3需要向前借1,13-5=8,结果为18),详情见代码(此代码不能解决负数):

#include<stdio.h>
#include<string.h>

int x[1000]={0},y[1000]={0},z[1005]={0};//将数组元素全部初始化为0

void sub(int x[],int y[],int len)
{
    int i,j;

    for(i=0;i<len;i++)
    {
        if(x[i]>=y[i])//如果x[i]>=y[i],不用向前一位借1,可直接减
            z[i]=x[i]-y[i];

        else  //如果x[i]<y[i],向前一位借1,同时前一位应减1
        {
            z[i]=x[i]+10-y[i];
            x[i+1]=x[i+1]-1;
        }
    }

    for(i=len-1;i>0;i--)//删除前缀0
    {
        if(z[i]==0)
            len--;
        else
            break;
    }

    for(i=len-1;i>=0;i--)  //倒序输出数组
        printf("%d",z[i]);

    printf("\n");
}
int main()
{
    char a[1000],b[1000];//通过字符串对大数进行输入并储存
    int len1,len2;

    while(scanf("%s %s",a,b)!=EOF)
    {
        int i,j=0,k=0;

        len1=strlen(a);
        len2=strlen(b);

        for(i=len1-1,j=0;i>=0;i--)//将两个字符串中的字符转化为数字,并倒序储存到数组中,即字符串为123456,则数组为654321
            x[j++]=a[i]-'0';//a[i]-'0'的意思为:因为我们将数字以字符串的形式输入,所以如果a[i]为'1',则在ASCLL中 '1' = 49;而'0'为48,所以49-48=1,转化为数字

        for(i=len2-1,k=0;i>=0;i--)
            y[k++]=b[i]-'0';

        if(len1>len2)  //若减数长度 > 被减数长度,正常减
            sub(x,y,len1);

        else if(len1<len2)  //若减数长度 < 被减数长度,被减数 减 减数
        {
            printf("-");
            sub(y,x,len2);
        }

        else  //若减数长度 == 被减数,判断两个数的大小
        {
            for(i=len1-1;i>=0;i--)//判断每一位两个数的大小
            {
                if(x[i]==y[i])
                    continue;
                if(x[i]>y[i])//即减数大
                {
                    sub(x,y,len1);
                    break;
                }
                if(x[i]<y[i])//即被减数大
                {
                    printf("-");
                    sub(y,x,len1);
                    break;
                }
            }
        }
    }
    return 0;
}

大数基本运算思路:https://blog.csdn.net/ysz171360154/article/details/85006289

大数加法:https://blog.csdn.net/ysz171360154/article/details/85006990

大数乘法:https://blog.csdn.net/ysz171360154/article/details/88918627

大数除法:https://blog.csdn.net/ysz171360154/article/details/88956342

大数阶乘:https://blog.csdn.net/ysz171360154/article/details/88929391

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java链表实现大数减法的示例代码: ```java import java.util.*; public class BigIntegerSubtraction { public static void main(String[] args) { // 生成两个随机数 String num1 = generateRandomNumber(); String num2 = generateRandomNumber(); System.out.println("num1: " + num1); System.out.println("num2: " + num2); // 将两个数存储到链表中 LinkList list1 = new LinkList(); LinkList list2 = new LinkList(); for (int i = num1.length() - 1; i >= 0; i--) { list1.Insert(num1.charAt(i) - '0'); } for (int i = num2.length() - 1; i >= 0; i--) { list2.Insert(num2.charAt(i) - '0'); } // 对两个链表进行减法操作 LinkList result = new LinkList(); int borrow = 0; Node p = list1.front, q = list2.front; while (p != null || q != null) { int x = p != null ? p.data : 0; int y = q != null ? q.data : 0; int z = x - y - borrow; if (z < 0) { z += 10; borrow = 1; } else { borrow = 0; } result.Insert(z); if (p != null) { p = p.next; } if (q != null) { q = q.next; } } // 输出结果 System.out.print("result: "); result.PrintList(); } // 生成1~50位的随机数 public static String generateRandomNumber() { Random random = new Random(); int length = random.nextInt(50) + 1; StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { sb.append(random.nextInt(10)); } return sb.toString(); } } class LinkList { public Node front; public int length = 0; public LinkList() { front = null; } public void Insert(int data) { Node newNode = new Node(data); if (front == null) { front = newNode; } else { Node p = front; while (p.next != null) { p = p.next; } p.next = newNode; } length++; } public void GetList() { Node p = front; while (p != null) { System.out.print(p.data + " "); p = p.next; } System.out.println(); } public void PrintList() { Node p = front; while (p != null && p.data == 0) { p = p.next; } if (p == null) { System.out.print("0"); } else { while (p != null) { System.out.print(p.data); p = p.next; } } System.out.println(); } public int GetRear() { Node p = front; while (p.next != null) { p = p.next; } return p.data; } } class Node { public int data; public Node next; public Node(int data) { this.data = data; next = null; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值