поднять Матрицу к власти в с - PullRequest
0 голосов
/ 28 сентября 2018

Пытаюсь поднять матрицу до степени p, но я не нахожу ошибки.Кто-нибудь может помочь и объяснить проблему?Я только начал программировать на C, поэтому большое спасибо за вашу помощь.Пользователь должен ввести матрицу, и она должна быть увеличена до степени p.

int main() {
    int n, p;
    printf("Number of Rows/Colums of square matrix: ");
    scanf("%d", &n);
    printf("to the power of: ");
    scanf("%d", &p);
    int m[n][n];
    int r[n][n];

    printf("Elements\n");
    for (int b = 0; b < n; b++) {
        for (int d = 0; d < n; d++) {
            printf("[%d][%d] = ", b + 1, d + 1);
            scanf("%d", &m[b][d]);
        }
    }

    int sum = 0;
    for (int i = 0; i < p; i++) {
        for (int b = 0; b < n; b++) {
            for (int d = 0; d < n; d++) {
                for (int k = 0; k < n; k++) {
                    sum += m[b][k] * m[k][d];
                }
                r[b][d] = sum;
                sum = 1;
            }
        }

        for (int b = 0; b < n; b++) {
            for (int d = 0; d < n; d++) {
                m[b][d] = r[b][d];
                r[b][d] = 0;
            }
        }
    }

    printf("RESULT:-\n");

    for (int c = 0; c < n; c++) {
        for (int d = 0; d < n; d++) {
            printf("%d   ", m[c][d]);
        }
        printf("\n");
    }

    getch();
    return 0;
}

Ответы [ 4 ]

0 голосов
/ 28 сентября 2018

В вашем коде есть несколько проблем:

  • Вы должны использовать временную матрицу t для вычисления результата r * m и скопировать его в r перед следующим шагом.
  • sum следует повторно инициализировать до 0 или лучше, инициализировать до 0 до цикла k.

Вот исправленная версия:

#include <stdio.h>

int main() {
    int n, p;
    printf("Number of Rows/Colums of square matrix: ");
    if (scanf("%d", &n) != 1 || n <= 0)
        return 1;
    printf("to the power of: ");
    if (scanf("%d", &p) != 1 || p < 0)
        return 1;

    int m[n][n];
    int r[n][n];
    int t[n][n];

    printf("Elements\n");
    for (int b = 0; b < n; b++) {
        for (int d = 0; d < n; d++) {
            printf("[%d][%d] = ", b + 1, d + 1);
            if (scanf("%d", &m[b][d]) != 1)
                return 1;
            r[b][d] = b == d; // initialize r to identity matrix
        }
    }
    for (int i = 0; i < p; i++) {
        for (int b = 0; b < n; b++) {
            for (int d = 0; d < n; d++) {
                int sum = 0;
                for (int k = 0; k < n; k++) {
                    sum += r[b][k] * m[k][d];
                }
                t[b][d] = sum;
            }
        }
        for (int b = 0; b < n; b++) {
            for (int d = 0; d < n; d++) {
                r[b][d] = t[b][d];
            }
        }
    }

    printf("RESULT:\n");
    for (int c = 0; c < n; c++) {
        for (int d = 0; d < n; d++) {
            printf("%3d ", r[c][d]);
        }
        printf("\n");
    }
    return 0;
}

Примечания:

  • Приведенный выше код работает для положительных степеней, в том числе 0, который создает единичную матрицу.

  • Обратите внимание, однако, что этот метод неэффективен для больших мощностей и int, вероятно, в любом случае переполнится для больших мощностей.

0 голосов
/ 28 сентября 2018

Я думаю, что у вас есть различные логические проблемы в вашем коде.

Внешний цикл неправильный, поскольку вы зацикливаетесь в один раз меньше количества мощности.

Во-вторых, вам нужна матрица буфера, как вынаписал свой код.

Другая проблема заключается в том, что когда вы умножаете значения строки / столбца, вы всегда используете исходную матрицу.Это логически неправильно, вам нужно умножить матрицу, вычисленную до текущей мощности, на исходную матрицу.

Я также не понимаю, почему вы сбрасываете переменную sum в 1, а не в 0.

Что-то вроде этого должно работать:

#include <stdio.h>

