Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
Tana12334
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 28
1

Программа для решения ребуса

02.05.2015, 14:17. Просмотров 1341. Ответов 10
Метки нет (Все метки)

помогите решить программу с ребусом, это комбинаторика.
я написала функции от программы но не могу додумать как написать функцию с самим решением ребуса, прошу помогите
0
Миниатюры
Программа для решения ребуса  
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.05.2015, 14:17
Ответы с готовыми решениями:

Составить программу для решения ребуса : КОТ + КОТ = ТОК, где разным буквам соответствуют разные цифры, одинаковым - одинаковые
Составить программу для решения ребуса : КОТ + КОТ = ТОК, где разным буквам...

Составить алгоритм решения ребуса
составить алгоритм решения ребуса МУХА+МУХА+МУХА=СЛОН(различные буквы означают...

Составить алгоритм решения ребуса РАДАР=(Р+А+Д)^4
Составить алгоритм решения ребуса РАДАР=(Р+А+Д)^4 (различные буквы означают...

Алгоритм решения ребуса сыр + сыр = рыба
Составить алгоритм решения ребуса сыр + сыр = рыба (различные буквы обозначают...

Программа для решения слау методом главных элементов для всеразмерной матрицы
Вот написал программу для решения слау методом главных элементов для...

10
Tana12334
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 28
02.05.2015, 14:42  [ТС] 2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
for ( i =0,i<k,i++)  Ci = i ;\\генерация сочетаний без повторений
    p =k ;
//затем содержимое массива С надо копировать в Р
Void reverse ( int m )//рекурсивная процедура генерации перестановок
{   i =1; j = m ;
    while  ( i <j )  { Pi <->Pj ;
             i =i +1; j=j -1;
                   }    
}
Void Antilex ( int m )
{  if  ( m =1) вывод массива P ;
    else  for ( i =0,i<m,i++ )
    {  Antilex ( m -1);
        if  (i < m )
              {  Pi <->Pm ;
         reverse ( m -1);
              }
    }
}
{  for ( i =0,i<n,i++ )P= i ;
    Antilex ( n );
}
<-> - поменять местами переменные
P – массив, содержащий перестановку;
n – количество элементов в перестановке
С – массив, содержащий сочетание;
k – количество элементов в сочетании;

Добавлено через 3 минуты
вот и не знаю что с этим делать, кто нибудь помогите, программа нужна сильно((

Добавлено через 4 минуты
Пример. ТОРГ * Г = ГРОТ. Имеем 4 различных цифры: Т, О, Р, Г. Следовательно, необходимо сгенерировать 4-размещения из 10 (всего 10 цифр), т.е. массив а[1], … , а[4], удовлетворяющий следующим условиям:
1) а[1] != 0, а[4] != 0 – т.к. число не может начинаться с 0.
2) а[1]*1000 + а[2]*100 + а[3]*10 + а[4] = а[4]*1000 + а[3]∙100 + а[2]∙10 + а[1] – это запись зашифрованного действия.
В процессе генерации каждую полученную комбинацию проверяют на выполнение перечисленных условий и отбирают подходящие. В общем случае решений может быть несколько. В данном примере ТОРГ = 1089 (1089*9 = 9801).
вот обьяснение к примеру другой задачи, помогите чтобы я разобралась((
0
MansMI
1449 / 1158 / 550
Регистрация: 08.01.2012
Сообщений: 4,509
02.05.2015, 15:17 3
для Москвы:
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
void AddNum(int n,int* arr)
{
    int i,num,sum,a;
    for(num=0; num<10; num++)
    {
        for(i=0; i<n; i++)
            if(arr[i]==num) break;
        if(i!=n) continue;
        arr[n]=num;
        if(n<5) AddNum(n+1,arr);
        else
        {
            sum=a=0;
            for(i=0; i<6; i++)
            {
                sum+=arr[i];
                a*=10;
                a+=arr[i];
            }
            if(sum*sum*sum*sum==a) printf("%d",a);
        }
    }
}
int main(int argc,char* argv[])
{
    int arr[6];
 
    AddNum(0,arr);
    getch();
    return 0;
}
0
Tana12334
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 28
02.05.2015, 18:24  [ТС] 4
MansMI, должен выводиться нe ответ, а вот так примерно)
0
Миниатюры
Программа для решения ребуса  
nefton
44 / 20 / 6
Регистрация: 28.02.2013
Сообщений: 193
03.05.2015, 09:29 5
Господи, это где ж такому учат? Это маленькая диссертация наверное )
мне кажется надо некоторая функция
C++
1
2
3
enum class symvol {0,1,2,3,4,5,6,7,8,9,obyedinenie,l_scobka,r_skobka,plus,minus,delit,umozit,stepen);
vector <symvol> virazenie;
int PoschitatVirazenie(virazenie* v);
А потом уже играться как-то с подстановками.

Добавлено через 6 минут
http://lord-n.narod.ru/download/book..._C/24/2404.htm

Добавлено через 5 минут
даже лучше (юзабильнее намного) это сделать так
Кликните здесь для просмотра всего текста
C++
1
2
3
4
enum class symvol {0,1,2,3,4,5,6,7,8,9,obyedinenie,l_scobka,r_skobka,plus,minus,delit,umozit,stepen);
vector <symvol> virazenie;
int PoschitatVirazenie(virazenie* v, int* result); //возвращает код ошибки (типа скобку забыли). 0 - всё нормально
string OshibkaVirazeniya(int error_code);
0
Tana12334
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 28
03.05.2015, 17:35  [ТС] 6
nefton, блин я только начинаю учиться программированию, и то что вы прислали совсем для меня непонятно еще
0
nefton
44 / 20 / 6
Регистрация: 28.02.2013
Сообщений: 193
03.05.2015, 20:56 7
ну что... я герой.
main.cpp
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include "Vichislitel.h"
 
 
using namespace std;
 
int main(){
 
    Vichislitel v;
    
    cout<<v.Parse("(10+5)*2+2^(2+1)")<<endl;
 
    cout<<endl<<endl;
    system("pause");
 
    return 0;
}


Vichislitel.h
Кликните здесь для просмотра всего текста
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
#pragma once
 
#include <vector>
#include <string>
 
class Vichislitel
{
public:
    Vichislitel();
    int Parse(std::string str);
 
private:
    enum class unit_type{null,chislo,obyedinit,plus,minus,umnozit,delit,stepen,l_skobka,r_skobka};
    class unit{
    public:
        unit(unit_type type, int value);
        unit_type type;
        int prioritet; //0=max prioritet
        int Result(int left, int right);
        int value;
        int Stepen(int base, int stepen);
    };
    std::vector <unit> virazenie;
    
    int Vichislit(std::vector<unit>* units, int start_pos, int end_pos); 
 
    int GetLeftPos(int start_pos);//Берёт первое число слева
    int GetRightPos(int start_pos);
    bool IsNumber(char c);
    int Number (char c);
};


Vichislitel.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "Vichislitel.h"
 
 
Vichislitel::Vichislitel(){;}
 
 
Vichislitel::unit::unit(Vichislitel::unit_type type, int value){
    unit::type = type;
    unit::value = value;
    if (type == unit_type::l_skobka) prioritet = 0;
    if (type == unit_type::r_skobka) prioritet = 0;
    if (type == unit_type::chislo) prioritet = 1;
    if (type == unit_type::obyedinit) prioritet = 2;
    if (type == unit_type::delit) prioritet = 3;
    if (type == unit_type::umnozit) prioritet = 3;
    if (type == unit_type::stepen) prioritet = 4;
    if (type == unit_type::plus) prioritet = 5;
    if (type == unit_type::minus) prioritet = 5;
    if (type == unit_type::null) prioritet = 6;
    return;
}
 
 
 
int Vichislitel::unit::Result(int left, int right){
    
    if (type==unit_type::null) {
        return -666;
    }
    
    if (type==unit_type::chislo) return value;
    if (type==unit_type::plus) return left+right;
    if (type==unit_type::minus) return left-right;
    if (type==unit_type::umnozit) return left*right;
    if (type==unit_type::delit) return left/right;
 
    if (type==unit_type::obyedinit){
        int right_digits = 1;
        while (right>=Stepen(10, right_digits)) right_digits++;
        return left*Stepen(10, right_digits)+right;
    }
    if (type==unit_type::stepen) return Stepen(left,right);
 
 
    return -666;
}
 
int Vichislitel::Vichislit(std::vector<unit>* units, int start_pos, int end_pos){
    
    //Избавляемся от скобок
    //Если видим открывающую скобку-считаем выражение до закрывающей
    //и ложим результат вместо открывающей собки, удаляя всё что в скобках
    bool is_skobki;
    do { //Ищем открывающую скобку, а за ней закрывающую
        //Важно, между ними никаких скобок
        is_skobki = false;
        int l_skobka_pos = 0;
        int r_skobka_pos = units->size()-1;
 
        for (int pos=start_pos; pos<=end_pos; pos++){
                if ((*units)[pos].type == unit_type::l_skobka) {
                    is_skobki = true;
                    l_skobka_pos = pos;
                }
                if ((*units)[pos].type == unit_type::r_skobka) {
                    is_skobki = true;
                    r_skobka_pos = pos;
                    break;
                }
        }
        //Тут мы имеем позиции левых и правых скобок (если есть)
        if (is_skobki){
            int result = Vichislit(units, l_skobka_pos+1, r_skobka_pos-1); 
            for (int pos = l_skobka_pos; pos<=r_skobka_pos; pos++){
                (*units)[pos].type=unit_type::null;
                (*units)[pos].prioritet=-1;
            }
            (*units)[l_skobka_pos].type = unit_type::chislo;
            (*units)[l_skobka_pos].value = result;
        }
    } while (is_skobki);
    //Так, теперь надо вычислить без скобок, согласно приоритетам
 
    for (int prioritet = 2; prioritet<= 5; prioritet++){
        for (int pos = start_pos+1; pos<end_pos; pos++){
            if ((*units)[pos].prioritet == prioritet){
                int left_pos = GetLeftPos(pos);
                int right_pos = GetRightPos(pos);
                int result = (*units)[pos].Result((*units)[left_pos].value, (*units)[right_pos].value);
                (*units)[left_pos].type = unit_type::null;
                (*units)[right_pos].type = unit_type::null;
                (*units)[pos].type = unit_type::chislo;
                (*units)[pos].value = result;
                (*units)[pos].prioritet = -1;
            }
        }
    }
    //Тут у нас должно остатся одно единственное число из всех юнитов
 
    for (int pos = start_pos; pos<=end_pos; pos++){
        if ((*units)[pos].type == unit_type::chislo) return (*units)[pos].value;
    }
 
    //Тут мы по идее не должны быть
    return -666;
}
 
int Vichislitel::GetLeftPos(int start_pos){
    for (int pos = start_pos-1; pos>=0; pos--){
        if (virazenie[pos].type == unit_type::chislo) return pos;
    }
    return -1;
}
 
int Vichislitel::GetRightPos(int start_pos){
    for (int pos = start_pos+1; pos<virazenie.size(); pos++){
        if (virazenie[pos].type == unit_type::chislo) return pos;
    }
    return -1;
}
 
 
int Vichislitel::unit::Stepen(int base, int stepen){
    int result = 1;
    for (int i=0; i<stepen; i++) result *= base;
    return result;
}
 
int Vichislitel::Parse(std::string str){
 
    virazenie.clear();
    for (int pos=0; pos<str.size(); pos++){
        if (str[pos] == '(')virazenie.push_back(unit(unit_type::l_skobka, 0));
        if (str[pos] == ')')virazenie.push_back(unit(unit_type::r_skobka, 0));
        if (IsNumber(str[pos])){
            virazenie.push_back(unit(unit_type::chislo, Number(str[pos])));
            if (pos<str.size()-1){
                if (IsNumber(str[pos+1])){
                    virazenie.push_back(unit(unit_type::obyedinit, 0));
                }
            }
        }
        if (str[pos] == '+')virazenie.push_back(unit(unit_type::plus, 0));
        if (str[pos] == '-')virazenie.push_back(unit(unit_type::minus, 0));
        if (str[pos] == '*')virazenie.push_back(unit(unit_type::umnozit, 0));
        if (str[pos] == '/')virazenie.push_back(unit(unit_type::delit, 0));
        if (str[pos] == '^')virazenie.push_back(unit(unit_type::stepen, 0));
    }
 
    return Vichislit(&virazenie, 0, virazenie.size()-1);
}
 
int Vichislitel::Number(char c){
    if (c == '0') return 0;
    if (c == '1') return 1;
    if (c == '2') return 2;
    if (c == '3') return 3;
    if (c == '4') return 4;
    if (c == '5') return 5;
    if (c == '6') return 6;
    if (c == '7') return 7;
    if (c == '8') return 8;
    if (c == '9') return 9;
    return -1;
}
 
bool Vichislitel::IsNumber(char c){
    if (Number(c) != -1) return true;
    return false;
}


Добавлено через 12 минут
Алгоритм разбора строки выражения оказался легче чем я думал.
1. Научится считать выражение без скобок.
всё выражение представляем как вектор юнитов (число, *,/,+,-,обьединить,^)
у юнитов операций (*,/,+,-,обьединить,^) есть приоритет. 0=самый высокий
Без никаких рекурсий заменяем операцию на её результат с левой и правой частью
А левую и правую части соответственно удаляем
И так в несколько проходов (сначала высший приоритет, потом пониже)
Остаётся 1 число в итоге. это и есть ответ, притом за линейное время.
2. Скобки
Скобки это тоже юниты.
И тоже без рекурсии можно (незнаю чё её использовал)
Смысл в ом чтоб найти открывающую и закрывающую скобку, чтоб между ними небыло больше скобок.
И заменить их на результат в скобках

Всё, парсер готов )))

Добавлено через 31 минуту
для перебора надо размещение без повторений
http://slovesnov.users.sourceforge.net/index.php?permutations,russian
0
nefton
44 / 20 / 6
Регистрация: 28.02.2013
Сообщений: 193
03.05.2015, 22:33 8
Лучший ответ Сообщение было отмечено DrOffset как решение

Решение

Ну что. решение готово.
Скину в архиве под visual studio весь проект.
Использовал класс для перебора вариантов вот отсюда.

В main маленькими англ буквами надо ввести левую и правую часть уравнения.
А прога его решит.

C++
1
2
string virazenie1 = "moskva";
string virazenie2 = "(m+o+s+k+v+a)^4";
0
Миниатюры
Программа для решения ребуса  
Вложения
Тип файла: rar parser.rar (1.85 Мб, 7 просмотров)
nefton
44 / 20 / 6
Регистрация: 28.02.2013
Сообщений: 193
03.05.2015, 23:20 9
а вот и первые баги.
1 надо поправить приоритет возведения в степень. он оказывается выше умножения.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
if (type == unit_type::obyedinit) prioritet = 2;
if (type == unit_type::stepen) prioritet = 3;
if (type == unit_type::delit) prioritet = 4;
if (type == unit_type::umnozit) prioritet = 4;
if (type == unit_type::plus) prioritet = 5;
if (type == unit_type::minus) prioritet = 5;


