0

私は非常に基本的なユーザーであり、Cで使用されるコマンドについてはあまり詳しくないので、ご容赦ください...非常に複雑なコードは使用できません。stdio.hおよびctype.hライブラリについてはある程度の知識がありますが、それだけです。txtファイルにマトリックスがあり、行と列の数の入力に基づいてマトリックスをロードしたい

たとえば、ファイルに5x5のマトリックスがあります。特定の2x2の部分行列を抽出したいのですが、どうすればよいですか?

を使用してネストされたループを作成しました:

FILE *sample
sample=fopen("randomfile.txt","r"); 
for(i=0;i<rows;i++){
  for(j=0;j<cols;j++){
     fscanf(sample,"%f",&matrix[i][j]);
   }
 fscanf(sample,"\n",&matrix[i][j]);
}
fclose(sample);

悲しいことに、コードは機能しません..私がこのマトリックスを持っている場合:

5.00 4.00 5.00 6.00 
5.00 4.00 3.00 25.00 
5.00 3.00 4.00 23.00 
5.00 2.00 352.00 6.00

そして、行に3、列に3を入力すると、次のようになります。

5.00 4.00 5.00
6.00 5.00 4.00
3.00 25.00 5.00

これは2x2のサブマトリックスではないだけでなく、最初の3行と最初の3列が必要な場合でも、正しく印刷されません。

行3と列3から始めて、2行2列の部分行列を取る必要があります。

私はで終わったはずです:

4.00 23.00 
352.00 6.00

これを実現するためにfgetsとsscanfを使用できると聞きました。これが私のトライアルコードです:

fgets(garbage,1,fin);
sscanf(garbage,"\n");

しかし、これも機能しません:(

私は何を間違っているのですか?

助けてください。ありがとう !

4

3 に答える 3

5

さて、サイズp x qの大きな行列の位置x yから始めて、サイズnxm部分行列を読みたいと思います。あなたは2つのものが必要です:

  1. x + n <= pおよびy + m <= qであることを確認します)
  2. 読みたいマトリックスの最初の要素にスキップします。これには、最初に最初のy -1行をスキップする必要があります
  3. 次の行からx -1要素をスキップしてから、 n要素を部分行列に読み込みます。m回繰り返します。

現在の実装では、マトリックスの最初の要素から読み取りを開始し、次に要素を連続してサブマトリックスに読み取ります。更新されたバージョン:

FILE *sample = fopen("randomfile.txt", "r");
// skip the first y-1 rows
for (i = 0; i < y - 1; i++) {
  fscanf(sample, "%*[^\n]\n", &matrix[i][j]);
}
for (i = 0; i < m; i++) {
  // skip the first x-1 numbers
  for (j = 0; j < x - 1; j++) {
     fscanf(sample, "%*f");
  }
  // read n numbers
  for (j = 0; j < n; j++) {
     fscanf(sample, "%f", &matrix[i][j]);
  }
  if (x + n < p) {
    // consume the rest of the line
    fscanf(sample, "%*[^\n]\n");
  }
}
fclose(sample);

更新:代わりに配列から部分行列を読み取るのはさらに簡単で、もう少し計算が必要です。要点は、サイズp x qの行列は、matrix [i、 j ]をarray [i *(j-1)+ j]から読み取ることができるように、サイズp xqの連続した配列に格納できます(約- 1つずつエラーが発生する可能性があり、どちらが列でどちらが行かはわかりませんが、うまくいけば、アイデアが得られます:-)

したがって、コードは次のようになります

for (i = 0; i < m; i++) {
  for (j = 0; j < n; j++) {
     submatrix[i][j] = array[(y + i) * p + x + j];
  }
}
于 2010-05-09T13:50:06.373 に答える
2

これを段階的に見ていきましょう。まず、コードのマイナーな修正をいくつか行います。

for(i=0;i<rows;i++){
  for(j=0;j<cols;j++){
    float dummy;  /* this will make thing easier later */
    fscanf(sample,"%f",&dummy);
    matrix[i][j] = dummy;
  }
/* fscanf(sample,"\n",&matrix[i][j]); this isn't even legal */
}

次に、必要なものを定義します。

int startrow = 2; /* The starting index. Remember we index 0,1,2,3 */
int startcol = 2;
int resultrows = 2; /* How many rows we want in our answer */
int resultcols = 2;
float result[resultrows][resultcols];

今、私たちは望まないものを無視します:

for(i=0;i<rows;i++){
  for(j=0;j<cols;j++){
    float dummy;
    fscanf(sample,"%f",&dummy);
    if(i >= startrow && i < startrow + resultrows &&
       j >= startcol && j < startcol + resultcols){
      matrix[i][j] = dummy;
    }
  }
}

これで、必要な値のみがにコピーされmatrix、残りmatrixは初期化されていないギブリッシュであることに注意してください。result代わりにそれを書いてください:

for(i=0;i<rows;i++){
  for(j=0;j<cols;j++){
    float dummy;
    fscanf(sample,"%f",&dummy);
    if(i >= startrow && i < startrow + resultrows &&
       j >= startcol && j < startcol + resultcols){
      result[i-startrow][j-startcol] = dummy;
    }
  }
}

編集:
すでにメモリにあるより大きなマトリックスからサブマトリックスをコピーする場合、内部ループは次のようになります。

for(j=0;j<cols;j++){
  if(i >= startrow && i < startrow + resultrows &&
     j >= startcol && j < startcol + resultcols){
      result[i-startrow][j-startcol] = matrix[i][j];
  }
}
于 2010-05-09T14:30:31.823 に答える
2

秘訣は、コンパイラに特定の配列要素を行列の開始点として扱わせることです。次のコードスニペットはそれを行います:

(int(*)[SIZE_OF_2ND_DIM])(&a[4][3])

次のプログラムは、意図された目的をキャプチャします。

#include <stdio.h>

int num;

void print( int a[][num], int row, int col )
{
  int i, j;
  for(i = 0; i < row; i++)
  {
    for(j = 0; j < col; j++)
      printf("%3d ", a[i][j]);
    printf("\n");
  }
}


int main()
{
  int a[10][10];
  int i, j;

  for(i = 0; i < 10; i++)
    for(j = 0; j < 10; j++)
      a[i][j] = i*10+j;

  num = 10;
  print(a, 10, 10);

  printf("\n\n");

  print((int(*)[num])(&a[4][3]), 5, 4);

  return 0;
}

対応する出力は次のとおりです。

  0   1   2   3   4   5   6   7   8   9
 10  11  12  13  14  15  16  17  18  19
 20  21  22  23  24  25  26  27  28  29
 30  31  32  33  34  35  36  37  38  39
 40  41  42  43  44  45  46  47  48  49
 50  51  52  53  54  55  56  57  58  59
 60  61  62  63  64  65  66  67  68  69
 70  71  72  73  74  75  76  77  78  79
 80  81  82  83  84  85  86  87  88  89
 90  91  92  93  94  95  96  97  98  99


 43  44  45  46
 53  54  55  56
 63  64  65  66
 73  74  75  76
 83  84  85  86
于 2016-01-06T05:08:13.627 に答える