【问题标题】:How do I add two large non-negative integers using char array in C?如何在 C 中使用 char 数组添加两个大的非负整数?
【发布时间】:2019-04-03 08:07:33
【问题描述】:

我正在编写一个程序来添加两个大的非负整数(每个大整数最多包含 100 个数字)。然而,在我的程序中,大多数情况下它会给出错误的输出。

我已经完成了main() 函数,但我认为我的代码的问题在于AddTwoBigNumbers() 函数。

#include <stdio.h>

const int MAX_INT_LENGTH = 100;

void AddTwoBigNumbers(char bigN[], char bigM[], char sum[]) {
    int i = 0;
    int index = 0;
    int count = 0;
    int index2 = 0;
    while (1) {
        int sum1 = count;
        if (bigM[index]) {
            sum1 += bigM[index] - '0';
            index++;
        }
        if (bigN[index2]) {
            sum1 += bigN[index2] - '0';
            index2++;
        }
        sum[i] = sum1 % 10 + '0';
        i++;
        count = sum1 / 10;
        if (bigM[index] == 0 && bigN[index2] == 0) {
            break;
        }
    }
    if (count) {
        sum[i] = count + '0';
        i++;
    }
    sum[i] = 0;

    int x, len = 0;
    for (x = 0; sum[x]; ++x) {
        ++len;
    }

    for (x = 0; x < len / 2; ++x) {
        sum[len] = sum[x];
        sum[x] = sum[len - x - 1];
        sum[len - x - 1] = sum[len];
    }
}

int main() {
    char bignum[2][MAX_INT_LENGTH]; // bignum[0] and bignum[1] are to store the digits of the two input number
    char sum[MAX_INT_LENGTH + 1];     // to store the sum of the two big numbers

    // read in two numbers
    scanf("%s", bignum[0]);
    scanf("%s", bignum[1]);

    // calculate sum of the two numbers
    AddTwoBigNumbers(bignum[0], bignum[1], sum);

    // display the sum on screen
    printf("%s\n", sum);

    return 0;
}

示例案例如下:

输入:

1
999999999999999999999999999

输出:

1000000000000000000000000000

我的输出:

1000000000000000000000000000

输入:

999999999999999999999999999
999999999999999999999999999

输出:

1999999999999999999999999998

我的输出:

1999999999999999999999999989

【问题讨论】:

  • 添加时会发生什么:9 + 9、9 + 99、99 + 9、99 + 99
  • 这似乎是learn how to debug your programs的最佳时机。
  • 我也建议你以后在做这样的基本测试之前不要写完整的程序。而是编写一小段代码,构建(启用额外警告)并修复可能的错误和警告,然后测试一小段代码。然后你再写一小段代码,构建(和修复问题)和测试。等等。这样一来,解决问题、调试代码以及​​将错误搜索限制在您添加的最后一小段代码中都会变得更加容易。
  • 并且要小心你复制粘贴的代码。如果您需要多次执行相同的操作,而不是复制粘贴代码并进行小的更改(有时会被遗忘或错误),而是将通用代码放入函数中。哪怕只有几行。函数也更容易单独测试和调试。
  • @Kira:你是从左到右添加数字,这是不可能的,即如果你输入100034,你的函数将首先添加13 .我相信您在反转它之后也不会用\0 终止sum 变量。因此,首先要反转您的输入,终止求和,然后学习如何使用调试器使用具有明显结果的更简单的输入来单步调试您的代码。

标签: c string addition


【解决方案1】:

您的函数将两个整数从左到右相加。试试这个方法,是从后往前相加的算法(数组参数通常降级为指针,所以这里char *bigN等于char bigN[]):

void AddTwoBigNumbers(char *bigN, char *bigM, char* sum)
{
    int add = 0;
    int index = 0;
    int count = 0;
    int nbigN = strlen(bigN)-1;
    int nbigM = strlen(bigM)-1;
    while (nbigN >= 0 || nbigM >= 0)
    {
        int N = 0, M = 0;
        if (nbigN >= 0)
        {
            N = bigN[nbigN] - '0';
            nbigN--;
        }
        if (nbigM >= 0)
        {
            M = bigM[nbigM] - '0';
            nbigM--;
        }
        add = N + M + count;
        sum[index++] = add % 10 + '0';
        count = add / 10;
    }
    if (count)
        sum[index++] = count + '0';
    sum[index] = 0;
    int nsum = strlen(sum);
    for (int i = 0, j = nsum - 1; i < j; i++, j--)
    {
        char c = sum[i];
        sum[i] = sum[j];
        sum[j] = c;
    }
}

编辑:

int strlen(char* buf)
{
    int len = 0;
    if (buf == NULL)
        return len;
    while (*buf++)
        len++;
    return len;
}

【讨论】:

  • 我忘了说这个程序只能使用 头文件。
  • 只需要重写strlen()函数即可。
【解决方案2】:

在您发布的程序中,您首先考虑的是最高有效数字。

尝试先考虑最低有效数字,然后再考虑更高有效数字。

考虑可能产生的进位值并将它们添加到下一组值中并相应地重置进位值。

请记住,数字被视为字符。当您需要整数值时,从字符中减去'0',然后通过添加'0' 将它们转换回字符形式。

针对bigMbigN长度不同的情况也进行调整。

如果bigM 的所有数字都超过了,则使用bigN 的值和携带值(如果有)来计算sum 的所有剩余数字,反之亦然。

最后,在两个输入数字的所有数字都用完后,检查是否有剩余的进位,并将其添加到sum

您可以以相反的方式计算并插入值到sum,如果您愿意,可以稍后反转字符串。

别忘了在最后用 nul ('\0') 终止 sum


你可以这样做

void AddTwoBigNumbers(char bigN[], char bigM[], char sum[])
{
    int i=strlen(bigM)-1, j=strlen(bigN)-1, k, carry=0;
    for(k=0; i>=0 && j>=0; --i, --j, ++k)
    {
        sum[k] = (bigM[i]-'0' + bigN[j]-'0' + carry)%10 + '0';
        carry = (bigM[i]-'0' + bigN[j]-'0' + carry)/10;
    }

    for(; i>=0; --i, ++k)
    {
        sum[k] = (bigM[i]-'0' + carry)%10 + '0'; 
        carry = (bigM[i]-'0' + carry)/10;
    }
    for(; j>=0; --j, ++k)
    {
        sum[k] = (bigN[j]-'0' + carry)%10 + '0'; 
        carry = (bigN[j]-'0' + carry)/10;
    }
    if(carry!=0)
    {
        sum[k++]=carry+'0';
    }
    sum[k]=0;

    //Reversing string
    for(int t=0; t<n/2; ++t)
    {
        char temp=sum[t];
        sum[t]=sum[n-1-t];
        sum[n-1-t]=temp;
    }
}

【讨论】:

  • 我忘了说这个程序只能使用 头文件。
猜你喜欢
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-07
  • 2021-07-13
相关资源
最近更新 更多