回答編集履歴

1

回答

2015/02/10 04:44

投稿

argius
argius

スコア9390

test CHANGED
@@ -1 +1,139 @@
1
1
  `bigIntSqrt`で時間がかかっているのではないでしょうか。`bigIntSqrt`の実装を教えてください。
2
+
3
+
4
+
5
+ ---
6
+
7
+
8
+
9
+ (回答)
10
+
11
+
12
+
13
+ `BigInteger`のインスタンスを取得する際に、`new BigInteger(String)`を使わずに`BigInteger.valueOf(long)`を使ったほうがパフォーマンスが良いです。また、何度も使う値は毎回`new`せずに、定数にしましょう。
14
+
15
+
16
+
17
+ それ以外にも、こんな感じでメソッドを作って置き換えると、コードの見通しが良くなります。
18
+
19
+
20
+
21
+ 計算結果があっているかどうかは確認できていません。
22
+
23
+
24
+
25
+ ```lang-java
26
+
27
+ // Java5以降
28
+
29
+
30
+
31
+ import static java.math.BigInteger.*; // ZERO, ONE
32
+
33
+ import java.math.BigInteger;
34
+
35
+ import java.util.Arrays;
36
+
37
+ import java.util.List;
38
+
39
+
40
+
41
+ public final class App {
42
+
43
+
44
+
45
+ static final BigInteger TWO = BigInteger.valueOf(2);
46
+
47
+ static final BigInteger THREE = BigInteger.valueOf(3);
48
+
49
+ static final BigInteger FIVE = BigInteger.valueOf(5);
50
+
51
+ static final BigInteger SEVEN = BigInteger.valueOf(7);
52
+
53
+ static List<BigInteger> smallPrimeNumbers = Arrays.asList(TWO, THREE, FIVE, SEVEN);
54
+
55
+
56
+
57
+ public static boolean isSosuuNum(BigInteger x) {
58
+
59
+ if (isNotDivisible(x, TWO) && isNotDivisible(x, THREE) && isNotDivisible(x, FIVE) && isNotDivisible(x, SEVEN)
60
+
61
+ && x.equals(ONE)) {
62
+
63
+ for (BigInteger bN = bigIntSqrt(x); bN.compareTo(ONE) > 0; bN = bN.subtract(ONE)) {
64
+
65
+ if (isDivisible(x, bN)) {
66
+
67
+ break;
68
+
69
+ }
70
+
71
+ else if (bN.equals(TWO)) {
72
+
73
+ return true;
74
+
75
+ }
76
+
77
+ }
78
+
79
+ }
80
+
81
+ else if (smallPrimeNumbers.contains(x)) {
82
+
83
+ return true;
84
+
85
+ }
86
+
87
+ return false;
88
+
89
+ }
90
+
91
+
92
+
93
+ private static BigInteger bigIntSqrt(BigInteger x) {
94
+
95
+ BigInteger div = ZERO.setBit(x.bitLength() / 2);
96
+
97
+ BigInteger div2 = div;
98
+
99
+ for (;;) {
100
+
101
+ BigInteger y = div.add(x.divide(div)).shiftRight(1);
102
+
103
+ if (y.equals(div) || y.equals(div2)) {
104
+
105
+ return y;
106
+
107
+ }
108
+
109
+ div2 = div;
110
+
111
+ div = y;
112
+
113
+ }
114
+
115
+ }
116
+
117
+
118
+
119
+ static boolean isDivisible(BigInteger a, BigInteger b) {
120
+
121
+ return a.mod(b).equals(ZERO);
122
+
123
+ }
124
+
125
+
126
+
127
+ static boolean isNotDivisible(BigInteger a, BigInteger b) {
128
+
129
+ return !a.mod(b).equals(ZERO);
130
+
131
+ }
132
+
133
+
134
+
135
+ }
136
+
137
+ ```
138
+
139
+