int main() {
int n, p;
printf("Numer of Rows/Colums of sq matrix: ");
scanf("%d", &n);
printf("to the power of: ");
scanf("%d", &p);
int m[n][n];
int r[n][n];
int tmp[n][n];

printf("Elements\n");
for ( int b = 0 ; b < n ; b++ ) {
    for ( int d = 0 ; d < n ; d++ ) {
        printf("[%d][%d] = ", b+1, d+1);
        scanf("%d", &m[b][d]);
        r[b][d] = m[b][d];
    }
}

int sum = 0;
//you loop 1 time less of the power
for (int i = 0; i < p - 1; i++)
{
    for ( int b = 0 ; b < n ; b++ )
    {
        for (int d = 0 ; d < n ; d++ )
        {
            for (int k = 0 ; k < n ; k++ )
            {
                sum += r[b][k]*m[k][d];
            }
            tmp[b][d] = sum;
            sum = 0;
        }
    }

    for ( int b = 0 ; b < n ; b++ ) {
        for ( int d = 0 ; d < n ; d++ ) {
            //m[b][d] = r[b][d];
            r[b][d] = tmp[b][d];
        }
    }
}

printf("RESULT:-\n");

for (int c = 0 ; c < n ; c++ )
{
    for (int d = 0 ; d < n ; d++ )
    {
        printf("%d   ", r[c][d]);
    }
    printf("\n");
}

getchar();
return 0;
}

Я бы просто указал, что это решение, вероятно, не работает с p <1 </p>

0 голосов
/ 28 сентября 2018

Я бы порекомендовал вам разбить эту сложную проблему на более мелкие.

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

Вам нужно начать с матрицы: a[m][n].Должны ли значения, которые он содержит, быть целыми, плавающими, двойными?Убедитесь, что вы можете создать матрицу разных размеров.Какими должны быть ваши ограничения на строки и столбцы?

Начните с методов чтения и записи вашей матрицы.

Далее приведен метод умножения двух матриц: c[m][n] = a[m][k]*b[k][n].Количество столбцов в a соответствует количеству строк в b, или вы не можете умножить.

Повышение матрицы до целой степени p > 1 означает умножение начальной матрицы на себя p раз.Видите ли вы, что одним требованием является то, что начальная матрица должна быть квадратной?(# строки == # столбцы) Если это не так, вы не можете повысить до целочисленной степени.

Вам понадобится цикл для повышения до степени p раз.Вы будете вызывать метод умножения матриц c = mult(a, b) каждый раз в цикле.Каждый проход будет принимать вывод из предыдущего вызова и делать его первой матрицей в вызове: c = mult(c, b).

Если вы атакуете проблему таким образом, вы сможете ее решить.Обязательно тщательно проверяйте каждый шаг, прежде чем двигаться дальше.

Это называется декомпозицией.Это основа для решения проблем в целом и компьютерных наук в частности.

0 голосов
/ 28 сентября 2018

Логика вашей программы неверна на нескольких уровнях.

Это ваша исправленная программа.Есть еще возможности для улучшения (разбивка кода на функции, использование лучшего именования переменных, использование более эффективного алгоритма, чем грубое умножение матриц, правильная обработка случая, когда p равно 0), но я постарался максимально придерживатьсяисходная неправильная реализация.

Это подход: у нас есть три матрицы: r результат, m матрица, предоставленная пользователем, и temp временная матрица.

  1. Первоначально мы копируем m в r, это результат для p = 1
  2. Мы повторяем шаги 3 и 4 p - 1 раз
  3. Умножаем r и m и помещаем результат в temp
  4. Мы копируем temp в r
  5. Теперь r содержит m, возведенное в степень p.

#include <stdio.h>

int main() {
  int n, p;
  printf("Numer of Rows/Colums of sq matrix: ");
  scanf("%d", &n);
  printf("to the power of: ");
  scanf("%d", &p);
  int m[n][n];
  int r[n][n];
  int temp[n][n];

  printf("Elements\n");
  for (int b = 0; b < n; b++) {
    for (int d = 0; d < n; d++) {
      printf("[%d][%d] = ", b + 1, d + 1);
      scanf("%d", &m[b][d]);
    }
  }

  // r = m
  // temp = m
  for (int b = 0; b < n; b++) {
    for (int d = 0; d < n; d++) {
      r[b][d]   = m[b][d];
    }
  }

  for (int i = 0; i < p - 1; i++)  // p - 1 because for p = 1, r already 
  {                                // contains the result
    int sum = 0;

    // temp = r * m
    for (int b = 0; b < n; b++)
    {
      for (int d = 0; d < n; d++)
      {
        for (int k = 0; k < n; k++)
        {
          sum += m[b][k] * r[k][d];
        }
        temp[b][d] = sum;
        sum = 0;
      }
    }

    // r = temp
    for (int b = 0; b < n; b++) {
      for (int d = 0; d < n; d++) {
        r[b][d] = temp[b][d];
      }
    }
  }

  printf("RESULT:\n");

  for (int c = 0; c < n; c++)
  {
    for (int d = 0; d < n; d++)
    {
      printf("%d   ", r[c][d]);
    }
    printf("\n");
  }

  return 0;
}
...