在一些编程比赛中,数字大于任何可用的整数数据类型,我们通常使用字符串代替。
问题1: 有了这些大数字,如何在下面的表达式中计算 e 和 f ?
(a / b)+(c / d)= e / f
请注意: GCD(e,f)= 1 ,即它们必须为最小化形式。例如, {e,f} = {1,2} ,而不是 {2,4} 。
另外,所有 a,b,c,d 都是我们已知的大数字。
问题2: 有人还能建议一种方法来找到两个大数字(大于任何可用的整数类型)的GCD吗?
答案 0 :(得分:0)
我建议使用完整的字节或单词而不是字符串。
在以256为底数而不是10为底数的思想中相对容易,并且处理器不总是进行10的乘法和除法效率更高。理想情况下,选择的字长应为处理器自然字长的一半,因为这样便于携带。当然,以64K或4G为基础的思考要稍微复杂一些,但甚至比以256为基础更好。
唯一的缺点是从ascii输入生成初始大数,您可以从base 10中免费获得它。使用较大的单词大小,可以通过将多个数字最初处理成一个单词来提高效率(例如,一次将9位数字转换成4G字符),然后对该单词进行长倍乘以大整数格式的正确偏移量。
一个折衷方案可能是使引擎以10亿为基准运行:这仍然比使用10为基础的引擎高9或81倍!
求解该方程式的最简单方法是将a / b * d / d和c / d * b / b相乘,因此它们都具有公分母b * d。
我认为您将需要对大数e和f进行因子分解,以找到任何公因子。请记住再次搜索相同的平方系数。
当然,这意味着您必须编写素数生成筛。您只需要生成最大平方根或e和f最小值的一半位数的因子即可。
您可以对b和d进行素数分解以得到一个较低的初始分母,但是加法之后无论如何都需要再次进行。
答案 1 :(得分:0)
我认为解决此问题的方法是分离问题:
将输入数字处理为字符数组(即std::string
)
创建一个类,其中每个对象可以存储表示大数字之一的std::list
(或类似数字),并可以对数据进行所需的算术运算
然后,您可以正常解决问题,而不必担心大量输入会导致溢出。
Here's a webpage that explains how you can have such an arithmetic class(C ++中的示例代码显示附加内容)。
一旦有了这样的 arithmetic 类,您就不再需要担心如何存储数据或任何溢出。
给人的印象是,当您没有溢出问题时,您已经知道如何找到GCD,但以防万一here's an explanation of finding the GCD(带有C ++示例代码)。
关于特定的数学问题:
// given formula: a/b + c/d = e/f
// = ( ( a*d + b*c ) / ( b*d ) )
// Define some variables here to save on copying
// (I assume that your class that holds the
// large numbers is called "ARITHMETIC")
ARITHMETIC numerator = a*d + b*c;
ARITHMETIC denominator = b*d;
ARITHMETIC gcd = GCD( numerator , denominator );
// because we know that GCD(e,f) is 1, this implies:
ARITHMETIC e = numerator / gcd;
ARITHMETIC f = denominator / gcd;