回答編集履歴

6

ikadzuchiさんからの引用

2020/06/08 03:32

投稿

skytomo
skytomo

スコア35

test CHANGED
@@ -128,7 +128,9 @@
128
128
 
129
129
  と思ったのかもしれません.
130
130
 
131
- しかし,この**if文の条件文が計算量の多い計算を含んでいるので,すごい時間がかかっているのです.**
131
+ しかし,この**if文の条件文が計算量の多い計算を含んでいるので,すごい時間がかかっている**のです.
132
+
133
+ ikadzuchiさんのおっしゃるとおり,除算や剰余はたいへん遅い処理なのです…
132
134
 
133
135
 
134
136
 

5

見出しを付けた

2020/06/08 03:31

投稿

skytomo
skytomo

スコア35

test CHANGED
@@ -1,3 +1,7 @@
1
+ ## 結論
2
+
3
+
4
+
1
5
  hnk_llさんのソースコードが以下の通りですね.
2
6
 
3
7
 
@@ -88,6 +92,8 @@
88
92
 
89
93
 
90
94
 
95
+ ## 解説1:なぜ従来の手法が遅いのか
96
+
91
97
  従来の手法ですと,
92
98
 
93
99
  ```c
@@ -116,23 +122,43 @@
116
122
 
117
123
  緑の部分がfor文の中で回っている部分です.
118
124
 
119
- if文で計算量を減していると思われますが
125
+ 質問者のhnk_llさんはおそ
120
126
 
121
- if文条件文自体が計算量多い計算含んでいるので,
127
+ if文条件を絞って,エラトステネス実装しよう」
122
128
 
129
+ と思ったのかもしれません.
130
+
123
- すごい時間がかかってします.無駄もあります.
131
+ しかし,の**if文の条件文が計算量の多い計算を含んいるので,すごい時間がかかっているのです.**
124
132
 
125
133
 
126
134
 
135
+ ## 解説2:どのように改善すればよいか
136
+
137
+
138
+
139
+ さて,どのように改善すれば速くなるかということですが,
140
+
127
- ,もっと速くるためには
141
+ このif文を使わずに実装ることです
142
+
143
+
144
+
145
+ 具体的には,
128
146
 
129
147
  i = 2のとき,j = 4 6 8 10 12 ...のときにbox[j]を0にし,
130
148
 
131
149
  i = 3のとき,j = 6 9 12 15 18 ...のときにbox[j]を0にし…
132
150
 
133
- というふうにiの倍数(ただし1倍を除く)でif文をるようにします.
151
+ というふうにiの倍数(ただし1倍を除く)のときだけfor文をるようにします.
152
+
153
+ そうすればif文は不要になります.
134
154
 
135
155
  ![改善策](61ab18131a66defa81c0540db1ed4a5a.png)
156
+
157
+ 画像だとこうなります.(緑の部分がfor文の中で回っている部分です.)
158
+
159
+ 緑の部分が減りましたね!
160
+
161
+
136
162
 
137
163
  それが
138
164
 
@@ -149,5 +175,3 @@
149
175
  ```
150
176
 
151
177
  というふうにすれば速くなる理由です.
152
-
153
- そしてこれが本来でいうところの「エラトステネスの篩」ですね.

4

画像を追加

2020/06/08 03:24

投稿

skytomo
skytomo

スコア35

test CHANGED
@@ -108,13 +108,17 @@
108
108
 
109
109
  しかし,これだと,無駄が多いです.
110
110
 
111
- というのも
111
+ というのも,下の画像を見てみてください.
112
112
 
113
- i = 2とき,j = 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 ...をif文で判定し,
113
+ ![従来手法](7508a3fad6116211c2e00584ed96bc13.png)
114
114
 
115
- i = 3とき,j = 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 ...をif文で判定し…
115
+ 画像は従来の手法でした場合のforの中回っている部分です.
116
116
 
117
+ 緑の部分がfor文の中で回っている部分です.
118
+
119
+ if文で計算量を減らしていると思われますが,
120
+
117
- というふうにもう素数ではないとさっき判定した数の多くが再びif文を通ってますね.
121
+ if文の条件文自体が計算量の多い計算含んでるので,
118
122
 
119
123
  これではすごい時間がかかってしまいます.無駄もあります.
120
124
 
@@ -128,7 +132,7 @@
128
132
 
129
133
  というふうにiの倍数(ただし1倍を除く)でif文を通るようにします.
130
134
 
131
-
135
+ ![改善策](61ab18131a66defa81c0540db1ed4a5a.png)
132
136
 
133
137
  それが
134
138
 
@@ -145,3 +149,5 @@
145
149
  ```
146
150
 
147
151
  というふうにすれば速くなる理由です.
152
+
153
+ そしてこれが本来でいうところの「エラトステネスの篩」ですね.

3

box[j]を0にするという記述を追加・変更

2020/06/08 03:11

投稿

skytomo
skytomo

スコア35

test CHANGED
@@ -104,7 +104,7 @@
104
104
 
105
105
  ```
106
106
 
107
- の部分で,j を1ずつ増やして,`j % i == 0 && box[j] == 0`が真のとき(つまり素数でないとき)に配列の中身を0にしていますね.
107
+ の部分で,j を1ずつ増やして,`j % i == 0 && box[j] == 0`が真のとき(つまり素数でないとき)にbox[j]を0にしていますね.
108
108
 
109
109
  しかし,これだと,無駄が多いです.
110
110
 
@@ -122,9 +122,9 @@
122
122
 
123
123
  ですので,もっと速くするためには
124
124
 
125
- i = 2のとき,j = 4 6 8 10 12 ...
125
+ i = 2のとき,j = 4 6 8 10 12 ...のときにbox[j]を0にし,
126
126
 
127
- i = 3のとき,j = 6 9 12 15 18 ...
127
+ i = 3のとき,j = 6 9 12 15 18 ...のときにbox[j]を0にし…
128
128
 
129
129
  というふうにiの倍数(ただし1倍を除く)でif文を通るようにします.
130
130
 

2

ifのくだりを修正

2020/06/08 02:52

投稿

skytomo
skytomo

スコア35

test CHANGED
@@ -122,9 +122,9 @@
122
122
 
123
123
  ですので,もっと速くするためには
124
124
 
125
- i = 2のとき,j = 4 6 8 10 12 ...をif文で判定し,
125
+ i = 2のとき,j = 4 6 8 10 12 ...
126
126
 
127
- i = 3のとき,j = 6 9 12 15 18 ...をif文で判定し…
127
+ i = 3のとき,j = 6 9 12 15 18 ...
128
128
 
129
129
  というふうにiの倍数(ただし1倍を除く)でif文を通るようにします.
130
130
 

1

文章の小さな修正

2020/06/08 02:45

投稿

skytomo
skytomo

スコア35

test CHANGED
@@ -104,7 +104,7 @@
104
104
 
105
105
  ```
106
106
 
107
- の部分で,j を1ずつ増やして,`j%i==0&&box[j]==0`(つまり素数でないときに配列の中身を0にしていますね.
107
+ の部分で,j を1ずつ増やして,`j % i == 0 && box[j] == 0`が真のとき(つまり素数でないときに配列の中身を0にしていますね.
108
108
 
109
109
  しかし,これだと,無駄が多いです.
110
110
 
@@ -122,11 +122,13 @@
122
122
 
123
123
  ですので,もっと速くするためには
124
124
 
125
- i = 2のとき,j = 4 6 8 10 12...
125
+ i = 2のとき,j = 4 6 8 10 12 ...をif文で判定し,
126
126
 
127
- i = 3のとき,j = 6 9 12 15 18...
127
+ i = 3のとき,j = 6 9 12 15 18 ...をif文で判定し…
128
128
 
129
129
  というふうにiの倍数(ただし1倍を除く)でif文を通るようにします.
130
+
131
+
130
132
 
131
133
  それが
132
134