質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

4回答

1216閲覧

配列を使用して素数を求める

nanashi_09

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2023/11/09 06:32

編集2023/11/09 06:33

実現したいこと

素数を配列を使って求めたい。
また表示を10の桁ごとに数え、その素数の数だけを’*’で表示させたい。
配列を使用しない場合で素数を求めるプログラムを書くことができたのですが、配列を使うとなると分からなくなってしまいました。

該当のソースコード

ソースコード int main(void) { int i, j; int ture; for (i = 2;i <= 1000;++i) { ture = 0; for (j = 2;j < i;++j) { if (i % j == 0) { ture = 1; break; } } if (ture == 0) { printf("%d\n",i); } } return 0; } ### 試したこと ここに問題に対して試したことを記載してください。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SaitoAtsushi

2023/11/09 07:14

配列を使うというのはどのように使うことを想定していますか? 配列をどのように使えるかわからないという質問なのですか?
jimbe

2023/11/09 07:24

「該当のソースコード」にはソースコードだけを書いてください。
otn

2023/11/09 08:06

> 配列を使うとなると分からなくなってしまいました。 質問ポイントが不明です。 1.Cにおける(あるいはプログラミングにおける)配列とは一体何なのかが理解できてない 2.配列は理解できていて、配列を使ったプログラムは書けるが、「素数を配列を使って求めろ」と言われて、素数と配列の関係が分からない ⇒ この場合は「エラトステネスの篩」を調べましょう 3.素数を求めるときに配列をどのように使うかまでは分かっているが、コードが書けない ⇒ この場合は配列をどのように使おうと思っているかを書きましょう などなど。
nanashi_09

2023/11/09 11:52

配列というものがどのようなものか分かっていないため、配列を使用して書くことができない。
otn

2023/11/09 14:13

> 配列というものがどのようなものか分かっていないため、配列を使用して書くことができない。 基本的なことを学ぶのはQAサイトでは難しいです。 配列とはどういう物かは、多くの人はプログラミング入門書を読むなどで自力で理解します。 あなたが理解できないというのは、どこかで何らかの思い違いなどがあるのだと思いますが、それが何か分からないので、乗り越えさせようが無いわけです。 誰か先生がいるなら相談する。基本的なことが自力で理解できない時は対面で教わるのが一番です)。対面であれば、あなたの理解状況が把握できます。 先生がいない場合は、入門書などで勉強しているのでしょうが、理解できるまで繰り返し読むとかしかないですね。
guest

回答4

0

10ごとに*を表示するだけなら、次のプログラムで実現できます。
「配列を使う」の意味がちがうかも知れませんけど。
出来るだけ簡単なことからやってみると、どんどん理解が深まりますよ!

#include <stdio.h>
#include <string.h>

int main(void) {
int i, j;
int ture;
int kosu=0;
char hosi[32];

memset(hosi,'*',10); for (i = 2;i <= 1000;++i) { ture = 0; for (j = 2;j < i;++j) { if (i % j == 0) { ture = 1; break; } } if (ture == 0) {

/////// printf("%d\n",i);
kosu++;
}

if ( i%10==0 ) { printf("%3d~%3d: %.*s\n",i-9,i,kosu,hosi); kosu=0; } } return 0;

}

投稿2023/11/16 10:31

HidekoSaeki

総合スコア42

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

配列の使い方はいろいろ考えられますが,C99 で導入された「ブーリアン(boolean)型」の配列を用いた記述例を下記に示します。

  • アルゴリズムは エラトステネスの篩 を参考にしました。

  • ブーリアン型配列 is_prime[i] の値(true, false)に「i が素数か否か」の意味を持たせ,この配列の値が( i = 1 〜 N で)正しくなるように計算していきます。

C

1#include <stdio.h> 2#include <stdbool.h> 3#include <math.h> 4 5#define N 1000 6 7int main(void) 8{ 9 bool is_prime[N + 1]; // is_prime[0] is not used 10 int m = sqrt(N + 0.5); // round down to integer 11 int i, j; 12 13 is_prime[1] = false; 14 15 for (i = 2; i <= N; i++) 16 is_prime[i] = true; 17 18 for (i = 2; i <= m; i++) { 19 if (!is_prime[i]) 20 continue; 21 for (j = i * i; j <= N; j += i) 22 is_prime[j] = false; 23 } 24 25 for (i = 1; i <= N; i++) { 26 if (is_prime[i]) 27 printf(" %4d", i); 28 if (i % 10 == 9 || i == N) 29 printf("\n"); 30 } 31 32 return 0; 33}
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 ... 953 967 971 977 983 991 997

投稿2023/11/10 11:34

編集2023/11/10 12:47
little_street

総合スコア437

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

otn さんがコメントでも触れていらっしゃいましたが、まずは「エラトステネスのふるい」法を、とりあえず1から100迄で良いので、自分の手で紙に書いて実践し、理解するところから始めることを強くおすすめします。

とは言え、その理解したアルゴリズムを、配列を使った C プログラムに、どのように落とし込めば良いのか、
また、「表示を10の桁ごとに数え、その素数の数だけを’*’で表示」とはどういう意味なのか、
すでに、かなりの時間考えた末、厚い壁にぶち当たった感覚があるのではないかと思います。
(私も昔はそうでしたから)

そこで、昔使っていた C の記憶を掘り起こして(汗)、「自分だったらこうするかな」というサンプルを書き下ろしてみました。

C

1#include <stdio.h> 2#include <math.h> /* sqrt() */ 3 4#define MAX_PRIME 1000 /* 素数を調べたい上限 */ 5#define IS_PRIME 0 /* 素数である */ 6#define IS_NOT_PRIME ( !IS_PRIME ) /* 素数でない */ 7 8int main( void ) { 9 int primes[ MAX_PRIME ] = { IS_PRIME }; /* まず配列の全ての要素が「素数である」と仮定する */ 10 int sqrt_max_prime = ( int )sqrt( ( float )MAX_PRIME ); /* 「エラトステネスのふるい」では全体の平方根より先を調べる必要が無いのでその停止値をあらかじめ求めておく */ 11 int step; /* ふるいにかけた回数(処理の本筋とは関係無いが「エラトステネスのふるい」の収束の速さを可視化するための変数) */ 12 int check_prime; /* ふるいにかける素数 */ 13 int i, j; 14 15 primes[ 0 ] = primes[ 1 ] = IS_NOT_PRIME; /* 素数の定義により */ 16 17 step = 1; 18 check_prime = 2; /* 最初のふるいは最初の素数を採用する */ 19 while ( check_prime < sqrt_max_prime ) { 20 printf( "step %d, checking prime number = %d\n", step, check_prime ); 21 for ( i = check_prime + check_prime; i < MAX_PRIME; i += check_prime ) { /* ふるいの「次」以降は素数ではない */ 22 primes[ i ] = IS_NOT_PRIME; 23 printf( "%d ", i ); 24 } 25 printf( "\nis not prime\n\n" ); 26 27 check_prime += 1; /* 次のふるいを仮定する */ 28 while ( primes[ check_prime ] == IS_NOT_PRIME ) { /* すでに素数でないものは次のふるいに採用しない */ 29 check_prime += 1; 30 } 31 step += 1; 32 } 33 34 /* 素数を表示 */ 35 printf( "primes is\n" ); 36 for ( i = 0; i < MAX_PRIME; i += 1 ) { 37 if ( primes[ i ] == IS_PRIME ) { 38 printf( "%d ", i ); 39 } 40 } 41 printf( "\n" ); 42 43 /* 表示を 10 の桁ごとに調べ、その素数の数だけを '*' で表示 */ 44 printf( "\nhistogram of primes is\n" ); 45 for ( i = 0; i < MAX_PRIME; i += 10 ) { /* 10 の桁ごとに処理する */ 46 printf( "%6d : ", i ); /* 処理桁を表示 */ 47 for ( j = i; j < i + 10; j += 1 ) { /* 10 の桁ごとの中を全て調べる */ 48 if ( primes[ j ] == IS_PRIME ) { /* それが素数ならば '*' を表示する */ 49 putchar( '*' ); 50 } 51 } 52 printf( "\n" ); 53 } 54 55 return 0; 56}

(11行目の step 変数宣言、20行目、23行目、25行目の printf( )、31行目の step 加算は、「エラトステネスのふるい」法が、いかに収束の早いアルゴリズムであるかを示すためのもので、削除しても動作には問題ありません;ちなみに 4行目の 1000 を 10000 にしても、たいした処理ステップにはなりません)

特に、サンプルの 18行目から 32行目までを、よくご覧下さい。 この部分が、「エラトステネスのふるい」を、私なりに忠実に C で書き表したものです。

紙に1から100までの「領域」と、変数 check_prime の「領域」と、変数 i の「領域」を書いて、
そして変数 sqrt_max_prime の「領域」には、100のルート、つまり 10 を書き込んでおいてから、
「自分がコンピューターになったつもりで」、紙と鉛筆(シャーペン)と消しゴムを使い、このプログラムを「頭と手で」1行ずつ、ていねいに実行してみてください。
まさに「エラトステネスのふるい」の動作そのものだ、という感じがしたと思いますが、いかがでしょうか……。

さて、これで素数は求まりましたが、次の問題である「表示を10の桁ごとに数え、その素数の数だけを’*’で表示」が待っています。
これはサンプルの 44~53行目が相当します。
「10の桁ごとに」というのは、おそらく、00台、10台、20台、30台、40台、50台、60台、70台、80台、90台、100台、110台、……ごとに、という事だと私は解釈しました。 つまりこれは「『10 ごとの素数の個数』の度数分布を表示せよ」ということでしょう。

そうと決まればプログラミングはさほど難しくありません。 10台ごとに処理するループを回して、1ループの中で 0~9 の10個について、それぞれ素数かどうか判定し、素数なら '*' を表示するだけです。
もちろん 10台ごとの改行を忘れてはいけません。
これで度数分布表(ヒストグラム)の完成です。

以上、ご参考になれば幸いです。

投稿2023/11/09 20:00

kurai

総合スコア85

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

表示を10の桁ごとに数え、その素数の数だけを’*’で表示させたい。

この記述の意味がわかりませんでした。以下を理解して書き直すとよいのではないでしょうか。

c

1#include <stdio.h> 2#define MAX_PRIME 1000 3 4int main(void) { 5 int primes[MAX_PRIME] = {0}; 6 int i, j, cnt = 2, isprime; 7 primes[0] = 2; 8 primes[1] = 3; 9 printf("%d\n", primes[0]); 10 printf("%d\n", primes[1]); 11 12 for (i = 5; i <= MAX_PRIME; i += 2) { 13 isprime = -1; 14 15 for (j = 1; j < cnt && primes[j] * primes[j] <= i; j++) { 16 if (i % primes[j] == 0) { 17 isprime = 0; 18 break; 19 } 20 } 21 22 if (isprime) { 23 printf("%d\n", i); 24 primes[cnt++] = i; 25 } 26 } 27 28 return 0; 29}

投稿2023/11/09 12:26

編集2023/11/09 12:48
bboydaisuke

総合スコア5339

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nanashi_09

2023/11/09 12:58

ありがとうございます。自分なりに考えてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問