2010-05-09 5 views
0

Я очень простой пользователь и мало знаю о командах, используемых в C, поэтому, пожалуйста, несите меня ... Я не могу использовать очень сложные коды. У меня есть некоторые знания в библиотеках stdio.h и ctype.h, но об этом. У меня есть матрица в txt-файле, и я хочу загрузить матрицу на основе ввода числа строк и столбцов.Как извлечь подматрицу 2x2 из большей матрицы

Например, у меня есть матрица размером 5 на 5. Я хочу извлечь конкретную подматрицу 2 на 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 по 2 подматрицы, но даже если бы я хотел первые 3 строки и первые 3 столбцы, его не печатают правильно ....

Мне нужно начинать со строки 3 и col 3, а затем взять подпрограмму 2 на 2!

я должна была закончиться с:

4.00 23.00 
352.00 6.00 

Я слышал, что я могу использовать fgets и sscanf для достижения этой цели. Вот мой пробный код:

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

Но это не работает либо :(

Что я делаю неправильно

Пожалуйста, помогите Спасибо

+1

Почему вы удалите этот вопрос в последний раз вы отправили его? http://stackoverflow.com/questions/2796071/how-to-extract-a-submatrix-from-a-matrix. Если вы удалите свои вопросы, это уменьшит вероятность того, что люди захотят добавить время, чтобы дать хорошие ответы. –

+1

У меня была ошибка в вопросе, мне нужна подматрица 2by2 (ошибка с моей стороны) – NLed

+0

В будущем, если в вашем вопросе есть ошибка, вам лучше всего исправить это, вместо того чтобы сделать совершенно новое сообщение. – dbyrne

ответ

4

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

  1. (Убедитесь, что х + п < = р и у + м < = д)
  2. перейти к первому элементу которую вы хотите прочитать. Это требует первого пропуск первого Y - 1 строку
  3. пропуск х - 1 элементы из следующей строки, а затем прочитать п элементов в вашу подматрицу. Повтор м раз.

Ваша текущая реализация начинает отсчет с самого первого элемента матрицы, а затем читает элементы смежно в подматрицу. Обновленная версия:

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: прочитать подматрицы из массива вместо еще проще, просто требует немного больше вычислений. Суть в том, матрица размером р х д могут быть сохранены в виде непрерывного массива размером р х д таким образом, что матрица [I, J] можно считать из массива [я * (j- 1) + j] (примерно - возможны ошибки, и я никогда не уверен, что такое столбец, а какая строка, но, надеюсь, вы получите эту идею :-)

Таким образом, код будет что-то вроде

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

Спасибо, что ответили. Что, если матрица 50x25. Я собираюсь использовать строку или столбец для сравнения? n = 2, x + 2 <50 или x + 2 <25? – NLed

+0

@ZaZu, только что обновили размеры для общего корпуса. –

+0

Большое спасибо, мой код оказался несколько схожим, но у меня была ошибка забыть прочитать его в новой матрице. У меня есть вопрос, хотя, если большая матрица не является частью файла? Что делать, если пользователь вводит матрицу в массив, а затем должен извлечь из нее подматрицу. Как изменится синтаксис scanf? – NLed

1

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

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

Большое спасибо за то, что вы тратите свое время и пишите это, я тестирую это и надеюсь, что я приготовлю его к работе. Спасибо – NLed

+0

Я пробовал использовать ваш метод, но я предпочел путь Питера, потому что он похож на то, как мой курс дается. Спасибо, хотя и очень ценю это. – NLed

1

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

(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