помогите разобраться с определителем матрицы
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Есть матрица размером NxN.Надо подсчитать определитель.Что я делаю:
1.Заполняю случайными числами(0 и1).
2.Проверяю,есть ли нулевые строки или столбцы
3.Проверяю есть ли совпадающие строки или столбцы
4.Выставляю на главной диагонали ненулевые значения.Для этого смотрю mas равен нулю,если да то к i-ой строке прибавляю все остальные строки.Таким образом у меня mas обязательно станет не нулевым.
5.Привожу матрицу к треугольному ввиду,т.е. к виду когда под главным диагоналем стоят одни нули.
6.Умножение элементов главного диагоналя дает определитель матрицы.
У меня почему то иногда файл,куда все это записывается вообще пуст.Иногда вычесляется,а в последнее время,даже массив первоначальной не полностью записывается.Кто может подсказать,в чем ошибка.Ниже код.
#include <stdio.h>
#include <stdlib.h>
#define N 4
float mas[N][N];
//*******Вспомогательная функция.Проверяет на 0,элементы гл.диагонали
int NullGlDiag()
{
for(int i=0;i<N;i++)
if(mas==0)return 1;
return 0;
}
void main()
{int i,j,k,fl;
FILE *f;
randomize();
f=fopen("1.txt","w");
//********Заполняем массив for(i=0;i<N;i++)
{
fprintf(f,"\n");
for(j=0;j<N;j++)
{
mas[j]=random(2)%2;
fprintf(f,"%f ",mas[j]);
}
}
//проверяем,есть ли нулевые строки или столбцы.
for(i=0;i<N;i++)
{
fl=0;
for(j=0;j<N;j++)
fl+=mas[j];
if(fl==0){fprintf(f,"\n\n%d stroka sostoit iz 0,poetomy opredelitel=0",i+1);fclose(f);return;}
}
for(i=0;i<N;i++)
{
fl=0;
for(j=0;j<N;j++)
fl+=mas[j];
if(fl==0){fprintf(f,"\n\n%d stolbes sostoit iz 0,poetomy opredelitel=0",i+1);fclose(f);return;}
}
//проверяем на одинаковые строки и столбцы
for(i=0;i<N-1;i++)
for(j=i+1;j<N;j++)
{
fl=1;
for(k=0;k<N;k++)if(mas[i][k]!=mas[j][k])fl=0;
if(fl==1)
{fprintf(f,"\n\n%d i %d stroki sovpadayt,poetomy opredelitel=0",i+1,j+1);
fclose(f);
return;
}
}
for(i=0;i<N-1;i++)
for(j=i+1;j<N;j++)
{
fl=1;
for(k=0;k<N;k++)if(mas[k][i]!=mas[k][j])fl=0;
if(fl==1)
{fprintf(f,"\n\n%d i %d stolbsi sovpadayt,poetomy opredelitel=0",i+1,j+1);
fclose(f);
return;
}
}
//Выставляем на диагонали ненулевые значения
fl=1 ;
while(fl==1)
{
if(NullGlDiag()==0)fl=0;
else
{
for(i=0;i<N;i++)
{
fl=0;
if(mas[i][i]==0)
{
fl=1;
for(j=0;j<N;j++)
if(i!=j)
for(k=0;k<N;k++)
mas[i][k]=mas[i][k]+mas[j][k];
goto lab1;
}
}
}
lab1:
}
//получаем треугольную матрицу
for(j=0;j<N;j++)
for(i=j+1;i<N;i++)
if(mas[i][j]!=0)
{
for(k=j;k<N;k++)
mas[i][k]=mas[i][k]/mas[i][j]-mas[j][k]/mas[j][j];
if(mas[i][i]==0)
{
fprintf(f,"\n\nglavnaya diagonal sodergit 0,opredelitel=0");
fclose(f);
return;
}
}
//получаем определитель,умножив друг на друга элементы гл.диагонали
float opr=1;
for(i=0;i<N;i++)opr*=mas[i][i];
fprintf(f,"\nopredelitel=%f",opr);
fclose(f);
return;
}
P.S. Язык программирования Си
1.Заполняю случайными числами(0 и1).
2.Проверяю,есть ли нулевые строки или столбцы
3.Проверяю есть ли совпадающие строки или столбцы
4.Выставляю на главной диагонали ненулевые значения.Для этого смотрю mas равен нулю,если да то к i-ой строке прибавляю все остальные строки.Таким образом у меня mas обязательно станет не нулевым.
5.Привожу матрицу к треугольному ввиду,т.е. к виду когда под главным диагоналем стоят одни нули.
6.Умножение элементов главного диагоналя дает определитель матрицы.
У меня почему то иногда файл,куда все это записывается вообще пуст.Иногда вычесляется,а в последнее время,даже массив первоначальной не полностью записывается.Кто может подсказать,в чем ошибка.Ниже код.
#include <stdio.h>
#include <stdlib.h>
#define N 4
float mas[N][N];
//*******Вспомогательная функция.Проверяет на 0,элементы гл.диагонали
int NullGlDiag()
{
for(int i=0;i<N;i++)
if(mas==0)return 1;
return 0;
}
void main()
{int i,j,k,fl;
FILE *f;
randomize();
f=fopen("1.txt","w");
//********Заполняем массив for(i=0;i<N;i++)
{
fprintf(f,"\n");
for(j=0;j<N;j++)
{
mas[j]=random(2)%2;
fprintf(f,"%f ",mas[j]);
}
}
//проверяем,есть ли нулевые строки или столбцы.
for(i=0;i<N;i++)
{
fl=0;
for(j=0;j<N;j++)
fl+=mas[j];
if(fl==0){fprintf(f,"\n\n%d stroka sostoit iz 0,poetomy opredelitel=0",i+1);fclose(f);return;}
}
for(i=0;i<N;i++)
{
fl=0;
for(j=0;j<N;j++)
fl+=mas[j];
if(fl==0){fprintf(f,"\n\n%d stolbes sostoit iz 0,poetomy opredelitel=0",i+1);fclose(f);return;}
}
//проверяем на одинаковые строки и столбцы
for(i=0;i<N-1;i++)
for(j=i+1;j<N;j++)
{
fl=1;
for(k=0;k<N;k++)if(mas[i][k]!=mas[j][k])fl=0;
if(fl==1)
{fprintf(f,"\n\n%d i %d stroki sovpadayt,poetomy opredelitel=0",i+1,j+1);
fclose(f);
return;
}
}
for(i=0;i<N-1;i++)
for(j=i+1;j<N;j++)
{
fl=1;
for(k=0;k<N;k++)if(mas[k][i]!=mas[k][j])fl=0;
if(fl==1)
{fprintf(f,"\n\n%d i %d stolbsi sovpadayt,poetomy opredelitel=0",i+1,j+1);
fclose(f);
return;
}
}
//Выставляем на диагонали ненулевые значения
fl=1 ;
while(fl==1)
{
if(NullGlDiag()==0)fl=0;
else
{
for(i=0;i<N;i++)
{
fl=0;
if(mas[i][i]==0)
{
fl=1;
for(j=0;j<N;j++)
if(i!=j)
for(k=0;k<N;k++)
mas[i][k]=mas[i][k]+mas[j][k];
goto lab1;
}
}
}
lab1:
}
//получаем треугольную матрицу
for(j=0;j<N;j++)
for(i=j+1;i<N;i++)
if(mas[i][j]!=0)
{
for(k=j;k<N;k++)
mas[i][k]=mas[i][k]/mas[i][j]-mas[j][k]/mas[j][j];
if(mas[i][i]==0)
{
fprintf(f,"\n\nglavnaya diagonal sodergit 0,opredelitel=0");
fclose(f);
return;
}
}
//получаем определитель,умножив друг на друга элементы гл.диагонали
float opr=1;
for(i=0;i<N;i++)opr*=mas[i][i];
fprintf(f,"\nopredelitel=%f",opr);
fclose(f);
return;
}
P.S. Язык программирования Си
Например, в первом цикле:
внутри цикла идет обращение к i-му элементу массива, а переменная i никак не инициализирована.
Или просто при вбивании текста две строки склеились? :
Код: Выделить всё
for(j=0;j<N;j++)
{
mas[i][j]=random(2)%2;
fprintf(f,"%f ",mas[i][j]);
}
Или просто при вбивании текста две строки склеились? :
Код: Выделить всё
//********Заполняем массив for(i=0;i<N;i++)
//получаем треугольную матрицу
for(j=0;j<N;j++)
for(i=j+1;i<N;i++)
if(mas[j]!=0)
{
for(k=j;k<N;k++)
mas[k]=mas[k]/mas[j]-mas[j][k]/mas[j][j];
if(mas==0)
{
fprintf(f,"\n\nglavnaya diagonal sodergit 0,opredelitel=0");
fclose(f);
return;
}
}
Именно здесь ошибка.Пишет ошибка с плавающей точкой.Деление на 0.Но по условию mas[j] не равен 0,а mas[j][j] находится на гл.диагонали.А там нет нулевых элементов.
Кто чем сможет помогите плиз
for(j=0;j<N;j++)
for(i=j+1;i<N;i++)
if(mas[j]!=0)
{
for(k=j;k<N;k++)
mas[k]=mas[k]/mas[j]-mas[j][k]/mas[j][j];
if(mas==0)
{
fprintf(f,"\n\nglavnaya diagonal sodergit 0,opredelitel=0");
fclose(f);
return;
}
}
Именно здесь ошибка.Пишет ошибка с плавающей точкой.Деление на 0.Но по условию mas[j] не равен 0,а mas[j][j] находится на гл.диагонали.А там нет нулевых элементов.
Кто чем сможет помогите плиз
пройдись отладчиком. если где-то почему-то делитель равен нулю, быстро обнаружишь.
У меня Си под Дос.Там нет таких возможностей. В принцапе алгоритм почти правильный.Только при получение треугольный матрицы надо запомнить сперва mas[j] а потом делить на него.BBB писал(а):пройдись отладчиком. если где-то почему-то делитель равен нулю, быстро обнаружишь.
Проблема походу из за нехватки памяти.Т.к. при размере массива 10 все выполняеться а при 100 уже нет.
Тот же алгоритм реализовал в VB6,там все без проблем.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
как это отладчика нет? 

Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Во-первых, странно. Что это за Си такой (хоть и под ДОС), под которым нет отладчика?AigizK писал(а):У меня Си под Дос.Там нет таких возможностей.
Во-вторых. Эх, молодость, молодость. Не программировали вы на 3-м Турбо Паскале!

В общем, если в самом деле нет отладчика - пользуйся отладочной печатью. Т.е.:
printf (<интересующая информация>)
А может и есть.Но ни разу не пользовался.Максимум что делал-это через printf как ты и говоришь. Да и не охота пока разбираться с этим-все равно не мне это надо.Но если вдруг кому понадибиться алгоритм могу выложить