【问题标题】:Division of a big number of 100 digits stored as string存储为字符串的大量 100 位数字的除法
【发布时间】:2014-07-04 18:41:46
【问题描述】:

我有一个 100 位数字存储为字符串。我想用小于 10 的整数除这个数。如何有效地将存储为字符串的大整数除以整数?

【问题讨论】:

  • 两种可能的(最明显的,众多的)方式。 (1):使用 BigInt 库。 (2):在代码中实现你在三年级或四年级学到的速记除法算法。
  • 感谢@DavidO,但是对于如此大的整数,速写除法运行非常缓慢。我该如何克服它?
  • 是的,这并不奇怪。如果这是一个学习练习,我会推荐“选项 2”,但它可能会很慢。如果是用于实际使用,我会推荐“选项 1”,因为它速度快、经过良好测试并且有据可查。
  • 一种方法,仅用于学习:将数字转换为基数 N,其中 N 是您要与之相除的数字;右移一位;转换回原来的基数 10。转换成基数 N 涉及基数 N 的加法和乘法。好吧,它可能不是“有效的”。只是在我看来,它似乎是 O(n^2),二次时间。但很适合学习。
  • 长除法的工作原理与您的数字所代表的基数无关。由于您想要一个可以将字符串转换为没有开销的基数,因此您只关心 10 次方的基数,并适合您的机器的原始整数大小。因此,假设一台 32 位机器,您可以以 10^8 为基数进行普通除法。这将导致分部数量减少 8 倍。您可以通过预先计算 10 的 8 次方来进一步加快速度。这将有助于您的编译器将 8 位数字转换为相应的数字。

标签: c++ string bignum


【解决方案1】:

您可以查看big integer library

您可以在 C++ 程序中使用此库对大小仅受计算机内存限制的整数进行算术运算。该库提供分别表示非负整数和有符号整数的 BigUnsigned 和 BigInteger 类。大多数 C++ 算术运算符都为这些类重载,因此大整数计算很简单:

#include "BigIntegerLibrary.hh"

BigInteger a = 65536;
cout << (a * a * a * a * a * a * a * a);

(prints 340282366920938463463374607431768211456)

同时检查GMP

【讨论】:

  • 感谢@R.T.有没有什么方法可以在不使用这个库和普通除法的情况下实现它?
  • @WasimThabraze 是的,您所做的正是编写库的人所做的:v。 (或者,只使用库)
  • :P 我去图书馆! @MohammadAliBaydoun
【解决方案2】:

@WasimThabraze - 你对普通除法的理解是什么?由于除数小于整数大小的 1/2,因此您可以对每个除数使用类似的内容:

char array[10] = {9,8,7,6,5,4,3,2,1,0};

void divide(int dvsr)
{
int rem = 0;
int dvnd;
int quot;
int i;
    for(i = 0; i < (sizeof(array)/sizeof(array[0])) ; i++){
        dvnd = (rem * 10) + array[i];
        rem = dvnd % dvsr;
        quot = dvnd / dvsr;
        array[i] = quot;
    }
}

int main(void)
{
    divide(8);
    return (0);
}

【讨论】:

  • 如果rem * 10 高于 INT_MAX 怎么办?
  • @realUser404 - dvsr(除数)的最大值为 9,因此 rem*10 的最大值为 80。
  • @rcgldr 很抱歉提出一个老问题,但是您是否以具有最大权重的数字位于数组中的第一个位置的方式存储大数字,反之亦然?
  • @smrdo_prdo - 在本例中,最高有效位在前,等于 array[0]。
  • @rcgldr 非常感谢!
【解决方案3】:

我希望这对您有所帮助,因为并非所有在线评委都允许BigIntegerLibrary。我假设有一些任意输入。

string input="123456789";
int n=input.size();
string final(n,'0');
string::const_iterator  p=input.begin(),q=input.end();
string::iterator f=final.begin();

void divide(int divisor)
{
 int reminder = 0,dividend,quotient;

 /*repeatedly divide each element*/
 for(; p!=q ; p++,f++){
    dividend = (reminder * 10) + (*p-'0');
    reminder = dividend % divisor;
    quotient = dividend / divisor;
    *f = quotient + '0';
 }
 /*remove any leading zeroes from the result*/
 n = final.find_first_not_of("0");
 if (n != string::npos)
 {
    final = final.substr(n);
 }
 std::cout << final ;
}

int main(){
   int x;
   std::cin  >> x;
   divide(x);
   return 0;
}

【讨论】:

    猜你喜欢
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多