2е. s*a^r = atov
находит 9*2^8 = 2304
но не находит почемуто прмер с картинки 9*5^4 = 5625

Добавлено через 7 минут
А!!!!!! ну так [sensored]!!!!
На картинке то ответ не верный! в правой части уравнения a=5 и v=5
что противоречит условию задачи

Добавлено через 21 минуту
экспромт
(l+u+g+a+n+s+k)^4 = ukr^2+a+ine^2
(5+8+2+6+9+0+4)^4 = 843^2+6+791^2
0
Tana12334
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 28
03.05.2015, 23:44  [ТС] 10
nefton, спасибо большое за проделанную работу, только вот не открывается ваше решение((
не могу его посмотреть, не могли бы вы кинуть программу скопированную в ответы?
буду очень благодарна
0
nefton
44 / 20 / 6
Регистрация: 28.02.2013
Сообщений: 193
04.05.2015, 06:59 11
Лучший ответ Сообщение было отмечено Tana12334 как решение

Решение

main.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
#include <iostream>
#include "Vichislitel.h"
#include "Permutations.h"
 
using namespace std;
 
 
class peremennaya{
public:
    char imya;
    int number;
};
 
int main(int argc,char* argv[])
{
 
    Vichislitel v;
    string virazenie1 = "(l+u+g+a+n+s+k)^4";
    string virazenie2 = "ukr^2+a+ine^2";
 
    int number=0;
    vector<peremennaya> peremennie;
    
    string ss=virazenie1+virazenie2;
    for (int pos=0; pos<ss.size(); pos++){
        if ((ss[pos]<'a')||(ss[pos]>'z')) continue;
        bool is_exist = false;
        for (auto it=peremennie.begin(); it<peremennie.end(); it++){
            if (ss[pos] == it->imya) is_exist = true;
        }
        if (!is_exist){
            peremennaya p;
            p.imya = ss[pos];
            p.number = number;
            number++;
            peremennie.push_back(p);
        }
    }
 
    Permutations p;
    
    p.init(number,10,PERMUTATIONS_WITHOUT_REPLACEMENTS);
    
    cout<<endl<<"Schitaem:  "<<virazenie1<<" = "<<virazenie2<<endl;
    cout<<endl<<"Vsego kombinacii:  "<<p.number()<<endl<<endl;
 
    int itteration = 0;
    do{
        if (itteration%1000 == 0) cout<<"Itteration: "<<itteration<<"        \r";
        itteration++;
        string s1 = virazenie1;
        string s2 = virazenie2;
        //Заменяем буквы в уравнениях на цыфры
        for (int i=0; i<number; i++){
            for (int pos=0; pos<s1.size(); pos++) if (s1[pos] == peremennie[i].imya) s1[pos] = p.getIndex(i)+48;
            for (int pos=0; pos<s2.size(); pos++) if (s2[pos] == peremennie[i].imya) s2[pos] = p.getIndex(i)+48;
        }
        //Самое главное
        if (v.Parse(s1) == v.Parse(s2)){
            cout<<endl<<"YAHOO!"<<endl;
            cout<<s1<<" = "<<s2<<endl;
            //break;
        }
    } while (p.next());
 
    cout<<endl<<endl;
    system("pause");
    return 0;
}


Vichislitel.h
Кликните здесь для просмотра всего текста
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
#pragma once
 
#include <vector>
#include <string>
 
class Vichislitel
{
public:
    Vichislitel();
    int Parse(std::string str);
 
private:
    enum class unit_type{null,chislo,obyedinit,plus,minus,umnozit,delit,stepen,l_skobka,r_skobka};
    class unit{
    public:
        unit(unit_type type, int value);
        unit_type type;
        int prioritet; //0=max prioritet
        int Result(int left, int right);
        int value;
        int Stepen(int base, int stepen);
    };
    std::vector <unit> virazenie;
    
    int Vichislit(std::vector<unit>* units, int start_pos, int end_pos); 
 
    int GetLeftPos(int start_pos);//Берёт первое число слева
    int GetRightPos(int start_pos);
    bool IsNumber(char c);
    int Number (char c);
};


Vichislitel.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "Vichislitel.h"
 
 
Vichislitel::Vichislitel(){;}
 
 
Vichislitel::unit::unit(Vichislitel::unit_type type, int value){
    unit::type = type;
    unit::value = value;
    if (type == unit_type::l_skobka) prioritet = 0;
    if (type == unit_type::r_skobka) prioritet = 0;
    if (type == unit_type::chislo) prioritet = 1;
    if (type == unit_type::obyedinit) prioritet = 2;
    if (type == unit_type::stepen) prioritet = 3;
    if (type == unit_type::delit) prioritet = 4;
    if (type == unit_type::umnozit) prioritet = 4;
    if (type == unit_type::plus) prioritet = 5;
    if (type == unit_type::minus) prioritet = 5;
    if (type == unit_type::null) prioritet = 6;
    return;
}
 
 
 
int Vichislitel::unit::Result(int left, int right){
    
    if (type==unit_type::null) {
        return -666;
    }
    
    if (type==unit_type::chislo) return value;
    if (type==unit_type::plus) return left+right;
    if (type==unit_type::minus) return left-right;
    if (type==unit_type::umnozit) return left*right;
    if (type==unit_type::delit) return left/right;
 
    if (type==unit_type::obyedinit){
        int right_digits = 1;
        while (right>=Stepen(10, right_digits)) right_digits++;
        return left*Stepen(10, right_digits)+right;
    }
    if (type==unit_type::stepen) return Stepen(left,right);
 
 
    return -666;
}
 
int Vichislitel::Vichislit(std::vector<unit>* units, int start_pos, int end_pos){
    
    //Избавляемся от скобок
    //Если видим открывающую скобку-считаем выражение до закрывающей
    //и ложим результат вместо открывающей собки, удаляя всё что в скобках
    bool is_skobki;
    do { //Ищем открывающую скобку, а за ней закрывающую
        //Важно, между ними никаких скобок
        is_skobki = false;
        int l_skobka_pos = 0;
        int r_skobka_pos = units->size()-1;
 
        for (int pos=start_pos; pos<=end_pos; pos++){
                if ((*units)[pos].type == unit_type::l_skobka) {
                    is_skobki = true;
                    l_skobka_pos = pos;
                }
                if ((*units)[pos].type == unit_type::r_skobka) {
                    is_skobki = true;
                    r_skobka_pos = pos;
                    break;
                }
        }
        //Тут мы имеем позиции левых и правых скобок (если есть)
        if (is_skobki){
            int result = Vichislit(units, l_skobka_pos+1, r_skobka_pos-1); 
            for (int pos = l_skobka_pos; pos<=r_skobka_pos; pos++){
                (*units)[pos].type=unit_type::null;
                (*units)[pos].prioritet=-1;
            }
            (*units)[l_skobka_pos].type = unit_type::chislo;
            (*units)[l_skobka_pos].value = result;
        }
    } while (is_skobki);
    //Так, теперь надо вычислить без скобок, согласно приоритетам
 
    for (int prioritet = 2; prioritet<= 5; prioritet++){
        for (int pos = start_pos+1; pos<end_pos; pos++){
            if ((*units)[pos].prioritet == prioritet){
                int left_pos = GetLeftPos(pos);
                int right_pos = GetRightPos(pos);
                int result = (*units)[pos].Result((*units)[left_pos].value, (*units)[right_pos].value);
                (*units)[left_pos].type = unit_type::null;
                (*units)[right_pos].type = unit_type::null;
                (*units)[pos].type = unit_type::chislo;
                (*units)[pos].value = result;
                (*units)[pos].prioritet = -1;
            }
        }
    }
    //Тут у нас должно остатся одно единственное число из всех юнитов
 
    for (int pos = start_pos; pos<=end_pos; pos++){
        if ((*units)[pos].type == unit_type::chislo) return (*units)[pos].value;
    }
 
    //Тут мы по идее не должны быть
    return -666;
}
 
int Vichislitel::GetLeftPos(int start_pos){
    for (int pos = start_pos-1; pos>=0; pos--){
        if (virazenie[pos].type == unit_type::chislo) return pos;
    }
    return -1;
}
 
int Vichislitel::GetRightPos(int start_pos){
    for (int pos = start_pos+1; pos<virazenie.size(); pos++){
        if (virazenie[pos].type == unit_type::chislo) return pos;
    }
    return -1;
}
 
 
int Vichislitel::unit::Stepen(int base, int stepen){
    int result = 1;
    for (int i=0; i<stepen; i++) result *= base;
    return result;
}
 
int Vichislitel::Parse(std::string str){
 
    virazenie.clear();
    for (int pos=0; pos<str.size(); pos++){
        if (str[pos] == '(')virazenie.push_back(unit(unit_type::l_skobka, 0));
        if (str[pos] == ')')virazenie.push_back(unit(unit_type::r_skobka, 0));
        if (IsNumber(str[pos])){
            virazenie.push_back(unit(unit_type::chislo, Number(str[pos])));
            if (pos<str.size()-1){
                if (IsNumber(str[pos+1])){
                    virazenie.push_back(unit(unit_type::obyedinit, 0));
                }
            }
        }
        if (str[pos] == '+')virazenie.push_back(unit(unit_type::plus, 0));
        if (str[pos] == '-')virazenie.push_back(unit(unit_type::minus, 0));
        if (str[pos] == '*')virazenie.push_back(unit(unit_type::umnozit, 0));
        if (str[pos] == '/')virazenie.push_back(unit(unit_type::delit, 0));
        if (str[pos] == '^')virazenie.push_back(unit(unit_type::stepen, 0));
    }
 
    return Vichislit(&virazenie, 0, virazenie.size()-1);
}
 
int Vichislitel::Number(char c){
    if (c == '0') return 0;
    if (c == '1') return 1;
    if (c == '2') return 2;
    if (c == '3') return 3;
    if (c == '4') return 4;
    if (c == '5') return 5;
    if (c == '6') return 6;
    if (c == '7') return 7;
    if (c == '8') return 8;
    if (c == '9') return 9;
    return -1;
}
 
bool Vichislitel::IsNumber(char c){
    if (Number(c) != -1) return true;
    return false;
}


Permutations.h (источник)
Кликните здесь для просмотра всего текста
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
/*
 * Permutations.h
 *
 *  Created on: 19.11.2013
 *      Author: alexey slovesnov
 */
 
#ifndef PERMUTATIONS_H_
#define PERMUTATIONS_H_
 
/*
 * PermutationType
 * PERMUTATIONS_WITHOUT_REPLACEMENTS k-permutations of n without replacements. Number of combinations equals n!/(n-k)!
 * PERMUTATIONS_WITH_REPLACEMENTS k-permutations of n with replacements. Number of combinations equals n^k
 * COMBINATION k-combination of n items. Number of combinations equals n!/(n-k)!/k!
*/
enum PermutationType { PERMUTATIONS_WITHOUT_REPLACEMENTS, PERMUTATIONS_WITH_REPLACEMENTS, COMBINATION };
 
class Permutations {
    int k,n;
    PermutationType type;
    int*i,*a;
    int index;
    void free();
 
    //add index
    void add();
 
public:
    Permutations();
    Permutations(const int k,const int n,const PermutationType type);
    bool init(const int k,const int n,const PermutationType type);
    bool next();
 
    inline const int getK()const {
        return k;
    }
 
    inline const int getN()const {
        return n;
    }
 
    inline const int* getIndexes()const {
        return type==PERMUTATIONS_WITHOUT_REPLACEMENTS?a:i;
    }
 
    inline const int getIndex(const int i)const {
        return getIndexes()[i];
    }
 
    //return number of combinations
    const int number()const;
 
    virtual ~Permutations();
};
 
#endif /* PERMUTATIONS_H_ */


Permutationc.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Permutations.cpp
 *
 *  Created on: 19.11.2013
 *      Author: alexey slovesnov
 */
 
#include <stdio.h>
#include "Permutations.h"
 
Permutations::Permutations(const int k,const int n,PermutationType type) {
    a=i=0;
    init(k,n,type);
}
 
Permutations::Permutations() {
    a=i=0;
}
 
const int Permutations::number()const{
    int i;
    int r=1;
    if(type==PERMUTATIONS_WITH_REPLACEMENTS){
        for(i=0;i<k;i++){
            r*=n;
        }
    }
    else{
        for(i=n-k+1;i<=n;i++){
            r*=i;
        }
        if(type==COMBINATION){
            for(i=2;i<=k;i++){
                r/=i;
            }
        }
    }
    return r;
 
}
 
bool Permutations::init(const int _k,const int _n,PermutationType _type){
    if(_k<=0 || _n<=0){
        printf("permutations. error n and k should be positive\n");
        return false;
    }
    if(_type!=PERMUTATIONS_WITH_REPLACEMENTS && _n<_k){
        printf("permutations. error n<k\n");
        return false;
    }
    free();
    n=_n;
    k=_k;
    type=_type;
 
    i=new int[k];
    a=new int[n];
 
    //init indexes
    index=0;
    i[0]=-1;
    add();
 
    return true;
}
 
void Permutations::add(){
    int j=index;
    int m,l;
    i[j]++;
    for(j++;j<k;j++){
        i[j] = type==COMBINATION ? i[j-1]+1 : 0;
    }
 
    if(type==PERMUTATIONS_WITHOUT_REPLACEMENTS){
        for(j=0;j<n;j++){
            a[j]=j;
        }
        for(j=0;j<k;j++){
            m=j+i[j];
            l=a[m];
            for( ; j!=k-1 && m>j ; m--){
                a[m]=a[m-1];
            }
            a[j]=l;
        }
    }
 
}
 
bool Permutations::next(){
    int l,j;
    for(j=k-1 ; j>=0 ; j--){
        if(type==PERMUTATIONS_WITHOUT_REPLACEMENTS){
            l=j;
        }
        else if(type==PERMUTATIONS_WITH_REPLACEMENTS){
            l=0;
        }
        else{
            l=k-1-j;
        }
        if(n-1!=i[j]+l){
            break;
        }
    }
    index=j;
 
    if(index==-1){
        return false;
    }
    add();
    return true;
}
 
void Permutations::free() {
    if(i){
        delete[]i;
        i=0;
    }
    if(a){
        delete[]a;
        a=0;
    }
}
 
Permutations::~Permutations() {
    free();
}


Если сделать releese версию - работает раз в 10 быстрее
0
04.05.2015, 06:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.05.2015, 06:59

Программа для решения СЛАУ
Здравствуйте,в общем, моя программа решает СЛАУ матричным методом, на основе...

Программа для решения уравнений
Помогите написать програму для уравнений z1=1-1/4*sin^2*2(альфа)+cos2(альфа)...

Нужна программа для решения интеграла
Всем доброго времени суток мне нужна программа для решения интеграла! Есть...


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

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

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