2

整数の三角迷路で最大値のパスを見つけるプログラムを作成する必要があります。

  • このプログラムは、最上部から始まり、ベースのどこかで終わるルートで渡された数値の最大合計を計算する必要があります。
  • 各ステップは、左斜め下または右斜め下のいずれかに進むことができます。
  • 三角形の行数は > 1 ですが <= 100 です。
  • 三角形の数字はすべて整数で、0 ~ 99 です。

機能に問題がありfscanfます。なぜか読めません。このプロジェクトはできるだけ早く期限が切れるので、助けやアドバイスをいただければ幸いです。

迷路の例を次に示します。

30

47 1

35 65 21

0 74 94 58

71 29 34 28 60

97 6 29 19 26 68

37 1 48 98 57 89 64

60 38 33 23 49 57 19 50

4 83 52 47 84 60 16 56 90

19 59 6 10 97 47 96 93 59 50

そして、これは私がこれまでに得たものです:

/#include <stdio.h>
/#include <stdlib.h>
/#define MAX 100

void read    (int maze [][MAX]);
int findPath (int maze[][MAX], int map[][MAX], int size);
void print   (int map [][MAX]);

int main()
{
    int maze [][MAX] = {};
    int map  [][MAX] = {};

    int sum = 0;
    int size = MAX;

    read     (maze);
    findPath (maze, map,size);
    print    (map);

    return;
}

void read (int maze[][MAX])
{
    FILE * mazeFile;
    int num, r, c, count;

    if ((mazeFile = fopen ("t4.txt", "r")) == NULL)
    {
        printf ("Error opening a file\n");
    }
    else
    {
        while (mazeFile != EOF)
        {        
            fscanf (mazeFile, "%d", &maze[r][c]);

            for (r = 0; r < 100 ; r++)
            {
                count = r + 1;
                for (c = 0; c <= count; c++)
                {
                    printf ("(%d, %d) = %d\n",r, c, maze[r][c]);
                }
            }
            fclose (mazeFile);
            return;
        }
    }
}

int findPath (int maze[][MAX], int map[][MAX], int size)
{
    int sum [MAX][MAX] = {0};
    int row, col, maxNum;

    for(row=(size-1); row >= 1; --row)
    {
        for (col-row;col>=1;--col)
        {
            maxNum = (sum[row+1][col] > sum [row+1][col+1] ? col : col + 1);
            sum[row][col]= maze[row][col] + sum [row+1][maxNum];

            map[row][col] = maxNum;
        }
    }  
    return sum [0][0];
}

void print (int map [][MAX])
{
    printf ("(%d, %d) = ", map[0][0], map[0][1]);
    return;
}
4

1 に答える 1

3

まあ:-)たくさんの問題がありますが、あなたが尋ねるのはファイルを読むことなので、今のところそれについて説明します:

一部訂正

  • read最初に, を使用しないでくださいwrite。これらは標準ライブラリ関数であるため、多くの問題が発生します。
  • 関数の戻り値の型として void を使用しないでください。int を使用し、成功時には 0 を返し、失敗時には負の数を返します (これは従来の方法です)。エラーをキャッチするコードを作成するのに役立ちます。
  • コメントを使用して関数を説明してください
  • タブは良いです。少なくとも 4 つのスペース (私はカーネル プログラマーなので、8 つのスペースのタブが好きです) は、午前 2 時 30 分に眠くて答えを見つけようとしているときに役立ちます。
  • 関数内のすべてのステートメントはタブで囲み、{ } と並べてはいけません
  • 適切な規則は、関数本体のみ改行で開始 { を使用し、ifforwhileなどの残りの部分では { をステートメントと同じ行に配置し、終了 } をステートメントの最初の文字に揃えて使用することです。
  • 各ステートメントの間に空白を入れすぎないでください。コードが読みにくくなります。

良いアプローチの例

ファイルを正しく読み取るコードの例を次に示します。

ステップ1:

コンテンツを読み取ってダンプするだけの単純な関数を作成して、READINGが正常であることを確認します。

#include <stdio.h>

/** 
 * @function: read_maze
 * @desc: Reads a maze file and dumps it to stdout, 
 * @return: Returns 0 on success, -1 on failure
 *
 */

int read_maze(const char *filename) 
{
     FILE *fp;
     int entry;

     fp = fopen(filename, "r");
     if ( !fp ) {
          perror(filename); /* prints system error related to
                             * the problem reading mazefile 
                             */
          return -1;
     }

     while(!feof(fp)) {
          if (fscanf(fp, "%d", &entry) == 1) { 
              printf ("%d\n", entry);
          }
     }

     return 0;
}

int main()
{
     if(read_maze("t4.txt")) {
          return -1;
     }

     return 0;
}

ステップ2:

意味のある三角形の迷路配列を作成します。

さて、ファイルを適切に読み取ることができることがわかったので、それを意味のある構造に入れてみます。

たくさんの行 (100) があることがわかっています。最初の行には 1 列、2 番目の行には 2 列、3 番目の行には 3 というように...

つまり、各行にはカーディナリティ (インデックス + 1) と同じ数の列があります。

では、以下のようなものでしょうか。

int row0[1];
int row1[2];
int row2[3];
   .
   .
   .
int row99[100]; 

それはちょっと醜いし、実際にはプログラム的ではありません。これを自動的に行うとよいでしょう。固定数は行数であり、動的割り当てはインデックスに関連付けられていることがわかります。それでは、整数へのポインターの配列を作成しましょう。そして、この配列の各メンバーは、メンバーのカーディナリティと同じ大きさの動的に割り当てられたメモリ ブロックにすることができます。(一口ヘヘ)

#define MAXROWS 100

int *row[MAXROWS]; 

注: 概念的には、MAXROWS は実際にはハードコードされた 0 ~ 99 に対応し、row角かっこ内の配列サイズの宣言部分ではなく、単語の前に貼り付けました。したがって、int row55[56];これは 55 を宣言することです。56 宣言は後で malloc から取得されます。

これで、データ型へのポインターがまさにそれであることがわかりました。つまり、データのメモリ ブロックを指すポインター (基本的には配列として機能する) です。つまり、各行に適切な列を割り当てましょう。

 /* starting from beginning */

 #define MAXROWS 100

 int *rows[MAXROWS];

 int init_triangular_array() 
 {
     int k;
     memset(rows, 0, sizeof(int *)*MAXROWS); /* make the rows array all zeros */
     for (k = 0; k < MAXROWS; k++) {
         rows[k] = (int *)calloc(k+1, sizeof(int)); /* cardinality */
         if( rows[k] == NULL ) {
              fprintf(stderr, "Unable to allocate memory, quoting\n");
              exit(-1); /* just kill the program */
         }
     }
 }

配列を初期化する関数ができたので、配列の使用が終わったら配列を解放する関数も作成しましょう。それはちょうどよいコーディングの練習だからです。

 void free_triangular_array()
 {
     int k;
     for (k = 0; k  < MAXROWS; k++ ) {
         if ( rows[k] ) 
              free(rows[k]);
     }
 }

そして、ファイルからそれを埋める関数を書きましょう:

 int fill_triangular_array(const char *filename)
 {

       FILE *fp = fopen(...);
       int row = 0, col = 0;

       while(!feof(fp)) {
             for (col = 0; col <= row_number; col++ ) {
                   // read an entry as above 
                   rows[row][col] = entry; 
             }
       }
 }

不足しているビットを埋めることができます。

そして、それをすべて使用するために今それをしたら

 int main() 
 {

         init_triangular_array();
         fill_triangular_array();
         /* do something with the array */
         free_triangular_array();

 }
于 2013-05-10T06:48:10.890 に答える