【问题标题】:Adding strings of integers添加整数字符串
【发布时间】:2023-03-30 03:25:01
【问题描述】:

我正在尝试为一个更大的项目编写一个算法,该算法将采用两个都是大整数的字符串(为了这个演示,仅使用 10 位数字)并将它们加在一起以产生一个准确表示的最终字符串两个原始字符串的总和。我意识到从一开始就有可能更好的方法来解决这个问题,但我应该专门使用大整数字符串而不是长整数。

我的想法是取两个原始字符串,将它们反转,使它们的个位,十位等都正确排列以进行添加。然后一次一个位置,将字符串中的字符转换为单个整数并将它们加在一起,然后将该总和用作最终字符串的位置或其他位置,一旦完成也将反转回正确的字符顺序.

我认为我遇到麻烦的地方是准备事件,其中字符串中相应位置的两个整数相加的总和大于 9,然后我会将一些余数结转到下一个位置。例如,如果我的一个位置有 7 和 5 会加到 12,那么我会保留 2 并在十位位置循环后将 1 加到十位位置操作。

我没有得到任何准确的结果,并且在花费大量时间绊倒自己试图纠正我的算法之后,我不确定我需要做些什么来解决这个问题。

希望我的预期过程很清楚,有人能够指出我正确的方向或纠正我在程序中可能存在的一些错误。

提前致谢。

#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

int main()
{
    string str1 = "1234567890", str2 = "2345678901"; //Two original strings of large integers
    string rev_str1, rev_str2;
    int int1 = 0, int2 = 0;
    string final; //Final product string, sum of two original strings
    int temp_int = 0, buffer_int, remainder = 0;
    string temp_str = "", buffer_str;
    char buffer[100] = {0};

    cout << "str1 = " << str1 << endl;
    cout << endl;
    cout << "str2 = " << str2 << endl;
    cout << endl;

    rev_str1 = string(str1.rbegin(), str1.rend());
    rev_str2 = string(str2.rbegin(), str2.rend());

    for (int i = 0; i < 10; i++)
    {
        buffer_str = rev_str1.at(i);
        int1 = atoi(buffer_str.c_str());
        buffer_str = rev_str2.at(i);
        int2 = atoi(buffer_str.c_str());
        buffer_int += (int1 + int2 + remainder);
        remainder = 0;

        while (buffer_int > 9)
        {
            buffer_int -= 10;
            remainder += 10;
        }

        temp_str = itoa(buffer_int, buffer, 10);
        final += temp_str;
    }

    final = string(final.rbegin(), final.rend());

    cout << "final = " << final << endl;
    cout << endl;
}

【问题讨论】:

  • 您要求的基本上不是使用 char 数组的 BigInteger 实现吗?
  • 与 Euler #13 非常奇怪的相似之处,不是吗?
  • 几个实现cmets,和程序的正确性无关:为什么不直接用反向迭代器来遍历字符串呢?此外,std::string::at(size_t) 返回一个char,如果减去'0' 的值,您可以直接将其相加,不需要中间的std::stringatoi()。最后,当然不需要itoa(),只需添加'0' 的值并追加即可。最后,您可以预先分配结果字符串并对其进行迭代,最多比输入字符串的长度长一位。
  • 首先使其适用于长度为零的字符串,然后是长度为 1,然后是长度为 2,然后是不同长度等。

标签: c++ string integer


【解决方案1】:

您的问题是您携带的是 10s 而不是 1s。当您添加19 + 5 时,您会在单位位置获得 4,并在 10s 位置添加额外的 1。您不会在 10s 位置添加额外的 10。

您只需将这一行:remainder += 10; 更改为 remainder += 1;

此外,如果您有两个以上的加数,则不需要 while 循环。事实上,当您一次只添加两个数字时,您可以拥有的最大加数是 9 + 9,它只携带 1。

【讨论】:

  • 不错的解决方案。 :) 小小的澄清,不过。即使有更多的加数,您也可以通过简单地将数字和模 10 来避免 while 循环,这会立即给您剩下的。这是更清晰的代码,只需要一个部门的成本。
  • @Agentlien:如果您认为一次除法的成本低于 while 循环的多次迭代,请记住,有些架构甚至没有整数除法指令,而且对于那些做。不过,我欢迎速度比较。
  • 您说得很好,这就是为什么我说它“只花费一个部门”,而不是声称在实践中哪个更快。在支持除法指令的架构上,我希望它更快,即使除法是一项昂贵的操作。对于那些没有的,好吧..我发现模版本更干净,更易读的代码。如果稍后您意识到这在实践中太慢了。好吧,那时您应该查看应该优化哪些硬件以及哪个版本对于该特定架构更快......
【解决方案2】:

这就是我想出的。它只适用于两个求和;如果你有更多,你将不得不稍微调整一下,特别是进位,然后可以大于 19,以及结果字符串的分配方式:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    // Two original strings of large integers
    string str1 = "1234567890",
           str2 = "2345678901234";

    // Zero-padd str1 and str2 to the same length
    size_t n = max(str1.size(), str2.size());
    if (n > str1.size())
        str1 = string(n-str1.size(), '0') + str1;
    if (n > str2.size())
        str2 = string(n-str2.size(), '0') + str2;

    // Final product string, sum of two original strings.
    // The sum of two integers has at most one digit more, for more inputs make
    // below reverse_iterator a back_insert_iterator, then reverse the result
    // and skip the removal of the padding.
    string final(n+1, '0');

    // The carry
    char carry = 0;

    // Iterators
    string::const_reverse_iterator s1 = str1.rbegin(), e = str1.rend(),
                                   s2 = str2.rbegin();
    string::reverse_iterator f = final.rbegin();

    // Conversion
    for (; s1 != e; ++s1, ++s2, ++f)
    {
        // Bracketing to avoid overflow
        char tmp = (*s1-'0')+(*s2-'0') + carry;
        if (tmp > 9)
        {
            carry = 1;
            tmp -= 10;
        }
        else
        {
            carry = 0;
        }
        *f = tmp + '0';
    }
    final[0] = carry + '0';

    // Remove leading zeros from result
    n = final.find_first_not_of("0");
    if (n != string::npos)
    {
        final = final.substr(n);
    }

    cout << "str1 = " << str1 << endl
         << "str2 = " << str2 << endl
         << "final = " << final << endl;
}

【讨论】:

  • 谢谢,我改变了一些东西,但你的算法帮了我很多。我很感激。此外,这绝对是一种比我最初更清洁的方式。
【解决方案3】:
#include<iostream>

使用命名空间标准; 主(){

int sum =0;
int a;
int reminder;
cout<<"Enter the Number :"<<endl;
cin>>a;
while(a>0){
    reminder=a%10;
    sum=r+sum;
    a=a/10;`enter code here`

}
cout<<"Additon is :"<<sum<<endl;

}

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多