簡體   English   中英

如何從更大的矩陣中提取2x2子矩陣

[英]How to extract a 2x2 submatrix from a bigger matrix

我是一個非常基本的用戶,對C語言中使用的命令不太了解,所以請多多包涵...我不能使用非常復雜的代碼。 我在stdio.h和ctype.h庫中有一些知識,但是僅此而已。 我在txt文件中有一個矩陣,我想根據我輸入的行數和列數來加載矩陣

例如,我在文件中有一個5 x 5的矩陣。 我想提取特定的2 x 2子矩陣,該怎么辦?

我使用以下方法創建了一個嵌套循環:

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

不僅這不是2 x 2的子矩陣,而且即使我想要前3行和前3列,它也無法正確打印。

我需要從第3行和第3行開始,然后取2 by 2子矩陣!

我本來應該以:

4.00 23.00 
352.00 6.00

聽說可以使用fgets和sscanf來完成此操作。 這是我的試用代碼:

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

但這也不起作用:(

我究竟做錯了什么 ?

請幫忙。 謝謝 !

好的,因此您想讀取大小為n x m的子矩陣,從大小為p x q的大矩陣中的位置xy開始。 您需要兩件事:

  1. (驗證x + n <= py + 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的矩陣可被存儲在大小p X q的連續陣列,使得矩陣[I,J]可從陣列中讀取[I *(J-1)+ j]的(約-可能會有一個錯誤的錯誤,我不確定是哪一列,哪一行是行,但是希望您能理解:-)

所以代碼會像

for (i = 0; i < m; i++) {
  for (j = 0; j < n; j++) {
     submatrix[i][j] = array[(y + i) * p + x + j];
  }
}

讓我們分階段進行。 首先,對您的代碼進行了一些次要的修復:

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];
  }
}

訣竅是使編譯器將您特定的數組元素視為矩陣的起點。 以下代碼段可以做到這一點:

(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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM