Я пишу функцию для расчета определителя. Матрица - все 4х4 двумерного массива. Я обнаружил, что следующие два кода имеют разные результаты. Я проверяю результат MATLAB.
Я использую тестовый пример, как это
0 2 0 1
3 3 2 1
3 2 4 0
2 2 1 1
Код, который имеет правильный результат:
void determinant()
{
double result=1;
int i;
int j;
int k;
for(i=0;i<4;i++)
{
for(j=i+1;j<4;j++)//swap the largest number to diagonal position
{
if(matrix[j][i]>matrix[i][i])
{
swap_row(i,j);
result=result*(-1);//once swap two rows, result will multiply by (-1)
}
}
for(j=i+1;j<4;j++)
{
double divident=matrix[j][i]/matrix[i][i];
for(k=0;k<4;k++)
{
matrix[j][k]=matrix[j][k]-matrix[i][k]*divident;//here is the different part
}
}
}
for(i=0;i<4;i++)
{
result=result*matrix[i][i];
}
cout<<"determinant="<<result<<endl;
}
Правильный код меняет матрицу в это:
3 3 2 1
0 2 0 1
0 0 2 -0,5
0 0 0 0,25
Однако, как только я пишу этот код без double divident=matrix[j][i]/matrix[i][i];
, результат будет поворачивать разные:
void determinant()
{
double result=1;
int i;
int j;
int k;
for(i=0;i<4;i++)
{
for(j=i+1;j<4;j++)//swap the largest number to diagonal position
{
if(matrix[j][i]>matrix[i][i])
{
swap_row(i,j);
result=result*(-1);//once swap two rows, result will multiply by (-1)
}
}
for(j=i+1;j<4;j++)
{
for(k=0;k<4;k++)
{
matrix[j][k]=matrix[j][k]-matrix[i][k]*matrix[j][i]/matrix[i][i];//here is the different part
}
}
}
for(i=0;i<4;i++)
{
result=result*matrix[i][i];
}
cout<<"determinant="<<result<<endl;
}
И неправильный код меняет матрицу в это
3 3 2 1
0 2 0 1
0 0 4 0
0 0 0 1
Что касается функции swap_row
, это работает так (и я уверен, что проблема здесь не существует):
void swap_elements(double &a, double &b)
{
double tmp;
tmp=a;
a=b;
b=tmp;
}
void swap_row(int i, int j)
{
for(column=0;column<4;column++)
{
swap_elements(matrix[i][column],matrix[j][column]);
}
}
Я использую this->display()
(функция - это функция пирема в классе) для отслеживания изменений, шаг за шагом, но кажется, что расчет ничего не прав, но заказ отличается (правильный код вычисляется по строке, но неправильно Один рассчитывает по одному элементу в массиве) Что заставляет меня смущать, что я ничего не изменил о цикле. Так в чем разница между этими двумя кодами?
1 ответ
Я думаю, что во втором варианте вашего кода вы перезаписываете вещи плохим образом. Рассмотрим петлю над k
, предположим i=0
и посмотрите на случай k=0
:
matrix[j][0]=matrix[j][0]-matrix[0][0]*matrix[j][0]/matrix[0][0];
Это будет перезаписать запись {matrix[j][0]
. Теперь рассмотрим следующую итерацию того же петля, то есть k=1
и еще i=0
:
matrix[j][1]=matrix[j][1]-matrix[i][1]*matrix[j][0]/matrix[0][0];
Как видите, это использует элемент matrix[j][0]
, который вы только что обновили в предыдущей итерации. Так что вы используете новое значение . В правильной версии вашего кода вы вместо этого храните значение matrix[j][0]
, прежде чем запустить цикл, и, таким образом, используйте правильное необъявленное значение на протяжении всего цикла.
Похожие вопросы
Связанные вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .