How to extract a 2x2 submatrix from a bigger matrix

后端 未结 3 769
醉话见心
醉话见心 2020-12-22 12:16

I am a very basic user and do not know much about commands used in C, so please bear with me...I cant use very complicated codes. I have some knowledge in the stdio.h and ct

相关标签:
3条回答
  • 2020-12-22 13:09

    The trick is to make the compiler treat your specific array element as the starting point of your matrix; the following code snippet does that:

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

    The following program captures the intended purpose:

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

    Here is the corresponding output:

      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
    
    0 讨论(0)
  • 2020-12-22 13:12

    OK, so you want to read a submatrix of size n x m, starting at positions x, y in the big matrix of size p x q. You need two things:

    1. (verify that x + n <= p and y + m <= q)
    2. skip to the first element of the matrix you want to read. This requires first skipping the first y - 1 rows
    3. skip x - 1 elements from the next row, then read n elements into your submatrix. Repeat m times.

    Your current implementation starts reading from the very first element of the matrix, then reads elements contiguously into the submatrix. An updated version:

    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);
    

    Update: to read the submatrix from an array instead is even simpler, just requires a bit more calculation. The gist is, a matrix of size p x q can be stored in a contiguous array of size p x q such that matrix[i,j] can be read from array[i*(j-1)+j] (approximately - there may be off-by-one errors and I am never sure which is the column and which is the row, but hopefully you get the idea :-)

    So the code would be something like

    for (i = 0; i < m; i++) {
      for (j = 0; j < n; j++) {
         submatrix[i][j] = array[(y + i) * p + x + j];
      }
    }
    
    0 讨论(0)
  • 2020-12-22 13:19

    Let's take this in stages. First a couple of minor fixes to your code:

    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 */
    }
    

    Now we define what we want:

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

    Now we ignore what we don't want:

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

    Notice that now only the values we want are copied into matrix, the rest of matrix is uninitialized gibberish. Now write it into result instead:

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

    EDIT:
    If you want to copy a submatrix from a larger matrix already in memory, the inner loop should be

    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];
      }
    }
    
    0 讨论(0)
提交回复
热议问题