Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.88/2010: Рейтинг темы: голосов - 2010, средняя оценка - 4.88
ForEveR
В астрале
Эксперт С++
7995 / 4754 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
1

Задачи для тренировки и лучшего понимания

15.07.2010, 05:53. Просмотров 364180. Ответов 1272
Метки нет (Все метки)

Ребят. Кто-нибудь может дать задачу для тренировки? Приблизительно по всему курсу С++. Буду благодарен за сложную задачу, но которую способен сделать новичок-любитель. Затраты сил-времени не важно. Главное, чтобы это было интересно и не слишком рутинно. + Если найдется человек который даст задачу просьба помогать с кодом, который я буду себя скидывать. Не переписывать за меня, но указывать на ошибки и желательно объяснять. Заранее спасибо.

Список задач, решение которых присутствует в данной теме:
43
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.07.2010, 05:53
Ответы с готовыми решениями:

Прошу примеров для понимания INDY
Уважаемые коллеги и братья по интересу. Прошу примеров использования Indy UDP...

Ищу примеры для понимания взаимодействия Callback + event
Господа, подкиньте плиз какой-нибудь пример для понимания взаимодействия...

Элементарные программы, для лучшего понимания языка...
Здравствуйте. Вот сегодня решил что пора изучать с++. Есть пару задач. Начал...

Нужны задачи для тренировки
Киньте задачки на классы......а то в самоучителе, по которому я учу...

Нужны задачи для тренировки
Здравствуйте киньте пожалуйста задания по с++ для человека начинающего ...

1272
nikkka
Мат в 32 хода
236 / 171 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
06.08.2010, 21:04 601
fasked, ну это если писать реальный язык которым ты собираешся пользоватся, а не mCF+... я же для тренировки хочу...

Не по теме:

а с++ на чём писался? на с? а с?

0
fasked
06.08.2010, 21:15
  #602

Не по теме:

Цитата Сообщение от nikkka Посмотреть сообщение
ну это если писать реальный язык которым ты собираешся пользоватся, а не mCF+... я же для тренировки хочу...
а для тренировки значит можно тяп-ляп делать?! :ireful:
Цитата Сообщение от nikkka Посмотреть сообщение
а с++ на чём писался? на с? а с?
си++ - это язык. компилятор/интерпретатор можно на чем угодно написать, можно написать компилятор Си++ на Си++. вот некоторая информация - будет интересно почитаешь (правда на английском)

0
nikkka
Мат в 32 хода
236 / 171 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
06.08.2010, 21:16 603
Цитата Сообщение от fasked Посмотреть сообщение
си++ - это язык. компилятор/интерпретатор можно на чем угодно написать, можно написать компилятор Си++ на Си++. вот некоторая информация - будет интересно почитаешь (правда на английском)
как это? я могу написать интерпретатор mFC+ на mFC+?????!?!?!
0
Nameless One
Эксперт С++
5786 / 3435 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
06.08.2010, 21:20 604
Цитата Сообщение от nikkka Посмотреть сообщение
как это? я могу написать интерпретатор mFC+ на mFC+?????!?!?!
Прочитай инфу по ссылке, поймешь, что да как. Только вот особенности твоего "языка" не позволят тебе написать для него компилятор/интерпретатор

Добавлено через 1 минуту
Вот вкратце то же самое, если с английским туго...
1
fasked
06.08.2010, 21:23
  #605

Не по теме:

Цитата Сообщение от nikkka Посмотреть сообщение
как это? я могу написать интерпретатор mFC+ на mFC+?????!?!?!
чтобы такое произошло тебе придется развить его до состояния конечного автомата (по Тьюрингу) :D

1
nikkka
Мат в 32 хода
236 / 171 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
06.08.2010, 21:27 606
fasked, Nameless One, спс!...

Не по теме:

Цитата Сообщение от Nameless One Посмотреть сообщение
если с английским туго
не, с этим к счастию всё ок...



Добавлено через 2 минуты
fasked, но написать компилятор для языка L нужет какой нить другой язык, так?
0
fasked
Эксперт С++
4982 / 2561 / 241
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
06.08.2010, 22:17 607
Цитата Сообщение от nikkka Посмотреть сообщение
но написать компилятор для языка L нужет какой нить другой язык, так?
ну логично же, если других компиляторов для этого языка больше не существует
1
ForEveR
В астрале
Эксперт С++
7995 / 4754 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
07.08.2010, 04:55  [ТС] 608
Поднадоело играть и решил написать что-то типа калька, который вычисляет введенные пользователем выражение... Пока для +-/*

Получилось уныло чуть более чем полностью...

1) Считает только одно выражение. То есть 2+3-4 не покатит никак.
2) Сам код абсолютно не адекватен... Большие функции, наверняка это можно сделать короче.
3) Не будет работать с отрицательными числами.
4) Ну и прочие солидные и не очень недостатки.

Просьба помочь, поправить и направить куда нужно)

Код:

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
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
 
std::string check(std::string Str, std::string Delim);
void plus(std::string Str, std::string Delim);
void minus(std::string Str, std::string Delim);
void multi(std::string Str, std::string Delim);
void fract(std::string Str, std::string Delim);
 
int main()
{
    std::string Str;
    std::string Delim("+-*/");
    std::cout<<"Enter formul (for example 2+5) ";
    std::cin>>Str;
    if(Str.find('+')!=std::string::npos)
        plus(Str, Delim);
    else if(Str.find('-')!=std::string::npos)
        minus(Str, Delim);
    else if(Str.find('*')!=std::string::npos)
        multi(Str, Delim);
    else if(Str.find('/')!=std::string::npos)
        fract(Str, Delim);
    else
        std::cerr<<"There is no such option!\n";
    return 0;
}
 
std::string check(std::string Str, std::string Delim)
{
    size_t index=0;
    while((index=Str.find_first_of(Delim))!=std::string::npos)
        Str[index]=' ';
    return Str;
}
 
void plus(std::string Str, std::string Delim)
{
    double Sum=0;
    Str=check(Str, Delim);
    std::stringstream ss(Str);
    std::vector<double>Arr;
    std::string temp;
    while(ss>>temp)
        Arr.push_back((atof(temp.c_str())));
    Sum=Arr[0]+Arr[1];
    std::cout<< Sum <<'\n';
}
 
void minus(std::string Str, std::string Delim)
{
    double Minus=0;
    Str=check(Str, Delim);
    std::stringstream ss(Str);
    std::vector<double>Arr;
    std::string temp;
    while(ss>>temp)
        Arr.push_back((atof(temp.c_str())));
    Minus=Arr[0]-Arr[1];
    std::cout<< Minus <<'\n';
}
 
void multi(std::string Str, std::string Delim)
{
    double Mult=0;
    Str=check(Str, Delim);
    std::stringstream ss(Str);
    std::vector<double>Arr;
    std::string temp;
    while(ss>>temp)
        Arr.push_back((atof(temp.c_str())));
    Mult=Arr[0]*Arr[1];
    std::cout<< Mult <<'\n';
}
 
void fract(std::string Str, std::string Delim)
{
    double Fract=0;
    Str=check(Str, Delim);
    std::stringstream ss(Str);
    std::vector<double>Arr;
    std::string temp;
    while(ss>>temp)
        Arr.push_back((atof(temp.c_str())));
    try
    {
        if(Arr[1]==0)
            throw("Error. Can`t be 0\n");
        Fract=Arr[0]/Arr[1];
    }
    catch(char*s)
    {
        std::cerr<<s;
        exit(1);
    }
    std::cout<<Fract<<'\n';
}
1
Nameless One
Эксперт С++
5786 / 3435 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
07.08.2010, 07:13 609
Тоже калькулятор, тоже пока только операторы + - * /, только в постфиксной нотации (т.е. выражение заданно в виде: 27 5 + 2 6 / * (соотв. (27 + 5) * 2 / 6)):

calculator.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
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
#ifndef CALCULATOR_H
#define CALCULATOR_H
 
#include <stack>
#include <string>
#include <sstream>
#include <regex>
#include <stdexcept>
 
namespace my
{
    const std::string   plus    = "+";
    const std::string   minus   = "-";
    const std::string   mult    = "*";
    const std::string   divide  = "/";
 
