c言語について質問です。このようにすると実行できなかったのですが対処法はありますか?上の関数は整数の1と自身の数を除いた約数の個数の数、求めたいのはn×10^5までの素数の個数を求めたいです

1件の回答

回答を書く

1094120

2026-01-08 05:20

+ フォロー

if(i=1;1\u0026lt;=n;i++){ 、のところを

if(i=1;i\u0026lt;=n;i++){ 、に修正すれば直ります。



「 1\u0026lt;=n 」だと永久に成り立ち続けるから無限ループになります。

「 i 」と打ち込むべきところを

「 1 」と打ち込んでしまったんでしょうね。



ただし、その修正をしたとしても、当環境で(昔のCore-i5でLinux 32bit版)

例えば n を 9 にした場合、処理時間が約 99 秒も掛かっています。

大したことしてない割りには、処理時間が掛かり過ぎです。

原因は、約数が 0 個でないことがわかった後も、

約数か否か判定してながらカウントし続けているからです。

0 個でないことだけわかればいいのだから個数求めても意味ないでしょう?

処理時間の 9 割がこの無意味な処理をやることに費やしてるのですから、

それをやらないよう、0 個でないとわかった時点で処理を打ち切るべきです。

だたし、

関数の名前が ncd_n のままだと、名前が実際の機能を表さなくなるから、

名前を is_composite 等、実際と合うように変える必要があります。

名前をそう変えて、その関数の中の

「 for(i=1;i\u0026lt;=n;i++){ 」を

「 for(i=2;i\u0026lt;n;i++){ 」に変えて(初期値を2に、\u0026lt;= を \u0026lt; に変えて)、

「 y=-2 」のところを

「 y=0 」に変えて、

「 y=y+1; 」の直後に「break;」の行を入れると、

処理時間が 10分の1 近くまで短くなります。



y=0;

for(i=2;i\u0026lt;n;i++){

if(n%i==0){

y=y+1;

break;

}





■処理時間を短くするのなら、もっと大幅に短くすることができますが

方法をここで説明するのは無理ですから、プログラムだけ載せておきます。

仕様は、質問にあるものと異なり(対象とする数の桁数も遥かに多い)、

1,10,‥,100000000,1000000000,4294967295 以下の個数と出現頻度です。

処理時間は65秒。質問にあるやり方だと、たぶん丸1日掛かっても終わらない。



#include \u0026lt;stdio.h\u0026gt;

#define Size 0x2000

typedef unsigned short ushort;

typedef struct _Cell {

unsigned prmDbl;

unsigned prmMlt;

struct _Cell *pNext;

} TCell;

int main(void){

static TCell *vpCell[0x10000], vCell[Size];

unsigned r, c, n, s;

TCell ppCell, pp, *p;

for (n = 0; n \u0026lt; 0x10000; n++){ vpCell[n] = NULL; }

r = 10; c = 1; n = 0; s = 3;

while (1){

p = NULL;

ppCell = \u0026amp;vpCell[(ushort)(s \u0026gt;\u0026gt; 1)];

while (*ppCell != NULL){

if (s != (*ppCell)-\u0026gt;prmMlt){

ppCell = \u0026amp;((*ppCell)-\u0026gt;pNext);

} else {

p = *ppCell;

*ppCell = p-\u0026gt;pNext;

(p-\u0026gt;prmMlt) += (p-\u0026gt;prmDbl);

pp = \u0026amp;vpCell[(ushort)((p-\u0026gt;prmMlt) \u0026gt;\u0026gt; 1)];

p-\u0026gt;pNext = *pp; *pp = p;

}

}

if (p == NULL){

c++;

if (s \u0026lt; 0x10000){

if (n \u0026gt;= Size){ printf(\u0026quot;Exceeded. %u\
\u0026quot;, s); return 1; }

p = \u0026amp;vCell[n]; n++;

p-\u0026gt;prmDbl = (s \u0026lt;\u0026lt; 1);

p-\u0026gt;prmMlt = s * s;

pp = \u0026amp;vpCell[(ushort)((p-\u0026gt;prmMlt) \u0026gt;\u0026gt; 1)];

p-\u0026gt;pNext = *pp; *pp = p;

}

}

if (s \u0026gt; r - 2){

printf(\u0026quot;%10u : %9u %5.2f%%\
\u0026quot;, r, c, (((double)c) / r) * 100);

fflush(stdout);

if (r \u0026gt;= 0xFFFFFFFF){ break; }

if (r \u0026gt;= 1000000000){ r = 0xFFFFFFFF; } else { r *= 10; }

}

s += 2;

}

return 0;

}



実行した結果はこれ(↓)です(「 _ 」のところは実際は空白)。

________10 : ________4 _40.00%

_______100 : _______25 _25.00%

______1000 : ______168 _16.80%

_____10000 : _____1229 _12.29%

____100000 : _____9592 __9.59%

___1000000 : ____78498 __7.85%

__10000000 : ___664579 __6.65%

_100000000 : __5761455 __5.76%

1000000000 : _50847534 __5.08%

4294967295 : 203280221 __4.73%

うったえる有益だ(0シェアするブックマークする

関連質問

Copyright © 2026 AQ188.com All Rights Reserved.

博識 著作権所有