设A表示其十进制表示不包含数字0的正整数集。A中元素的倒数之和已知为23.10345。
例如。1,2,3,4,5,6,7,8,9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,111-119,...
然后取每一个数的倒数,然后把总数加起来。
如何对此进行数值验证?
编写一个计算机程序来验证这个号码。
以下是我到目前为止所写的内容,我需要帮助解决这个问题,因为这需要很长时间才能完成:
Java中的代码
import java.util.*;
public class recip
{
public static void main(String[] args)
{
int current = 0; double total = 0;
while(total < 23.10245)
{
if(Integer.toString(current).contains("0"))
{
current++;
}
else
{
total = total + (1/(double)current);
current++;
}
System.out.println("Total: " + total);
}
}
}发布于 2010-10-02 21:41:54
对于current的所有值都大于某些阈值N,1.0/(double)current将足够小,因此total不会因为添加1.0/(double)current而增加。因此,终止标准应该类似于
while(total != total + (1.0/(double)current))而不是根据先验已知的极限进行测试。当current到达N的特殊值时,循环将停止。
发布于 2010-10-02 22:47:10
我怀疑转换到字符串然后检查字符'0‘是花费太长时间的步骤。如果您想避免所有的零,那么可能有助于增加current:
(编辑--感谢亚伦McSmooth)
current++;
for( int i = 10000000; i >= 10; i = i / 10 )
{
if ( current % i ) == 0
{
current = current + ( i / 10 );
}
}这是未经测试的,但概念应该很清楚:每当您命中10的倍数时(例如,300或20000),就会添加下一个较低的10 (在我们的示例中分别为10 + 1和1000 + 100 +10+1),直到您的数字中没有更多的零为止。
相应地更改您的while循环,看看如果您的问题变得易于管理的话,这对性能是否有帮助。
哦,您可能也需要限制System.out输出。每十、一百或一万次迭代就足够了吗?
编辑第二版:睡了一会儿,我想我的答案可能有点短视(如果你愿意的话,可以怪在深夜)。我只是希望,哦,一百万次的current迭代会让你找到解决方案,然后把它留在那里,而不是用log( current )等来计算校正案例。
再想一想,我看到了整个问题的两个问题。其一,你的目标号码是23.10345,这对我的口味很有帮助。毕竟,您正在添加数以千计的项,如"1/17“、"1/11111”等,它们具有无限的十进制表示形式,而且它们的加起来不太可能达到23.10345。如果数学专家这么说的话,那么我想看看他们得出这个结论的算法。
另一个问题与第一个问题有关,它涉及到有限内存中对有理数的二进制表示。你可以通过使用BigDecimals,但我有我的怀疑。
所以,基本上,我建议你重新编程的数值算法,而不是去蛮力的解。抱歉的。
编辑第三版:出于好奇,我在C++上写了这个来验证我的理论。它现在运行了6分钟,大约是14.5分钟(约550米)。迭代)。我们走着瞧。
当前版本是
double total = 0;
long long current = 0, currPowerCeiling = 10, iteration = 0;
while( total < 23.01245 )
{
current++;
iteration++;
if( current >= currPowerCeiling )
currPowerCeiling *= 10;
for( long long power = currPowerCeiling; power >= 10; power = power / 10 )
{
if( ( current % power ) == 0 )
{
current = current + ( power / 10 );
}
}
total += ( 1.0 / current );
if( ! ( iteration % 1000000 ) )
std::cout << iteration / 1000000 << " Mio iterations: " << current << "\t -> " << total << std::endl;
}
std::cout << current << "\t" << total << std::endl;手工计算currPowerCeiling (或无论如何可以调用它)可以节省每次迭代时的log10和pow计算。每一点都有帮助-但它仍然需要永远.
编辑第四版:状态约为66,000次迭代,总计高达16.2583次,运行时约为13小时。看起来不太好,鲍比·S
发布于 2010-10-04 05:44:50
如何将当前数字存储为一个字节数组,其中每个数组元素都是一个数字0-9?这样,您可以非常快速地检测零(使用==而不是String.contains比较字节)。
缺点是您需要实现增量,而不是使用++。您还需要设计一种方法来标记“不存在”数字,这样就不会将它们检测为零。为不存在的数字存储-1听起来是一种合理的解决方案。
https://stackoverflow.com/questions/3847615
复制相似问题