Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.04.2013, 17:20   #1
cerum
 
Регистрация: 14.04.2013
Сообщений: 4
По умолчанию Нахождение детерминанта матрицы на С

Помогите пожалуйста написать программу для нахождения детерминанта матриц на основе рекурсивного алгоритма на языке С.
Написал такую программу

Код:
#include <conio.h> 
#include <stdio.h> 
#define n 4



int main (void)
{
	int Minor (int *ptr, int *ptr2, int nn, int row, int col);
	long int Determinant (int *ptr, int nn);

	long int det;
	//int i, j;
	int M[n][n] = {
		{3, 5, 7, 8},
		{-1, 7, 0, 1},
		{0, 5, 3, 2},
		{1, -1, 7, 4}
	};
	int *ptr;

	ptr = &M[0][0];
	
	det = Determinant (&M[0][0], n);
	printf("\n\t Determinant = %d", det);
	
	printf("\n\n Press any key: ");
	_getch();
	return 0;

}



int Minor (int *ptr, int *ptr2, int nn, int row, int col)
{
	int ki, kj, di = 0, dj;

	for (ki = 0; ki < nn - 1; ki++)
	{
		if (ki == row)
			di = 1;
		dj = 0;

		for (kj = 0; kj < nn - 1; kj++)
		{
			if (kj == col)
				dj = 1;
			*(ptr2 + ki*nn + kj) = *(ptr +(ki + di)*nn + (kj + dj)); 
		}
	}

}


long int Determinant (int *ptr, int nn)
{
	long int i, j, d = 0, k = 1;
	int R[n][n] = {0};
	int *ptr2, **ptr3;

	ptr2 = &R[0][0];
	ptr3 = &ptr;

	if (nn < 1)
		return 1;
	else if (nn == 1)
		d = *ptr;
	else if (nn == 2)
		d = *ptr * *(ptr + nn + 1) - *(ptr + nn) * *(ptr + 1);
	else 
		for (i = 0; i < nn; ++i)
		{
			Minor (*ptr3, &R[0][0], nn, i, 0);
			d += k * *(ptr + i*nn) * Determinant (&R[0][0], nn - 1);
			k = -k;
			
		}

	return d;

}
Если матрица больше чем 2х2, то не работает. Как ее исправить?
cerum вне форума Ответить с цитированием
Старый 14.04.2013, 22:16   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Код:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

long int
det(int **ptr, int n, int row, unsigned free_col)
{
    if (row >= n) {
        return 1;
    }
    long int s = 0, k = 1;
    int i;
    for (i = 0; i < n; ++i) {
        if (!(free_col >> i & 1)) {
            s += k * ptr[row][i] * det(ptr, n, row + 1, free_col | (1 << i));
            k = -k;
        }
    }
    return s;
}

long int
Determinant(int **ptr, int n)
{
    return det(ptr, n, 0, 0);
}

int
main(void)
{
    srand(time(NULL));
    int n = 4;
    int **m = malloc(n * sizeof(*m));
    int i, j;
    for (i = 0; i < n; ++i) {
        m[i] = malloc(n * sizeof(**m));
        for (j = 0; j < n; ++j) {
            m[i][j] = rand() % 11 - 5;
            printf("%4d", m[i][j]);
        }
        printf("\n");
    }
    printf("\nDeterminant = %ld\n\nPress any key", Determinant(m, n));
    for (i = 0; i < n; ++i)
        free(m[i]);
    free(m);
    _getch();
    return 0;
}
Лучше немного поменять алгоритм.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 14.04.2013 в 22:20.
BDA на форуме Ответить с цитированием
Старый 18.04.2013, 21:41   #3
cerum
 
Регистрация: 14.04.2013
Сообщений: 4
По умолчанию

BDA, большое спасибо за помощь. А вот эти фрагменты можно заменить чем-то более простым?
Код:
 if (!(free_col >> i & 1))
Код:
free_col | (1 << i))
Никак ни разберусь как они работают? С побитовыми операциями вообще только сейчас познакомился.
BDA, разъясни пожалуйста как эти две строки работают
cerum вне форума Ответить с цитированием
Старый 18.04.2013, 22:44   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Пожалуйста.
Как раз таки использование битовых операций наиболее просто, на мой взгляд (да и экономично - 4 байта для матриц до 32х32 включительно; матрицы с большим размером считать нельзя таким образом - нужно использовать больший беззнаковый тип).
free_col хранит 0 биты на тех местах, какие колонки еще не использованы для расчета.

if (!(free_col >> i & 1))
free_col >> i - сдвиг на i бит влево
free_col >> i & 1 - побитовое "И" c 1 (выделяется 1 бит из числа)
!(free_col >> i & 1) - если полученный бит нулевой, то условие выполняется

free_col | (1 << i))
1 << i - сдвиг 1 бита на i бит вправо
free_col | (1 << i)) - побитовое "ИЛИ" 2 чисел (таким образом, на i месте будет 1 бит)
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 18.04.2013 в 22:50.
BDA на форуме Ответить с цитированием
Старый 11.05.2013, 20:22   #5
cerum
 
Регистрация: 14.04.2013
Сообщений: 4
По умолчанию

BDA, не разберусь только со знаком > из следующей строки
Код:
if (row >= n)
= понятно зачем, благодаря нему определитель матрицы 1х1 равен самому числу, а вот зачем знак > не пойму, без него результат получается неверный. Разве есть такой момент выполнения программы, когда передаваемая строка будет больше размерности матрицы? Заранее спасибо
cerum вне форума Ответить с цитированием
Старый 11.05.2013, 20:45   #6
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Наверное не может. Поставьте == вместо >= и протестируйте программу.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 12.05.2013, 10:37   #7
cerum
 
Регистрация: 14.04.2013
Сообщений: 4
По умолчанию

Сделал как вы советовали, теперь все отлично. BDA, большое спасибо за помощь!
cerum вне форума Ответить с цитированием
Старый 12.05.2013, 12:02   #8
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Пожалуйста.
= - оператор присваивания
== - оператор сравнения
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 12.05.2013 в 12:52.
BDA на форуме Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нахождение обратной матрицы suslic3d Общие вопросы Delphi 0 11.12.2012 15:01
нахождение обратной матрицы и единичной матрицы размерностью N denisbrain Паскаль, Turbo Pascal, PascalABC.NET 0 17.05.2012 11:53
Нахождение обратной матрицы Linkfanka Помощь студентам 1 24.01.2012 08:23
Нахождение определителя матрицы La`Fleur C++ Builder 0 10.05.2011 22:34
нахождение нечетных элементов матрицы graf890 Помощь студентам 2 20.02.2011 01:07