    class calculator
    {
    public:
        static double result(std::string& rhs)
        {
            std::stack<double> stk;
            std::istringstream iss(rhs);
            std::string elem;
            while(iss >> elem)
            {
                if(isDouble(elem))
                {
                    double operand = std::stod(elem);
                    stk.push(operand);
                }
                else if(elem == plus)
                {
                    double operand2 = stk.top();
                    stk.pop();
                    double operand1 = stk.top();
                    stk.pop();
                    stk.push(operand1 + operand2);
                }
                else if(elem == minus)
                {
                    double operand2 = stk.top();
                    stk.pop();
                    double operand1 = stk.top();
                    stk.pop();
                    stk.push(operand1 - operand2);
                }
                else if(elem == mult)
                {
                    double operand2 = stk.top();
                    stk.pop();
                    double operand1 = stk.top();
                    stk.pop();
                    stk.push(operand1 * operand2);
                }
                else if(elem == divide)
                {
                    double operand2 = stk.top();
                    stk.pop();
                    double operand1 = stk.top();
                    stk.pop();
                    stk.push(operand1 / operand2);
                }
                else
                    throw(std::runtime_error
                        ("Unexpected token: \'" + elem + "\'"));
            }
            //В стеке должен остаться только одно значение
            if(stk.size() != 1)
                throw(std::runtime_error("Syntax error"));
            return stk.top();
        }
    private:
 
        static bool isDouble(const std::string& rhs)
        {
            std::regex re("^-?[1-9]+\\d*(?:\\.\\d+)?$");
            return std::regex_match(rhs, re);
        }
    };
};
 
#endif

main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <regex>
 
#include "calculator.h"
 
int main()
{
    try
    {
        std::string exp;
        while(std::getline(std::cin, exp))
            std::cout << "\tResult = " << my::calculator::result(exp) << std::endl;
    }
    catch(std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
    system("pause");
    return EXIT_SUCCESS;
}


Кстати, существует довольно-таки несложный алгоритм для преобразования выражения в инфиксной нотации в выражение в постфиксной нотации. ИМХО, именно таким образом и нужно запрограммировать калькулятор (ввел выражение в инфиксной нотации -> перевел в постфиксную -> вычислил), т.к. с появлением в нем хотя бы тех же скобок для переопределения приоритетов реализация сильно усложниться.
0
nikkka
Мат в 32 хода
236 / 171 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
07.08.2010, 09:50 610
Постепенно дополняю свой интерпретатор. Новые возможности: обявление переменных, инициализация переменных, вывод переменных. Пример программы:
Код
ZDAROVA
:The value of X is :
$x              //ключевой символ $ обозначает создание переменной. WARNING! перменная может состоять только из одной буквы.
x=5+1       //WARNING! Можно использовать знаки операций + - * /. НО НЕЛЬЗЯ ВВОДИТЬ ЧИСЛА БОЛЬШЕ 9-И!!!! неудобно, но исправлю...
GET(x)  //выводит значение переменной.
:^The value of Y is :
$y
y=5/2
GET(y)
VSO
Есть и свои плюсы. На пример можно создавать неограниченное кол. переменных.

Добавлено через 1 минуту
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
#include "iostream"
#include <cstring>
#include "conio.h"
using namespace std;
int hmv=0;
struct var
{
    char name;
    double val;
};
int wisi(var arr[], int size, char search)
{
    for(int i=0;i<size;i++)
        if(arr[i].name==search)
            return i;
}
double stoia(var & a)
{
    return a.val;
}
double stoi(char i)
{
    if(i=='1') return 1;
    else if(i=='2') return 2;
    else if(i=='3') return 3;
    else if(i=='4') return 4;
    else if(i=='5') return 5;
    else if(i=='6') return 6;
    else if(i=='7') return 7;
    else if(i=='8') return 8;
    else if(i=='9') return 9;
    else if(i=='0') return 0;
}
int main()
{
    int wif=0;
    char s[10][50];
    char temp;
    for(int i=0;i<10;i++)
    {
        cin.get(s[i],50).get();
        if(!strcmp(s[i],"VSO"))
            break;
        if(s[i][0]=='$')
            hmv++;
    }
    system("cls");
    var variable[hmv];
    if(strcmp(s[0],"ZDAROVA"))
    {    
        cout<<"Error! Can\'t find \"ZDAROVA\"!";
    }
    else
    {
        int k=1;
        for(int i=0;i<10;i++)
        {
            if(s[i][0]==':')
            {
                while(s[i][k]!='\0' && s[i][k]!=':')
                {
                    if(s[i][k]=='^') cout<<"\n";
                    else cout<<s[i][k];
                    k++;
                }//end of while
                k=1;
            }
            if(s[i][0]=='$')
            {
                variable[wif].name=s[i][1];
                wif++;
            }
            if(s[i][1]=='=')
            {
                if(s[i][3]=='+') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])+stoi(s[i][4]);
                if(s[i][3]=='-') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])-stoi(s[i][4]);
                if(s[i][3]=='*') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])*stoi(s[i][4]);
                if(s[i][3]=='/') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])/stoi(s[i][4]);
            }
            if(s[i][0]=='G' && s[i][1]=='E' && s[i][2]=='T' && s[i][3]=='(' && s[i][5]==')')
                cout<<variable[wisi(variable, hmv, s[i][4])].val;
        }//end of for
    } //end of else
    getch();
    return 0;
}
Добавлено через 6 минут
Протестируйте пожалуйста...
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
07.08.2010, 10:01 611
По поводу выражений очень много теории в этой теме: Пишем свой интерпретатор языка BASIC
Но там очень много букв, так что нужные места придётся поискать. Но в пределах первых 20 постов уже обозначена постановка задачи: вместо калькулятора простенький интерпретатор
2
nikkka
Мат в 32 хода
236 / 171 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
07.08.2010, 10:35 612
Теперь возможна и инициализация "на месте":
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
#include "iostream"
#include <cstring>
#include "conio.h"
using namespace std;
int hmv=0;
struct var
{
    char name;
    double val;
};
int wisi(var arr[], int size, char search)
{
    for(int i=0;i<size;i++)
        if(arr[i].name==search)
            return i;
}
double stoia(var a)
{
    return a.val;
}
double stoi(char i)
{
    if(i=='1') return 1;
    else if(i=='2') return 2;
    else if(i=='3') return 3;
    else if(i=='4') return 4;
    else if(i=='5') return 5;
    else if(i=='6') return 6;
    else if(i=='7') return 7;
    else if(i=='8') return 8;
    else if(i=='9') return 9;
    else if(i=='0') return 0;
}
int main()
{
    int wif=0;
    char s[10][50];
    char temp;
    for(int i=0;i<10;i++)
    {
        cin.get(s[i],50).get();
        if(!strcmp(s[i],"VSO"))
            break;
        if(s[i][0]=='$')
            hmv++;
    }
    system("cls");
    var variable[hmv];
    if(strcmp(s[0],"ZDAROVA"))
    {    
        cout<<"Error! Can\'t find \"ZDAROVA\"!";
    }
    else
    {
        int k=1;
        for(int i=0;i<10;i++)
        {
            if(s[i][0]==':')
            {
                while(s[i][k]!='\0' && s[i][k]!=':')
                {
                    if(s[i][k]=='^') cout<<"\n";
                    else cout<<s[i][k];
                    k++;
                }//end of cout-ing string
                k=1;
            }
            if(s[i][0]=='$')
            {
                variable[wif].name=s[i][1];
                wif++;
                if(strlen(s[i])==6)
                {
    
                        if(isdigit(s[i][3]) && isdigit(s[i][5]))
                        {
                            if(s[i][4]=='+') variable[wisi(variable, hmv, s[i][1])].val=stoi(s[i][3])+stoi(s[i][5]);
                            if(s[i][4]=='-') variable[wisi(variable, hmv, s[i][1])].val=stoi(s[i][3])-stoi(s[i][5]);
                            if(s[i][4]=='*') variable[wisi(variable, hmv, s[i][1])].val=stoi(s[i][3])*stoi(s[i][5]);
                            if(s[i][4]=='/') variable[wisi(variable, hmv, s[i][1])].val=stoi(s[i][3])/stoi(s[i][5]);
                        }
                        else if(isalpha(s[i][3]) && isdigit(s[i][5]))
                        {
                            if(s[i][4]=='+') variable[wisi(variable, hmv, s[i][1])].val=stoia(variable[wisi(variable, hmv, s[i][3])])+stoi(s[i][5]);     
                            if(s[i][4]=='-') variable[wisi(variable, hmv, s[i][1])].val=stoia(variable[wisi(variable, hmv, s[i][3])])-stoi(s[i][5]);
                            if(s[i][4]=='*') variable[wisi(variable, hmv, s[i][1])].val=stoia(variable[wisi(variable, hmv, s[i][3])])*stoi(s[i][5]);
                            if(s[i][4]=='/') variable[wisi(variable, hmv, s[i][1])].val=stoia(variable[wisi(variable, hmv, s[i][3])])/stoi(s[i][5]);
                        }
                        else if(isdigit(s[i][3]) && isalpha(s[i][5]))
                        {
                            if(s[i][4]=='+') variable[wisi(variable, hmv, s[i][1])].val=stoi(s[i][3])+stoia(variable[wisi(variable, hmv, s[i][5])]);     
                            if(s[i][4]=='-') variable[wisi(variable, hmv, s[i][1])].val=stoi(s[i][3])-stoia(variable[wisi(variable, hmv, s[i][5])]);
                            if(s[i][4]=='*') variable[wisi(variable, hmv, s[i][1])].val=stoi(s[i][3])*stoia(variable[wisi(variable, hmv, s[i][5])]);
                            if(s[i][4]=='/') variable[wisi(variable, hmv, s[i][1])].val=stoi(s[i][3])/stoia(variable[wisi(variable, hmv, s[i][5])]);
                        }
                }
                if(strlen(s[i])==4)
                {
                    variable[wisi(variable, hmv, s[i][1])].val=stoi(s[i][3]);
                }
            } //end of creating variable
            if(s[i][1]=='=')
            {
                if(strlen(s[i])==3)
                {
                    variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2]);
                }
                else
                {
                    if(isdigit(s[i][2]) && isdigit(s[i][4]))
                    {
                        if(s[i][3]=='+') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])+stoi(s[i][4]);
                        if(s[i][3]=='-') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])-stoi(s[i][4]);
                        if(s[i][3]=='*') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])*stoi(s[i][4]);
                        if(s[i][3]=='/') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])/stoi(s[i][4]);
                    }
                    else if(isalpha(s[i][2]) && isdigit(s[i][4]))
                    {
                        if(s[i][3]=='+') variable[wisi(variable, hmv, s[i][0])].val=stoia(variable[wisi(variable, hmv, s[i][2])])+stoi(s[i][4]);     
                        if(s[i][3]=='-') variable[wisi(variable, hmv, s[i][0])].val=stoia(variable[wisi(variable, hmv, s[i][2])])-stoi(s[i][4]);
                        if(s[i][3]=='*') variable[wisi(variable, hmv, s[i][0])].val=stoia(variable[wisi(variable, hmv, s[i][2])])*stoi(s[i][4]);
                        if(s[i][3]=='/') variable[wisi(variable, hmv, s[i][0])].val=stoia(variable[wisi(variable, hmv, s[i][2])])/stoi(s[i][4]);
                    }
                    else if(isdigit(s[i][2]) && isalpha(s[i][4]))
                    {
                        if(s[i][3]=='+') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])+stoia(variable[wisi(variable, hmv, s[i][4])]);     
                        if(s[i][3]=='-') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])-stoia(variable[wisi(variable, hmv, s[i][4])]);
                        if(s[i][3]=='*') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])*stoia(variable[wisi(variable, hmv, s[i][4])]);
                        if(s[i][3]=='/') variable[wisi(variable, hmv, s[i][0])].val=stoi(s[i][2])/stoia(variable[wisi(variable, hmv, s[i][4])]);
                    }
                }
            } //end of initialization
            if(s[i][0]=='G' && s[i][1]=='E' && s[i][2]=='T' && s[i][3]=='(' && s[i][5]==')')
                cout<<variable[wisi(variable, hmv, s[i][4])].val; //cout-ing variable
            
        }//end of for
    } //end of else
    getch();
    return 0;
}
1
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
07.08.2010, 10:48 613
nikkka, я в твоём коде не разбирался, но беглого взгляда оказалось достаточно, чтобы увидеть два потенциальных косяка. В функциях wisi и stoi у тебя возможен выход из процедуры с неинциализированным значением (например, при ошибке во внутренней логике в точке вызова). Такой код может вызвать трудноотлавливаемые ошибки исполнения, потому что точка проявления ошибки может оказаться слишком далеко от точки возникновения ошибки. Я бы в конце этих функций поставил ловушки недопустимых ситуаций (assert или на худой конец просто abort). Это позволит сократить дистанцию от точки возникновения ошибки до точки проявления. Вообще добавление статического контроля в виде assert'ов очень сильно упрощает жизнь и сокращает время отладки. 99% ошибок в моей практике ловится именно на assert'ах, а потому для их разбра в львиной доле случаев даже отладчик не нужен
1
nikkka
Мат в 32 хода
236 / 171 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
07.08.2010, 10:53 614
Evg, поправлю.
а как зделать так что бы я мог написать к слову x=54+12?
0
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 19,997
Записей в блоге: 30
07.08.2010, 11:00 615
Как в твоей программе - не знаю, мне просто лень было с ней разбираться Как делать по науке - дал ссылку выше. Про грамматический анализ, насколько я понял, ты прочитал. Далее идут пояснения, как из всего этого сделать лексический анализ. Тут просто вещь такая, что это нужно взять и один раз сделать самому. После чего вдруг сразу станет ясно очень многое. #pragma по началу не верил в то, что самому можно написать интерпретатор, обладая лишь базовыми знаниями. Теперь, думаю, он понимает, что написать можно всё что угодно, вопрос лишь во времени
1
fasked
Эксперт С++
4982 / 2561 / 241
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
07.08.2010, 16:36 616
Цитата Сообщение от Nameless One Посмотреть сообщение
Кстати, существует довольно-таки несложный алгоритм для преобразования выражения в инфиксной нотации в выражение в постфиксной нотации. ИМХО, именно таким образом и нужно запрограммировать калькулятор (ввел выражение в инфиксной нотации -> перевел в постфиксную -> вычислил), т.к. с появлением в нем хотя бы тех же скобок для переопределения приоритетов реализация сильно усложниться.
написал конвертер из инфиксной в постфиксную.
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
#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
 
#define OP_PLUS            '+'
#define OP_MINUS           '-'
#define OP_ASTERIX         '*'
#define OP_SLASH           '/'
#define OP_LEFT_BRACKET    '('
#define OP_RIGHT_BRACKET   ')'
#define OP_QUOTE           '\"'
 
const int code_matrix[5][4] = { 
   { 0, 0, 0, 0 },
   { 1, 2, 2, 1 },
   { 1, 1, 2, 1 },
   { 1, 1, 1, 1 },
   { 4, 2, 2, 3 }
};
 
int code_priority(char ch)
{
   switch(ch)
   {
   case OP_PLUS:
   case OP_MINUS: 
      return 1;
 
   case OP_ASTERIX:
   case OP_SLASH: 
      return 2;
 
   case OP_LEFT_BRACKET:
      return 3;
 
   case OP_RIGHT_BRACKET:
      return 4;
 
   default: 
      return 0;
   }
}
int get_code(int row, int col)
{
   return code_matrix[row][col];
}
 
int main()
{
   std::string expr;
   std::string out;
   std::stack<char> stack;
 
   std::cout << "input expression: ";
   std::cin >> expr;
 
   for(int i = 0, code = 0; i < expr.size(); ++i)
   {
      if(stack.empty())
         code = get_code(code_priority(expr[i]), 0);
      else
         code = get_code(code_priority(expr[i]), code_priority(stack.top()));
 
      switch(code)
      {
      case 0: // GREEN
         out += expr[i];
         break;
 
      case 1: // PUSH
         stack.push(expr[i]);
         break;
 
      case 2: // POP
         out += stack.top();
         stack.pop();
         i--;
         break;
 
      case 3: // DEL
         stack.pop();
         break;
 
      default:
         std::cerr << "error" << std::endl;
 
         system("PAUSE");
         return EXIT_FAILURE;
      }
   }
 
   while(!stack.empty())
   {
      if(stack.top() != OP_RIGHT_BRACKET && stack.top() != OP_LEFT_BRACKET)
         out += stack.top();
      stack.pop();
   }
 
   std::cout << out << std::endl;
 
   system("PAUSE");
   return EXIT_SUCCESS;
}
1
nikkka
07.08.2010, 16:41
  #617

