文字列にキャストしてから文字「0」をチェックするのは、時間がかかりすぎるステップだと思います。すべてゼロを避けたい場合は、次のように増やすと役立つ場合がありますcurrent
。
(編集-Aaron 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
ああ、出力も少し制限したいかもしれません。10分の1、100分の1、または10000回の反復で十分でしょうか?
2番目の編集:
少し眠った後、私の答えは少し近視眼的かもしれないと思います(もしそうなら、遅い時間のせいにしてください)。などcurrent
を使用して修正ケースを計算するのではなく、100万回の反復で解決策が得られ、そのままにしておくことを望んでいました。log( current )
考え直してみると、この問題全体に2つの問題があります。1つは、23.10345の目標数が、私の好みに合わせて丸めるのが難しいということです。結局のところ、「1/17」や「1/11111」などの数千のアイテムを無限の小数表現で追加しているので、合計が正確に23.10345になる可能性はほとんどありません。数値数学の専門家がそう言うなら、それでいいのですが、それなら、彼らがこの結論に到達したアルゴリズムを見たいと思います。
もう1つの問題は、最初の問題に関連しており、有理数の限られたメモリ内バイナリ表現に関係しています。BigDecimalsを使用することで得られるかもしれませんが、私には疑問があります。
したがって、基本的には、力ずくの解決策を採用するのではなく、数値アルゴリズムを再プログラムすることをお勧めします。ごめん。
3番目の編集:
好奇心から、理論をテストするためにこれをC++で記述しました。現在6分間実行されており、約14.5(約550 mio。の反復)です。わかります。
現在のバージョンは
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
4番目の編集:
ステータスは約66,000 mioの反復、合計は最大16.2583、実行時間は約13時間です。見栄えが悪い、ボビーS.-私はもっと数学的なアプローチを提案します。