1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RiSTAdvent Calendar 2024

Day 20

素因数分解開発録 カイジ

Posted at

c言語を使って素因数分解をしてもらいます
手順はまあ

1.素因数分解してほしい数字を入力

2.素数で割る

3.素因数を表示

こんなもんでしょう。
一旦書いてみます

prime_proto.c
#include <math.h>
#include <stdio.h>
int main() {
    int n = 0, p2 = 0, p3 = 0, p5 = 0, p7 = 0;  // その素因数で何回割れるかの変数
    scanf("%d", &n);                            // 素因数分解する数字を入力
    do {                                        // 実際に素因数分解するパート
        if (n % 2 == 0) {
            do {
                n = n / 2;
                p2++;
            } while (n % 2 == 0);
        }
        if (n % 3 == 0) {
            do {
                n = n / 3;
                p3++;
            } while (n % 3 == 0);
        }
        if (n % 5 == 0) {
            do {
                n = n / 5;
                p5++;
            } while (n % 5 == 0);
        }
        if (n % 7 == 0) {
            do {
                n = n / 7;
                p7++;
            } while (n % 7 == 0);
        }
    } while (n != 1);
    printf("2^%d*3^%d*5^%d*7^%d", p2, p3, p5, p7);  // 結果を表示
}

できた😊
動かしてみようぜ

結果 child_of_god@MacBook:~/freespace_C$ gcc prime_proto.c -o prime_proto child_of_god@MacBook:~/freespace_C$ ./prime_proto 12 2^2*3^1*5^0*7^0child_of_god@MacBook:~/freespace_C$
どうですか? 問題点は山積み。

問題点

1. 見づらい

2. 対応範囲がバカ狭い

3. 素因数でない数字も表示される

一個ずつ解決していきます

1. 見づらい

これはまあすぐに解決

2^2*3^1*5^0*7^0child_of_god@MacBook:~/freespace_C$
        ↑
    ここに改行がない!
これは最後にputs("");を入れて解決。

2. 対応範囲がバカ狭い

これもすぐに解決

p2 = 0, p3 = 0, p5 = 0, p7 = 0;

ここの変数を配列にすればいいのでは?

int p[100];

それに伴って

 do {                                        // 実際に素因数分解するパート
        if (n % 2 == 0) {
            do {
                n = n / 2;
                p2++;
            } while (n % 2 == 0);
        }
        if (n % 3 == 0) {
            do {
                n = n / 3;
                p3++;
            } while (n % 3 == 0);
        }
        if (n % 5 == 0) {
            do {
                n = n / 5;
                p5++;
            } while (n % 5 == 0);
        }
        if (n % 7 == 0) {
            do {
                n = n / 7;
                p7++;
            } while (n % 7 == 0);
        }
    } while (n != 1);

の部分も素数の配列(とりあえず二桁まで)

int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,73,79,83,89,97};

と配列prime[]の要素数

pnumber = sizeof(prime) / sizeof(prime[0]) //c言語の配列の要素数の出し方

を使うことによって

 do {
        for (int i = 0; i < pnumber; i++)  // 実際に素因数分解するパート
            if (n % prime[i] == 0) {
                do {
                    n = n / prime[i];
                    p[i]++;
                } while (n % prime[i] == 0);
            }
    } while (n != 1);

に書き換えれば対応範囲も大幅アップ。

3. 素因数でない数字も表示される

2^2*3^1*5^0*7^0child_of_god@MacBook:~/freespace_C$

5と7が素因数じゃないのに表示されています。
さっき使う素因数を増やしたのでこれは大問題
現状の結果を表示するコードは

printf("2^%d*3^%d*5^%d*7^%d", p2, p3, p5, p7);  // 結果を表示

これなのでまずは問題点2の改善に合わせて書き換える

素因数^個数*

のブロックを配列prime[]の要素数(=pnumber)だけ表示すればいいので

for (int i = 0; i < pnumber; i++) {  // 結果を表示
        printf("%d^%d*", prime[i], p[i]);
    }

でもこれで実行しちゃうと

12
2^2*3^1*5^0*7^0*11^0*13^0*17^0*19^0*23^0*29^0*31^0*37^0*41^0*43^0*47^0*53^0*59^0*61^0*67^0*71^0*73^0*79^0*73^0*79^0*83^0*89^0*97^0*

こうなっちゃうよね~ 修正していきます。

素因数^個数*

の個数の部分が0なら表示しないようにすればよいので

for (int i = 0; i < pnumber; i++) {  // 結果を表示
        if (p[i] != 0) {
            printf("%d^%d*", prime[i], p[i]);
        }
    }

これでいいのでは?
解決
これで問題点はすべて解決しました
これがver2だ

prime_proto_ver2.c
#include <math.h>
#include <stdio.h>
int main() {
    int n = 0, p[100], prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 73, 79, 83, 89, 97}, pnumber = sizeof(prime) / sizeof(prime[0]) /*c言語の要素数の出し方*/;  // その素因数で何回割れるかの変数
    scanf("%d", &n);                                                                                                                                                                                              // 素因数分解する数字を入力
    do {
        for (int i = 0; i < pnumber; i++)  // 実際に素因数分解するパート 改善点2
            if (n % prime[i] == 0) {
                do {
                    n = n / prime[i];
                    p[i]++;
                } while (n % prime[i] == 0);
            }
    } while (n != 1);
    for (int i = 0; i < pnumber; i++) {  // 結果を表示 改善点3
        if (p[i] != 0) {
            printf("%d^%d*", prime[i], p[i]);
        }
    }
    puts("");  // 改善点1
}

さあ動作確認

結果

child_of_god@MacBook:~/freespace_C$ ./prime_proto_ver2
143
11^1*13^1*
child_of_god@MacBook:~/freespace_C$

動いた!!

ちゃんと問題点も全部修正出来ました
今後ももっとアップグレードしていきます。

part1 おわり

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?