- ベストアンサー
二重ループを使うプログラムについて(C言語)
素因数分解するプログラムで、例えば360を入力したとき、 2^3 * 3^2 * 5^1 と表示するプログラムを作りたいのですが、scanfとprintfの部分は分かるのですが、肝心の二重ループの部分が分かりません…。 最後に*が表示されないようにするというのが条件なのですが、初心者で慣れてないので、詳しく教えていただけないでしょうか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
質問の fig()関数なんですけど、これって、ぜんぜん初心者向きじゃないですね。もっと簡単な方法もあるのでしょうけれど...。 素因数分解をひとつの文字列として出力した関係から、その文字列をそのまま使ってプログラムしてみました。したがって、プログラムはバイト操作の内容となっていますので、ご了解ください。 なお、「二重ループの部分」がわからないとのことですが、一重で済んでいます。ソースをじっくり読んでいただければと思います。ポインターの勉強には良いかと。 /* Making figure program by Mac OSX * file name: tigen.c * compile: gcc tigen.c * execution: ./a.out */ #include <stdio.h> #define SIZE 256 #define SEPARATER '*' char buf[SIZE], form[SIZE], mark[2]; /* プロトタイプ宣言 */ void prime(int); void fig(void); char *compare(char *, char *); int main(void) { int n; /* 初期値設定 */ mark[0] = SEPARATER; mark[1] ='\0'; /* 数値の入力 */ printf("整数を入力してください。"); scanf("%d", &n); /* 素因数分解 */ prime(n); printf("\tf(%d) = %s ", n, buf); /* 数式の生成 */ fig(); printf("= %s\n", form); return 0; } void prime(int n) { int m; char *j; j = buf; for (m = 2; n != 1; m++) { while(n % m == 0) { n /= m; j += sprintf(j, "%d%s", m, mark); } } *(j - 1) = '\0'; } void fig(void) { char *p, *key, *j, *temp; int count; key = p = buf; // 素因数分解の文字列を直接解析 j = form; count = 1; do { while (*(++p) && *p != SEPARATER); *p++ = '\0'; temp = compare(key, p); if (temp == p) { // キーと次数が違う場合 if (key != buf) j += sprintf(j, " %s ", mark); j += (count == 1 ? sprintf(j, "%s", key) : sprintf(j, "%s^%d", key, count)); count = 1; key = temp; } else { // キーと次数が同じ場合 if (*temp >= '0' && *temp <= '9') { // 次数が異なるとき while(*temp >= '0' && *temp <= '9') temp--; if (count == 1) j += (count == 1 ? sprintf(j, "%s", key) : sprintf(j, "%s^%d", key, count)); count = 1; key = temp + 1; } else // 次数が同じとき count += 1; } } while (*p); // 文字列の終わりまで } char *compare(char *a, char *b) { char *temp; temp = b; while (*a == *b && *a) { a++; b++; } return *a ? temp : b; }
その他の回答 (3)
- titokani
- ベストアンサー率19% (341/1726)
まずは、 2 2 2 3 3 5 と表示するプログラムを作ることを考えましょう。 それができてから、 2^3 * 3^2 * 5^1 と、表示すること考えるのが、考えやすいと思います。
- foofoo0
- ベストアンサー率42% (39/92)
入力された数を素数の小さい方から割切れるあいだ割っていき、割れなくなったら次の素数で割るということを繰り返して、答えが素数になったら終了すればよいのでは? *を出力するのはどういう条件のときかを考えればよいのでは?
- Tacosan
- ベストアンサー率23% (3656/15482)
(プログラムじゃなくて) あなたが「紙と鉛筆と頭と手」でこの問題に取り組むとしたら, どうしますか? ちなみに「最後に*が表示されないようにする」と解釈してもいいし「最初に * が表示されないようにする」と解釈してもいい.