Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Strain
0 / 0 / 0
Регистрация: 10.06.2013
Сообщений: 18
#1

Пытаюсь рекурсивно сделать задачу. гляньте код плз) - C++

10.06.2013, 02:17. Просмотров 472. Ответов 11
Метки нет (Все метки)

КТО-НИБУДЬ, избавьте меня от мучений, гляньте код, посмотрите где я лажанул(((
Пытаюсь решить задачу рекурсивно, упражняясь в этом непростом деле..
Я постарался быть няшой и всё подробно комментировал

C++
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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
//программа читает из файла размерность квадратной матрицы, затем саму матрицу
//затем вычисляет её определитель
 
 
using namespace std;
 
int DET(int S,int counter, int size, int*massive[]);
//рекурсивная функция, вычисляющая определитель размера size.
//counter - номер строки в исходном определителе, по которой раскладывается данный определитель
//S - сумма элементов строки, умноженная на их алгебраические дополнения
//massive[size][size] - матрица, для которой вычисляется определитель
 
int main(){
    ifstream input("input.txt");
    ofstream output("output.txt");
    int size,s1; //обе переменные - размер исходной матрицы
    input >> size;
    s1=size;
    //создаём динамический массив size x size элементов, заполняем его числами из файла
    //и выводим на экран
    int **mass=new int*[size];
    for (int i=0;i<size;i++)
        mass[i]=new int[size];
    for (int i=0;i<size;i++){
        for (int j=0;j<size;j++){
            input >> mass[i][j];
            cout << setw(5) << mass[i][j];
        }
        cout << endl;
    }
    cout << endl;
    //обнуляем счётчик строк и суммы
    int counter=0;
    int S = 0;
    cout <<"DET = "<<DET(S,counter,size,mass)<<endl<<endl; //находим определитель
    //освобождаем память
    for (int i=0;i<s1;i++)
        delete[]mass[i];
    delete[]mass;
    system("pause");
    return 0;
}
 
int DET(int S,int counter, int size, int*massive[]){
    //тут два базовых случая, простых для рассчёта. 
    //используем обычные школьные формулы вычисления определителя 
    //матрицы 1x1 и 2x2
    if (size == 1)
        return massive[0][0];
    else if (size == 2)
        return massive[1][1]*massive[2][2]-massive[2][1]*massive[1][2];
    //если размерность матрицы больше 2, прибегаем к рекурсивному вызову
    else{
        size--; //размер алгебраического дополнения на 1 меньше исходного
        counter++; //переходим на следующую строку, по ней будем раскладывать определитель
        S=0; //на каждом рекурсивном вызове обнуляем сумму, чтобы новые определители
        //считались корректно
        //тут пробегаем по всем элементом строки по которой раскладываем
        for (int k=0;k<size+1;k++){
// создаём динамический массив алгебраического дополнения
            int **alg=new int*[size];
            for (int i=0;i<size;i++)
                alg[i]=new int[size];
    //и заполняем его соответствующими элементами исходного массива
    //затем выводим алгебраическое дополнение на экран
        for (int i=0;i<size;i++){
            for (int j=0;j<size;j++){
                if (j>=k)
                    alg[i][j]=massive[i+counter][j+1];
                if (j<k)
                    alg[i][j]=massive[i+counter][j];
                cout <<setw(5)<<alg[i][j];
            }
        cout <<endl;
        }
    //тут школьная формула разложения определителя по строке.
    //продолжаем рекурсивно вызывать функцию DET пока не придём к базовому случаю
        S+=pow(double(-1),double(counter+k))*massive[counter][k]*DET(S,counter,size,alg);
        cout <<k<<") "<<S<<endl;}
    }
    //освобождаем память
    for (int i=0;i<size;i++)
        delete[]massive[i];
    delete[]massive;
    //в случае размера >2 возвращаем S, рассчитанную по школьной формуле
    return S;
}
Добавлено через 26 минут
Вот тут код в человеческом виде)

http://paste.org.ru/?0ebamv
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.06.2013, 02:17
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Пытаюсь рекурсивно сделать задачу. гляньте код плз) (C++):

Гляньте код... - C++
В тексте, состоящем из русских букв, подсчитайте количество гласных букв. #include &lt;iostream.h&gt; #include &lt;conio.h&gt; #include...

Объясните задачу с циклами плз. - C++
Добрый день. Недавно начал читать учебник по С++ Стенли Липпмана Вводный курс 4-е издание. И одно из заданий никак не получается сделать....

Народ гляньте код и подскажите что не так. - C++
Условие: Написать функцию, которая округляет любое вещественное число до определённого количества знаков с математической точностью. ...

Циклы.Проверьте плз код! - C++
Задание: Напишите прогу,использующую вложенные циклы,которая запросит у пользователя значение кол-ва строк для отображения.Затем она должна...

Пытаюсь переписать код с циклом for, в код с циклом while, но не совсем получается - C++
Возникло пару вопросов: #include &lt;iostream&gt; using namespace std; int main () { for (int i = 0; i&lt;=10; i++) cout &lt;&lt;...

Пытаюсь сделать парсинг курса валют - C++
Пытаюсь сделать парсинг курса валют с сайта kurs.com.ua. А именно нужно с вкладки межбанк брать цену продажи доллара к гривне , а с НБУ...

11
MrGluck
Модератор
Эксперт CЭксперт С++
7492 / 4607 / 693
Регистрация: 29.11.2010
Сообщений: 12,603
10.06.2013, 02:18 #2
Цитата Сообщение от Strain Посмотреть сообщение
Вот тут код в человеческом виде)
выложили бы в тегах CPP, было бы тут в человеческом виде
0
Strain
0 / 0 / 0
Регистрация: 10.06.2013
Сообщений: 18
10.06.2013, 02:31  [ТС] #3
MrGluck, спасибо, буду знать)
сам нашёл очевидную ошибку в 55й строке. Двойки заменить единицами, а единицы нулями.
Но всё равно не работает((((
0
MrGluck
Модератор
Эксперт CЭксперт С++
7492 / 4607 / 693
Регистрация: 29.11.2010
Сообщений: 12,603
10.06.2013, 02:33 #4
Strain, выложите исправленный код на форум
Если возможно, под спойлером без комментов, лично мне так проще будет
0
Strain
0 / 0 / 0
Регистрация: 10.06.2013
Сообщений: 18
10.06.2013, 11:34  [ТС] #5
MrGluck, спасибо за участие, код удалось пофиксить.
Насчёт counter - было ошибкой вообще вводить эту переменную, я убрал её из кода.
От преобразования int->double я ушёл, используя более простые условные операции cpp

в общем всё заработало, вот работоспособный код

C++
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
#include <iostream>
#include <iomanip>
#include <fstream>
 
//программа читает из файла размерность квадратной матрицы, затем саму матрицу
//затем вычисляет её определитель
 
 
using namespace std;
 
int DET(int S, int size, int*massive[]);
//рекурсивная функция, вычисляющая определитель размера size.
//counter - номер строки в исходном определителе, по которой раскладывается данный определитель
//S - сумма элементов строки, умноженная на их алгебраические дополнения
//massive[size][size] - матрица, для которой вычисляется определитель
 
int main(){
    ifstream input("input.txt");
    ofstream output("output.txt");
    int size,s1; //обе переменные - размер исходной матрицы
    int result; //результат вычисления определителя
    input >> size;
    s1=size;
    //создаём динамический массив size x size элементов, заполняем его числами из файла
    //и выводим на экран
    int **mass=new int*[size];
    for (int i=0;i<size;i++)
        mass[i]=new int[size];
    for (int i=0;i<size;i++){
        for (int j=0;j<size;j++){
            input >> mass[i][j];
            cout << setw(5) << mass[i][j];
        }
        cout << endl;
    }
    cout << endl;
    //обнуляем счётчик строк и суммы
    int S = 0;
    result=DET(S,size,mass);
    cout <<endl<<"DET = "<<result<<endl<<endl; //находим определитель
    output << result; //записываем результат в файл
    //освобождаем память
    for (int i=0;i<s1;i++)
        delete[]mass[i];
    delete[]mass;
    system("pause");
    return 0;
}
 
int DET(int S, int size, int*massive[]){
    S=0; //на каждом рекурсивном вызове обнуляем сумму, чтобы новые определители
    //считались корректно
    //тут два базовых случая, простых для рассчёта. 
    //используем обычные школьные формулы вычисления определителя 
    //матрицы 1x1 и 2x2
    if (size == 1)
        return massive[0][0];
    else if (size == 2)
        return massive[0][0]*massive[1][1]-massive[1][0]*massive[0][1];
    //если размерность матрицы больше 2, прибегаем к рекурсивному вызову
    else{
        size--; //размер алгебраического дополнения на 1 меньше исходного
 
        //тут пробегаем по всем элементом строки по которой раскладываем
        for (int k=0;k<size+1;k++){
// создаём динамический массив алгебраического дополнения
            int **alg=new int*[size];
            for (int i=0;i<size;i++)
                alg[i]=new int[size];
    //и заполняем его соответствующими элементами исходного массива
    //затем выводим алгебраическое дополнение на экран
        for (int i=0;i<size;i++){
            for (int j=0;j<size;j++){
                if (j>=k)
                    alg[i][j]=massive[i+1][j+1];
                if (j<k)
                    alg[i][j]=massive[i+1][j];
                cout <<setw(5)<<alg[i][j];
            }
        cout <<endl;
        }
    //тут школьная формула разложения определителя по строке.
    //продолжаем рекурсивно вызывать функцию DET пока не придём к базовому случаю
        S+=(((k+1)%2)?1:-1)*massive[0][k]*DET(S,size,alg);
        cout <<k<<") "<<S<<endl;
    //освобождаем память
    for (int i=0;i<size;i++)
        delete[]alg[i];
    delete[]alg;
        }}
    //в случае размера >2 возвращаем S, рассчитанную по школьной формуле
    return S;
}
0
MrGluck
Модератор
Эксперт CЭксперт С++
7492 / 4607 / 693
Регистрация: 29.11.2010
Сообщений: 12,603
10.06.2013, 12:36 #6
Strain, если матрица квадратная, то незачем хранить две переменные, тем более так, как это сделано у вас. В циклах контроль все равно по первой организован.
Рекомендую делать проверку на открытие файла, например так:
C++
1
2
3
4
5
if (!ifs)
{
    // ... сообщение об ошибке
    return 1;
}
Хедера не хватает cstdlib для функции system.
Советую пробелы расставлять почаще, читаемость кода повышается заметно.
И комментировать лишь то, о чем не может сказать сам код.
int S - ненужный параметр, он все равно каждый раз 0 равен при входе в функцию, логичней было бы разместить его как локальную переменную. Сам по себе динам. массив принято писать в параметрах до размера (обычно так делают).
А в целом, очень даже неплохо
1
Kuzia domovenok
1957 / 1810 / 142
Регистрация: 25.03.2012
Сообщений: 6,280
Записей в блоге: 1
10.06.2013, 12:40 #7
В этом примере Память освобождается не только в конце основной программы
Цитата Сообщение от Strain Посмотреть сообщение
//освобождаем память
for (int i=0;i<s1;i++)
delete[]mass[i];
delete[]mass;
но и при каждом вызове функции.
Цитата Сообщение от Strain Посмотреть сообщение
for (int i=0;i<size;i++)
delete[]massive[i];
delete[]massive;
То есть после первого вызова функции - массив уже окончательно испорчен.
0
MrGluck
Модератор
Эксперт CЭксперт С++
7492 / 4607 / 693
Регистрация: 29.11.2010
Сообщений: 12,603
10.06.2013, 12:52 #8
Kuzia domovenok, не туда смотришь. В исправленном коде освобождается массив из main-a только в конце работы программы и при каждом вызове функции сначала формируется дин. массив, потом с ним идет работа, а потом он же и освобождается.
0
Ternsip
660 / 188 / 6
Регистрация: 10.05.2012
Сообщений: 595
10.06.2013, 13:47 #9
Strain, я уже писал
Определитель матрицы - нужен полноценный пример
0
Strain
0 / 0 / 0
Регистрация: 10.06.2013
Сообщений: 18
10.06.2013, 14:11  [ТС] #10
Ternsip, ох у тебя там много для меня непонятных пока что слов))

vector, scanf и добрая половина подключаемых заголовочных файлов..
и ты как-то ещё обошёлся без динамических массивов..
В общем надо прошариваться. Опыта в программировании у меня 1,5-2 месяца, многого не знаю

сам эту задачу сначала решил тоже используя метод Гаусса, но мой код был раза в 2 больше((
0
Ternsip
660 / 188 / 6
Регистрация: 10.05.2012
Сообщений: 595
10.06.2013, 14:14 #11
Strain, vector - динамический массив объектов. scanf - это считывание
0
Strain
0 / 0 / 0
Регистрация: 10.06.2013
Сообщений: 18
10.06.2013, 14:14  [ТС] #12
MrGluck, спасибо)
0
10.06.2013, 14:14
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.06.2013, 14:14
Привет! Вот еще темы с ответами:

Рекурсивно найти n-ую производную для заданого x. Результат похож на шестнадцатеричный код - C++
Задание:рекурсивно найти n-ую производную f(x)={e}^{(a{x}^{2}+bx+c)} для заданого x,построив для {f}^{(n)}(x) рекурентное соотношение. ...

Плз обьясните неучу как выполнить в VC++ код на asme. - C++
Плз обьясните неучу как выполнить в VC++ код на asme. Дериктива _asm а как с ней работать ? Допутим есть код для примера : ...

пытаюсь сделать реализацию через считывание из файла кол-ва чисел, i,но незнаю как сделать реализацию из файла в массив и сортировки. - C++
В файле input.txt находится неизвестное количество вещественных чисел в интервале . Выцапарать их оттуда, отсортировать по убыванию модуля...

Нужно вывести все буквы, которые встречаются в ней , и их количество , легкий код только сделайте плз - C++
Пример Input zazbazy output a 2 ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru