2

正弦曲線の文字イメージを出力する次のコードがあります。

#include <stdio.h>
#include <math.h>

/**show the image of sine curve*/
main()
{
    double y;
    int m, x;
    for (y = 1; y >= 0; y -= 0.1) {
        m = asin(y) * 10;
        for (x = 1; x < m; x++)
            printf(" ");
        printf("*");
        for (; x < 31 - m; x++)
            printf(" ");
        printf("*\n");
    }
    for (y = 0; y <= 1; y += 0.1) {
        m = 31 + asin(y) * 10;
        for (x = 1; x < m; x++)
            printf(" ");
        printf("*");
        for (; x < 93 - m; x++)
            printf(" ");
        printf("*\n");
    }
}

生成される出力は次のとおりです。

              * *
          * *
        * *
      * *
     * *
    * *
   * *
  * *
 * *
* *
* *
                              * *
                               * *
                                * *
                                 * *
                                  * *
                                   * *
                                    * *
                                     * *
                                       * *
                                         * *
                                             * *

ご覧のとおり、私のコードの結果は連続的ではありません。コードのどこが間違っているか知りたいです。一方で、誰かが私により良い解決策を教えてくれれば幸いです。

4

3 に答える 3

4

正弦波の上半分のコードは、m 個のスペース、アスタリスク、いくつかのスペースx、アスタリスクの順に出力します。数xは、2 番目のアスタリスクの後にm 個のスペースがあり、合計で 31 個のスペースが印刷されるように計算されます。下半分のコードは、上半分がカバーする距離の後に正弦波を継続するために 31 個のスペースを割り当てます。これは、上半分が 33 文字 (31 個のスペースと 2 個のアスタリスク) のフィールドに印刷されるという事実を説明できません。2 番目のループでは、各行の先頭にさらに 2 つのスペースが出力されます。

ノート:

半波長が 10 π になるように波をスケーリングするために、おそらく 31 が選択されました。この場合、上部が 33 文字ではなく 31 文字のフィールドに 2 つのアスタリスクを印刷するように調整された場合、描写はより正確になります。

より正確なのは、分数の文字スペースを考慮して、最も近いスペースにアスタリスクを出力することです。

さらに、発生する丸め誤差に関係なく浮動小数点演算が使用されるため、ループ カウンターが目的どおりに機能するのは偶然です。異なる値を使用すると、ループの反復カウントが必要な数から 1 つずれることがあります。整数値を持つループ カウンターを使用するようにコードを再構成することが望ましいでしょう (ただし、浮動小数点型の場合もあります)。

于 2013-10-23T14:33:30.120 に答える
0

不連続を引き起こしているのは、実際には正弦波の前半だけです。前半全体は左に 2 つのスペースです。本当の解決策は、これらの欠陥に合わせてアルゴリズムを調整し、各象限が正しい位置から始まるようにすることです (Eric P. が詳しく説明しています)。ただし、安価な修正は、(x-position) の最初の値をm右に表示するように調整することから始めて、すべてを右にシフトし、その後スペースを使用して修正を波形全体に伝播することです。

連続性とシフトはこのコードで修正され、コメントは修正が行われた場所を示しています。

#include <stdio.h>
#include <math.h>
/**show the image of sine curve*/
main(){
    double y;
    int m,x;
    for(y=1;y>=0;y-=0.1)
    {
        m=(asin(y)*10) +1;//"+1" to shift right 1
        for(x=1;x<m;x++)  //to get first 11
        {                 //asterisks in sync. spaces used thereafter
            printf(" ");
        }
        printf("*");
        for(;x<32-m;x++) 
        {
            printf(" ");
        }
        printf(" *\n"); //" "1 additional space to shift image right
    }
    for(y=0;y<=1;y+=0.1)
    {
            m=31+asin(y)*10;
            for(x=1;x<m;x++) 
            {
                printf(" ");
            }
            printf("   *"); //2 additional spaces to shift image right
            for(;x<93-m;x++) 
            {
                printf(" ");
            }
            printf("*\n");
    }
    getchar();
}   

*これは、シフトされた連続出力のイメージです: *

ここに画像の説明を入力

于 2013-10-23T15:04:04.970 に答える