C言語関係掲示板

過去ログ

No.1127 九九の(組み合わせの)最小公倍数を表示するプログラム

[戻る] [ホームページ]
No.2099

それぞれの最小公倍数を表示するプログラムを作っているのですが
投稿者---azu(2004/06/18 19:06:36)


ちょっと前に、
           <九九計算コード表>
+---+--------------------------------------+
|   |   1   2   3   4   5   6   7   8   9  |
+---+--------------------------------------+
| 1 |   1   2   3   4   5   6   7   8   9  |
| 2 |   2   4   6   8  10  12  14  16  18  |
| 3 |   3   6   9  12  15  18  21  24  27  |
| 4 |   4   8  12  16  20  24  28  32  36  |
| 5 |   5  10  15  20  25  30  35  40  45  |
| 6 |   6  12  18  24  30  36  42  48  54  |
| 7 |   7  14  21  28  35  42  49  56  63  |
| 8 |   8  16  24  32  40  48  56  64  72  |
| 9 |   9  18  27  36  45  54  63  72  81  |
+---+--------------------------------------+



という、九九の計算表を表示するプログラムを(皆さんの協力もあり)作れ
たのですが、今度はここから発展させて それぞれの九九の答えを表示する
のではなく それぞれの九九の(組み合わせの)最小公倍数を表示するプログ
ラムにしたいのです。 プログラムが正しければ、

             <最小公倍数計算コード表>
+---+--------------------------------------+
|   |   1   2   3   4   5   6   7   8   9  |
+---+--------------------------------------+
| 1 |   1   2   3   4   5   6   7   8   9  |
| 2 |   2   2   6   4  10   6  14   8  18  |
| 3 |   3   6   3  12  15   6  21  24   9  |
| 4 |   4   4  12   4  20  12  28   8  36  |
| 5 |   5  10  15  20   5  30  35  40  45  |
| 6 |   6   6   6  12  30   6  42  24  18  |
| 7 |   7  14  21  28  35  42   7  56  63  |
| 8 |   8   8  24   8  40  24  56   8  72  |
| 9 |   9  18   9  36  45  18  63  72   9  |
+---+--------------------------------------+



という 結果が得られるはずなのですが、実行すると"0(数字)"が永久に
表示されていくという結果になってしまいます。
私が作ったプログラムは、

#include<stdio.h>
int main(void)
{int i,x,y;
 printf("\n            <最小公倍数計算コード表>\n+-------------------------------------------+\n");
 printf("|   |");
 for(i = 1;i <= 9;i++)                     
   {printf("%4d",i);                       /* 上部の1〜9までの数字の表示 */
   }
 printf(" |\n+-------------------------------------------+\n");
 for(x = 1;x <= 9;x++)
   {printf("| %d |",x);                     /* 左縦1列の1〜9までの数字の表示 */
   for(y = 1;y <= 9;y++)     
     {while(x * y != 0)                  /* xもしくはyの一方が0になるまで */
       {if(x > y)
     x = x % y;
       else
     y = y % x;
       }       /* lcm(x,y) = x * y / gcd(x,y) という公式より、始めに最大公約数を求める */
     printf("%4d",x * y / (x + y));          /* それぞれの最小公倍数の計算結果の表示 */
     }
   printf("  |\n");
   }
 {printf("+--------------------------------------------+\n");
 } 
 return 0;
}



というものなのです。かなり試行錯誤はしたのですが、おそらく悪い所だら
けだと思います。 その悪い箇所をどのように直したら、上に表示したような
正しい実行結果が得られるのか 教えてください。
プログラム自体(使っている構文など)が 根本的におかしくて 直しようがない
のなら、全てを書き直してもいいので ぜひ 教えてください、お願いします。


No.2100

Re:それぞれの最小公倍数を表示するプログラムを作っているのですが
投稿者---ぽこ(2004/06/18 19:19:36)


過去ログ調べました?


No.2101

Re:それぞれの最小公倍数を表示するプログラムを作っているのですが
投稿者---REE(2004/06/18 19:43:51)


最小公倍数を求める時に、ループ変数でもあるx,yを変更したらまずいのではないですか?

x,yはどちらかが0になっているのですから、x * y / (x+y)を表示したら0でしょうね


No.2107

Re:それぞれの最小公倍数を表示するプログラムを作っているのですが
投稿者---ZAQ(2004/06/19 01:20:05)


#include<stdio.h>
int main(void)
{
    int x,y,i,j;    
    for(i=1;i<10;i++)
    {
        for(j=1;j<10;j++)
        {   
            x=i;y=j;
            do{
                if(i<j){i+=x;}
                else if(i>j){j+=y;}
                if(i==j)break;
            }while(1);
            printf("%4d",i);
            i=x;j=y;
            if(j%9==0)printf("\n");
        }
    }
    return 0;
}

へたですが、わかりやすいと思います。レイアウトは自分で考えてください。
<実行結果>
  1   2   3   4   5   6   7   8   9
  2   2   6   4  10   6  14   8  18
  3   6   3  12  15   6  21  24   9
  4   4  12   4  20  12  28   8  36
  5  10  15  20   5  30  35  40  45
  6   6   6  12  30   6  42  24  18
  7  14  21  28  35  42   7  56  63
  8   8  24   8  40  24  56   8  72
  9  18   9  36  45  18  63  72   9



No.2128

Re:もう一歩のはずなのですが
投稿者---azu(2004/06/21 20:38:47)



   Re:で悪い部分を指摘してくれた皆さん、とてもありがとうございます(返事
が遅くてすみません)。
 特に、とても解りやすく書いて下さった ZAQさんのプログラムを参考にさせ
てもらいました。感謝です。
  本当に情けないのは分かっているのですが、実行結果におけるレイアウトの
表示がうまくいきません。実行すると次のように、縦列が"1"だけ表示されて
残りの"2"〜"9"が表示されないのです。  それと一番下の行が 右側にずれて
表示されるのです(これはプログラムを見ての通り理由は分かっているのです
が、どう直していいのか分かりません)。




          <最小公倍数計算コード表>
+---+--------------------------------------+
|   |   1   2   3   4   5   6   7   8   9  |
+---+--------------------------------------+
| 1 |   1   2   3   4   5   6   7   8   9  |
|   |   2   2   6   4  10   6  14   8  18  |
|   |   3   6   3  12  15   6  21  24   9  |
|   |   4   4  12   4  20  12  28   8  36  |
|   |   5  10  15  20   5  30  35  40  45  |
|   |   6   6   6  12  30   6  42  24  18  |
|   |   7  14  21  28  35  42   7  56  63  |
|   |   8   8  24   8  40  24  56   8  72  |
|   |   9  18   9  36  45  18  63  72   9  |
|   |+---+--------------------------------------+



プログラムはこんな風なんですが、どこを どう直せばいいのでしょうか、教えて
ください。

#include<stdio.h>
int main(void)
{int x,y,i,j;
 printf("\n          <最小公倍数計算コード表>\n+---+--------------------------------------+\n");
 printf("|   |");
 for(x = 1;x <= 9;x++)                     
   {printf("%4d",x);                       /* 上部の1〜9までの数字の表示 */
   }
 printf("  |\n+---+--------------------------------------+\n");
 for(y = 1;y <= 9;y++)
   {printf("| %d |",y);                     /* 左縦1列の1〜9までの数字の表示 */   for(y = 1;y <= 9;y++)         
     for(i = 1;i <= 9;i++) 
       {for(j = 1;j <= 9;j++)
     {x = i;y = j;
     do{if(i < j){i += x;}
     else if(i > j){j += y;}
     if(i == j)break;
     }
     while(1);
     printf("%4d",i);
     i = x;j = y;
     if(j % 9 == 0)printf("  |\n|   |");
     }                
       }             
   {printf("+---+--------------------------------------+\n");
   }   
   return 0;
   }
}




No.2130

Re:もう一歩のはずなのですが
投稿者---かずま(2004/06/21 21:07:57)


> プログラムはこんな風なんですが、どこを どう直せばいいのでしょうか、

そのプログラムは、インデント(字下げ)がいい加減で、読みにくくて仕方が
ありません。それで、次のように書き直してみました。

#include <stdio.h>

int main(void)
{
    int x, y, i, j;

    printf("\n"
           "<最小公倍数計算コード表>\n"
           "+---+--------------------------------------+\n"
           "|   |");
    for (x = 1; x <= 9; x++)    /* 上部の1〜9までの数字の表示 */
        printf("%4d", x);

    printf("  |\n"
           "+---+--------------------------------------+\n");

    for (y = 1; y <= 9; y++) {
        printf("| %d |", y);    /* 左縦1列の1〜9までの数字の表示 */
        for (x = 1; x <= 9; x++) {
            for (i = x, j = y; i != j; )
                if (i < j) i += x;
                else       j += y;
            printf("%4d", i);
        }
        printf("  |\n"
               "+---+--------------------------------------+\n");
    }
    return 0;
}



No.2134

Re:もう一歩のはずなのですが
投稿者---かずま(2004/06/21 22:17:33)


ちょっと勘違いしていました。

        printf("  |\n"
               "+---+--------------------------------------+\n");
    }
    return 0;

を
        printf("  |\n");
    }
    printf("+---+--------------------------------------+\n");
    return 0;

にしてください。



No.2137

Re:もう一歩のはずなのですが
投稿者---azu(2004/06/21 22:33:33)



 こんなに分かりやすくスッキリとしたプログラムになるなんて、、、とても
参考になります。いかに自分のプログラムに無駄が多かったかに 気付かされました。
  ありがとうございます。




No.2131

Re:もう一歩のはずなのですが
投稿者---ぽこ(2004/06/21 21:12:45)


以前azuさんが建てられたスレッドとまったく同じソースコードを利用できるはずですが。。

まず最小公倍数を別関数にしてはどうですか?
そうすると前のスレッドで積を計算していた箇所で関数を呼び出すだけの
変更で済むはずです。


No.2132

Re:もう一歩のはずなのですが
投稿者---ぽこ(2004/06/21 21:15:02)


すみません、日本語がおかしな部分がありました。

>まず最小公倍数を別関数にしてはどうですか?
まず、最小公倍数を求める箇所を別関数にしてはどうですか?


No.2136

Re:もう一歩のはずなのですが
投稿者---ZAQ(2004/06/21 22:28:06)


>まず、最小公倍数を求める箇所を別関数にしてはどうですか?
#include<stdio.h>
int gcd(int i,int j);
void main(void)
{
    int x,i,j;    
    printf("\n"
           "<最小公倍数計算コード表(ユーグリッド互除法バージョン)>\n"
           "+---+--------------------------------------+\n"
           "|   |");
    for (x=1;x<=9;x++)printf("%4d",x);

    printf("  |\n"
           "+---+--------------------------------------+\n");

    for(i=1;i<10;i++)
    {
    printf("| %d |",i); 
        for(j=1;j<10;j++)
        {   
        
                printf("%4d",i*j/gcd(i,j));
        }
    printf("  |\n""+---+--------------------------------------+\n");
    }

}

int gcd(int i,int j)
{
    if(j==0)return i;
    return gcd(j,i%j);
}
/******************************************************
<最小公倍数計算コード表(ユーグリッド互除法バージョン)>
+---+--------------------------------------+
|   |   1   2   3   4   5   6   7   8   9  |
+---+--------------------------------------+
| 1 |   1   2   3   4   5   6   7   8   9  |
+---+--------------------------------------+
| 2 |   2   2   6   4  10   6  14   8  18  |
+---+--------------------------------------+
| 3 |   3   6   3  12  15   6  21  24   9  |
+---+--------------------------------------+
| 4 |   4   4  12   4  20  12  28   8  36  |
+---+--------------------------------------+
| 5 |   5  10  15  20   5  30  35  40  45  |
+---+--------------------------------------+
| 6 |   6   6   6  12  30   6  42  24  18  |
+---+--------------------------------------+
| 7 |   7  14  21  28  35  42   7  56  63  |
+---+--------------------------------------+
| 8 |   8   8  24   8  40  24  56   8  72  |
+---+--------------------------------------+
| 9 |   9  18   9  36  45  18  63  72   9  |
+---+--------------------------------------+
******************************************************/

再帰を使って作りました。あってるのかな〜?とりあえず動きます。
これを覚えておくと複雑なアルゴリズムを簡潔に書けるようになります。したがってプログラムが見やすくなります。




No.2138

Re:もう一歩のはずなのですが
投稿者---azu(2004/06/21 22:50:31)



  なるほど、ぽこさんが 言っているアドバイスの方法が分かってきました。これまた
とっても勉強になります。この解き方も解りやすくて おもしろいですね。
  こんな解き方があったとは、、、勉強不足でした。
  適格な指摘をしてくれた ぽこさん、ここまで詳しく プログラムを教えてくれた
ZAQさん ありがとうございます、感謝です。