

連日の質問すみません。

テキストファイルから、各列の最大値を読み込み、その読み込んだ最大値の中から最小値を読み込んで出力するプログラムを作成したいのですが、どうすればいいのかがわかりません。

今回のテキストファイルと、現時点でのプログラム、コンパイル結果を以下に示します。

＜テキストファイル(center.txt)＞

[code]

    4
    
    0.0 4.0 5.0 7.0
    4.0 0.0 3.0 3.0
    5.0 3.0 0.0 4.0
    7.0 3.0 4.0 0.0
    
[/code]

<プログラム>

[code]

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    
    const int FNLEN = 50;   /* ファイル名の長さ */
    const int MAX_N = 100;      /* ノード数最大値 */
    
    int main()
    {
        FILE *fp;
        int i, j, nnode;
        
        double dem[MAX_N], dist[MAX_N][MAX_N], wdist[MAX_N][MAX_N],dist2[MAX_N];
        char file_name[FNLEN];  /* データファイル名 */
    
        printf("Data file name: ");
        scanf("%s", file_name);
    
        if ((fp = fopen(file_name,"r")) == NULL){  /* ファイルオープンに失敗した場合は終了 */
            printf("%s: ファイルをオープンできません!\n", file_name);
            return -1;
        }
        printf("データファイル名:   %s\n", file_name);
    
        fscanf(fp,"%d",&nnode);  /* ノード数の読み込み */
    
        if (nnode < 1 || nnode > MAX_N) {
            printf("ノードの数は1以上%3d以下にしてください！\n", MAX_N);
            return -1;
        }
    
        for (i = 0; i < nnode; i++){   /* 距離行列の読み込み */
            for (j = 0; j < nnode; j++){
                fscanf(fp, "%lf", &dist[i][j]);
            }
        }
        fclose(fp);  /* ファイルクローズ */
        for (i = 0; i < nnode; i++) { // 行
            for (j = 0; j < nnode; j++) { // 列
                printf("%.3f ", dist[i][j]);
            }
            printf("\n");
        }
        int max1_index=0,max2_index=0;//各列の最大値
        for (j = 0; j < nnode; j++) {
         for (i = 0; i < nnode; i++) {
           if(dist[i][j]>dist[max1_index][max2_index]){
              max1_index=i;
              max2_index=j;
            }
           }
        }
        int min_index = 0;//各列の最大値の中の最小値(最大値の最小値）
        for (j = 0; j < nnode; j++) {
            if (dist[min_index] > dist[j]) {
                max1_index = j;
            }
        }
        printf("\n\nノードの列番号は %dで、その値は %.3f\n", min_index + 1, dist[max1_index][min_index]);     /* 結果の出力 */
    
        return 0;
    }
    
[/code]

<現時点の実行結果>

[code]

    $ ./a.out
    Data file name: center.txt
    データファイル名:   center.txt
    0.000 4.000 5.000 7.000 
    4.000 0.000 3.000 3.000 
    5.000 3.000 0.000 4.000 
    7.000 3.000 4.000 0.000 
    
    
    ノードの列番号は 1で、その値は 7.000
    
[/code]

<期待する結果>

[code]

    $ ./a.out
    Data file name: center.txt
    データファイル名:   center.txt
    0.000 4.000 5.000 7.000 
    4.000 0.000 3.000 3.000 
    5.000 3.000 0.000 4.000 
    7.000 3.000 4.000 0.000 
    
    
    ノードの列番号は 2で、その値は 4.000
    
[/code]

実行結果を見ていて感じたことは、左から一列目の最大値を求められていることから、あとはすべての列の最大値を求め、そのすべての列の最大値の中の最小値を求めるプログラムを作成したいのですが、どうすればいいのかがわかりませんでした。

どのように実装すればいいのでしょうか。回答よろしくお願いします。


CC BY-SA 4.0
2020-12-24T14:36:41.833
72870
2020-12-25T01:41:57.157
2020-12-25T01:41:57.157
3060
41837
question
c
各列の最大値を求めて、そこから最小値を求めるプログラム


コードを書くことは簡単ですが、  
それだと意味が理解できない可能性があります。  
特に質問者様はおそらくコードの問題というよりもアルゴリズムができていないと見受けれます。  
なのでまず質問者様がやるべきことはコードを書くことよりも頭の中でアルゴリズムをきちんと組み立てることです。  
それができれば、コードに起こすことはそれほど難しくないでしょう。  
逆に、アルゴリズムがわかっていない状態でただコードを提示されても理解は進みません。

なぜアルゴリズムが理解していないかと私が思ったかというと

[code]

    int max1_index=0,max2_index=0;//各列の最大値
    for (j = 0; j < nnode; j++) {
     for (i = 0; i < nnode; i++) {
       if(dist[i][j]>dist[max1_index][max2_index]){
          max1_index=i;
          max2_index=j;
        }
       }
    }
    
[/code]

特にこのコードを見て

> 左から一列目の最大値を求められていることから

というコメントをしていらっしゃいますがまずそもそも認識が違います。  
このコードはすべての数の中の最大値を求めるアルゴリズムです。  
もっといえば最初に現れる最大値を求めるアルゴリズムです。

まずは今のコードが何をしているのかまずはきちんと追ってみましょう。

２次元配列を繰り返している部分はいったん省いて以下だけピンポイントに絞ると

[code]

       if(dist[i][j]>dist[max1_index][max2_index]){
          max1_index=i;
          max2_index=j;
        }
    
[/code]

max1_index及びmax2_indexに保存しているデータよりijのデータが大きければ  
max1_index及びmax2_indexをijに更新するというアルゴリズムです。

これを現実世界に置き換えると  
手元でメモした数字より列から持ってきた数字のほうが大きければメモを書き換えています。  
しかもメモしている数字は一つだけです。  
つまりはすべての数字をチェックして最も大きな数字を一つ持ってくることになります。

ちょいと厳しいですがここが理解できないと次に進めないのでぜひ頑張ってみてください。

理解できた場合は次に進みます。  
さて本当にやらなきゃいけないことは何かというと各列の大きな数字を持ってくる必要がありますね。  
今はメモが一つだけなので一つしか保存できません。つまりメモを各列分用意します。

１列目の最大値のメモ,２列目の最大値のメモ,・・・nnode列目の最大値のメモ

つまりこれも配列でメモを用意するとよいかもしれないですね。nnode分です。  
列を回しながらその列の最大値を該当のN列目の最大値のメモに配列にデータを入れていきます。

次に各列の最大値の中の最小値の求め方ですが、  
もう各列のnnode個の最大値のメモの配列があるので  
ほとんどできているようなもんですね。そのメモの配列を全部確認して最小の値を求めてみてください。

なかなか遠回りの回答ですが、ぜひ理解してご自身で解いてみてください。


CC BY-SA 4.0
2020-12-25T00:54:52.550
72874
2020-12-25T00:54:52.550
22665
72870
answer