数学用語が苦手です。
これは何と呼ばれていますか?
48 という数字があるとします。48 を構成する 2 つの要素を見つける必要があります。48 では 8,6 72 では 9,8 になります。
48 に対して 12,4 や 12,6 とは言いたくない
public static int[] revominuteFactors(long x) {
int[] result = new int[2];
for (int a = 0; a <= x; a++) {
for (int b = 0; b <= x; b++) {
if ((a * b) == x) {
if (result[0] == 0 && result[1] == 0) {
result[0] = a;
result[1] = b;
} else if (Math.abs(a - b) < Math.abs(result[0] - result[1])) {
result[0] = a;
result[1] = b;
}
}
}
}
return result;
}
数学の教授に尋ねたところ、その名前はrevominute要因に沿っているとのことでした.
そのような数字に特定の名前はないと思います。それらを見つけることに関しては、おそらく最も簡単な方法は次のとおりです(数値nが与えられた場合):
int factor1, factor 2;
for (int i = (int)(Math.sqrt(n)); i > 0; i--) {
if (i/n == (double)i/n) {
factor1 = i;
factor2 = i/n;
break;
}
}
それが役立つことを願っています!
距離が最も小さい因子のペアに特定の名前はありません。しかし、それがあなたが望むものかどうかを計算するのは簡単です。(少なくとも一般的な因数分解と同じくらい簡単ですが、小さな数の場合は簡単です。)
これを行う 1 つの方法を次に示します (2 つの因数が接近している場合に最も高速になります)。これは、フェルマーの因数分解アルゴリズムに基づいています。
static int sqrRoot(int n){
//Find largest square <= n
int sqr = 0;
for (int i=15; i >= 0; --i){
int newsqr = sqr + (1<<i);
if (newsqr * newsqr <= n) {sqr = newsqr;}
}
return sqr;
}
static int[] closestFactors(int n){
if (n <= 0) {throw new IllegalArgumentException();}
int s = sqrRoot(n);
if (s*s == n){
int[] ans = {s,s};
return ans;
}
int a = s * s - n;
while(s < n){
if (a > 0){ //may not be true on first iteration
int sa = sqrRoot(a);
//whole number case
if (sa*sa == a){ //We found a factorization
int[] ans = {s-sa, s+sa};
return ans;
}
}
//half number case
int sa2 = sqrRoot(a+s);
if (sa2 * (sa2+1) == a+s){
int[] ans = {s-sa2, s+sa2+1};
return ans;
}
a += s + s + 1;
s++;
}
int[] ans = {1, n};
return ans;
}
明らかに、すべての因子を見つけて、リストから適切な因子を選択するだけです。
別の方法として、 から始めることもできますlow = high = floor(sqrt(n))
。次に、 の場合low * high < n
、インクリメントしますhigh
。場合low * high > n
、減分しますlow
。の場合は、答えとしてlow * high = n
返します。(low, high)
これはそれほど効率的ではありませんが、おそらくいくつかの小さな最適化を行うことができます。
例:
n = 325
low = 18, high = 18, low * high = 324
low = 18, high = 19, low * high = 342
low = 17, high = 19, low * high = 323
low = 17, high = 20, low * high = 340
low = 16, high = 20, low * high = 320
low = 16, high = 21, low * high = 336
low = 15, high = 21, low * high = 315
low = 15, high = 22, low * high = 330
low = 14, high = 23, low * high = 322
low = 14, high = 24, low * high = 336
low = 13, high = 24, low * high = 312
low = 13, high = 25, low * high = 325
answer: 13, 25
これは大雑把ですが、ファクタリングの代替手段です。このような 2 つの因数を見つけるための効率的なソリューションは、暗号化で使用される疑似素数を効率的に因数分解できることに注意してください。
通常のケースで因数分解するN
には、簡単なアルゴリズムで から開始し、 で除算p = 2
するかどうかを確認します。そうでない場合は、次の値 (次の整数、または次の素数など) に設定して繰り返します。p
N
p
問題の理想的なケースでは、因子は に近くなりsqrt(N)
ます。したがって、 から始めて、を割るものが見つかるまでp = floor(sqrt(N))
デクリメントできます。p
N
毎回テスト値を減らすとうまくいきます。通常の場合、連続する素数を試すなど、数学的に賢い方法があるかもしれません。素数を因数分解できる場合は、素数で因数分解できます。しかし、あなたの問題では、素数は気にしないので、ここで素数をあまり使用できない可能性があります。
これの名前がわかりません。
Java では、これを他の言語と同じ方法で計算します。
最悪の場合、ステップ 1. は NP であり、ステップ 2 (ブルート フォース) は「のみ」O(F^3)
でF
あることに注意してください。
さらに強引なアプローチは、適切な範囲の数値のペアを反復処理し、それらの積が元の数値であるかどうかをテストすることです。
コーディングとデバッグは、読者の演習として残します :-)