получить суб-массив из 2D-массива в C [duplicate]

Это означает, что ваш код использовал ссылочную переменную объекта, которая была установлена ​​в нуль (т. е. она не ссылалась на экземпляр фактического объекта).

Чтобы предотвратить ошибку, объекты, которые могут быть пустыми, должны быть протестированы для null перед тем, как использовать.

if (myvar != null)
{
    // Go ahead and use myvar
    myvar.property = ...
}
else
{
    // Whoops! myvar is null and cannot be used without first
    // assigning it to an instance reference
    // Attempting to use myvar here will result in NullReferenceException
}
0
задан NLed 9 May 2010 в 14:33
поделиться

3 ответа

ОК, поэтому вы хотите прочитать подматрицу размера n x m , начиная с позиций x , y в большой матрице размера p x q . Вам нужно две вещи:

  1. (убедитесь, что x + n & lt; = p и y + m & lt; = 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];
  }
}
5
ответ дан Péter Török 3 September 2018 в 16:20
поделиться

Давайте рассмотрим это поэтапно. Сначала несколько незначительных исправлений для вашего кода:

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

EDIT: Если вы хотите скопировать подматрицу из более крупной матрицы, уже находящейся в памяти, внутренний цикл должен быть

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];
  }
}
2
ответ дан Beta 3 September 2018 в 16:20
поделиться

Хитрость заключается в том, чтобы компилятор рассматривал ваш конкретный элемент массива как отправную точку вашей матрицы; следующий фрагмент кода делает это:

(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
1
ответ дан LKB 3 September 2018 в 16:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: