for (; i < limit; i += x) {
x += 100;
}
を変えてループの反復の数を計算ループ構造を使用することなくi
とx
を計算するエレガントな解決策がありますか?はインクリメント
私の考え:
私はOにO(N)からの複雑さを軽減するために人気のガウス総和式1+2+3+4+...+n = (n*(n+1))/2
とバイナリ検索を使用することができます(Nを記録)。
Assume i = 0, x = 0 then:
i = 0*100 + 1*100 + 2*100 + 3*100 + ... + (n-1)*100 = ((n-1)*n)/2*100
if (i != 0 && x != 0) then:
i = i + x+0*100 + x+1*100 + x+2*100 + ... + x+(n-1)*100 = i+x*n + ((n-1)*n)/2*100
Thus (i < limit) = (i+x*n+((n-1)*n)/2*100 < limit)
今すぐ上記の不等式を満たす最大のn
を見つけるために、バイナリサーチのいくつかの種類を使用します。
if (i < limit)
for (n = 1; i+x*n+((n-1)*n)/2*100 < limit; n -= j, n += 1)
for (j = 1; i+x*n+((n-1)*n)/2*100 < limit; n += j, j += j);
今私は、反復ループの初期のn
の数を発見したことを、i
とx
を用いて計算することができます。
i += x*n+((n-1)*n)/2*100
x += 100*n
任意の提案ですか?より高速なO(1)ソリューションはありますか?
O(1)ソリューション:
const int d = 100;
while (i < limit) { i += x; x += d; }
ここにダニエルの答えの助けを借りて、反復O(1)ステップでn
、その後i
とx
の数を計算する方法です。
i < limit
= i+x*n+(n*(n+1))/2*d < limit
= d*n^2 + (2*x-d)*n - 2*(limit-i) < 0
上記式は次不等式であり、quadratic formula用いて解くことができる:i = i+x*n+((n-1)*n)/2*d
従って今解決することができる(上記参照)
(-b ± (b^2-4ac)^0.5)/2a
はしたがって反復n
の数である。
a = d
b = 2*x-d
c = -2*(limit-i)
n = ceil((-b + sqrt(b*b-4*a*c))/(2*a))
ここで、最初の(ループ)whileループの数はn
です。つの式を使用してとx
(上記参照):
i += x*n+((n-1)*n)/2*d
x += d*n
Iは、単純なCプログラムを使用してこれらの式をテストし、それはしばらく(のための)ループと同じ結果を与えます。
以前の質問に戻って回答を受け入れると、おそらくこの質問に対してより良い回答が得られます。 – mbeckish