Не по теме:

Цитата Сообщение от fasked Посмотреть сообщение
написал конвертер из инфиксной в постфиксную.
так как я ничего не понял, удаляюсь в дебри википедии... :D

0
ForEveR
07.08.2010, 16:50  [ТС]
  #618

Не по теме:

fasked, Красиво все через стек закручено. I like it

0
fasked
Эксперт С++
4982 / 2561 / 241
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
07.08.2010, 16:51 619
Цитата Сообщение от nikkka Посмотреть сообщение
так как я ничего не понял, удаляюсь в дебри википедии...
да тут все предельно просто. в постфиксной нотации в принципе нет проблем с приоритетами операций, так как нет скобок и оператор расположен после операндов, а не между как в привычной нам записи. соответственно считать проще и памяти уходит меньше. гуглить по словам "обратная польская запись"

Добавлено через 1 минуту
Цитата Сообщение от Lavroff Посмотреть сообщение
Красиво все через стек закручено. I like it
от switch-case конструкций надо бы избавиться. и еще там есть как минимум одна бесполезная функция.
0
ForEveR
В астрале
Эксперт С++
7995 / 4754 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
07.08.2010, 17:29  [ТС] 620
Мда... Видимо получилось хуже чем ночью...

Const_strings.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef _Const_string_H_
#define _Const_string_H_
 
#include <string>
 
namespace Operators
{
    const char Plus='+';
    const char Minus='-';
    const char Div='/';
    const char Mult='*';
}
 
#endif

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
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include "Const_strings.h"
 
using namespace Operators;
 
int main()
{
    std::string Str;
    std::cout<<"Enter string: ";
    std::getline(std::cin, Str);
    std::string Delim;
    Delim+=Plus; Delim+=Minus; Delim+=Div; Delim+=Mult;
    char ch='0';
    std::string::iterator p=Str.begin();
    p=(std::find_first_of(Str.begin(), Str.end(), Delim.begin(), Delim.end()));
    if(p!=Str.end())
        ch=*p;
    std::stringstream ss(Str);
    std::string Temp;
    std::vector<double> Vec;
    int i=0;
    while(ss>>Temp)
    {
        double l=atof(Temp.c_str());
        Vec.push_back(l);
    }
    if(ch=='+')
        std::cout<< Vec[0] + Vec[2] <<'\n';
    else if(ch=='-')
        std::cout<< Vec[0] + Vec[2] <<'\n';
    else if(ch=='*')
        std::cout<< Vec[0] * Vec[2] <<'\n';
    else if(ch=='/')
    {
        try
        {
            if(Vec[2]==0)
                throw(std::runtime_error("Can` t divide by zero!"));
            std::cout<< Vec[0] / Vec[2] <<'\n';
        }
        catch(std::exception&e)
        {
            std::cout<< e.what() <<'\n';
        }
    }
    else
        std::cerr<<"There is no such token\n";
    return 0;
}
0
07.08.2010, 17:29
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.08.2010, 17:29

Нужны простые задачи для тренировки
Добрый день всем:) Наверное подобных тем как я тут сотни,но всё же. Начал...

Какая база требуется для понимания C++?
Доброго времени суток! Возникло желание научиться работать в Си, но одолели...

Какую литературу для первоначального понимания С++ нужно учить
Что первоначальное для понимания нужно учить и от куда лучше вычитывать? ...


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

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

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