Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.54/2345: Рейтинг темы: голосов - 2345, средняя оценка - 4.54
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562

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

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

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

Список задач, решение которых присутствует в данной теме:
44
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.07.2010, 05:53
Ответы с готовыми решениями:

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

Задачи для тренировки и лучшего понимания языка
Предлагаю в этой теме размещать задачи, которые помогут новичкам (и не только) более детально разобраться в основах языка. При размещении...

Литература для лучшего понимания сути программирования
Привет! Подскажите литературу, которая поможет разобраться в сути самого процесса программирования, поможет изучить теорию алгоритмов,...

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

Не по теме:

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

0
06.08.2010, 21:15

Не по теме:

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

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

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

Не по теме:

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

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

Не по теме:

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



Добавлено через 2 минуты
fasked, но написать компилятор для языка L нужет какой нить другой язык, так?
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
06.08.2010, 22:17
Цитата Сообщение от nikkka Посмотреть сообщение
но написать компилятор для языка L нужет какой нить другой язык, так?
ну логично же, если других компиляторов для этого языка больше не существует
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
07.08.2010, 04:55  [ТС]
Поднадоело играть и решил написать что-то типа калька, который вычисляет введенные пользователем выражение... Пока для +-/*

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

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
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
07.08.2010, 07:13
Тоже калькулятор, тоже пока только операторы + - * /, только в постфиксной нотации (т.е. выражение заданно в виде: 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
Мат в 32 хода
 Аватар для nikkka
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
07.08.2010, 09:50
Постепенно дополняю свой интерпретатор. Новые возможности: обявление переменных, инициализация переменных, вывод переменных. Пример программы:
Code
1
2
3
4
5
6
7
8
9
10
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
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.08.2010, 10:01
По поводу выражений очень много теории в этой теме: Пишем свой интерпретатор языка BASIC
Но там очень много букв, так что нужные места придётся поискать. Но в пределах первых 20 постов уже обозначена постановка задачи: вместо калькулятора простенький интерпретатор
2
Мат в 32 хода
 Аватар для nikkka
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
07.08.2010, 10:35
Теперь возможна и инициализация "на месте":
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
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.08.2010, 10:48
nikkka, я в твоём коде не разбирался, но беглого взгляда оказалось достаточно, чтобы увидеть два потенциальных косяка. В функциях wisi и stoi у тебя возможен выход из процедуры с неинциализированным значением (например, при ошибке во внутренней логике в точке вызова). Такой код может вызвать трудноотлавливаемые ошибки исполнения, потому что точка проявления ошибки может оказаться слишком далеко от точки возникновения ошибки. Я бы в конце этих функций поставил ловушки недопустимых ситуаций (assert или на худой конец просто abort). Это позволит сократить дистанцию от точки возникновения ошибки до точки проявления. Вообще добавление статического контроля в виде assert'ов очень сильно упрощает жизнь и сокращает время отладки. 99% ошибок в моей практике ловится именно на assert'ах, а потому для их разбра в львиной доле случаев даже отладчик не нужен
1
Мат в 32 хода
 Аватар для nikkka
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
07.08.2010, 10:53
Evg, поправлю.
а как зделать так что бы я мог написать к слову x=54+12?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.08.2010, 11:00
Как в твоей программе - не знаю, мне просто лень было с ней разбираться Как делать по науке - дал ссылку выше. Про грамматический анализ, насколько я понял, ты прочитал. Далее идут пояснения, как из всего этого сделать лексический анализ. Тут просто вещь такая, что это нужно взять и один раз сделать самому. После чего вдруг сразу станет ясно очень многое. #pragma по началу не верил в то, что самому можно написать интерпретатор, обладая лишь базовыми знаниями. Теперь, думаю, он понимает, что написать можно всё что угодно, вопрос лишь во времени
1
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
07.08.2010, 16:36
Цитата Сообщение от 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
07.08.2010, 16:41

Не по теме:

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

0
07.08.2010, 16:50  [ТС]

Не по теме:

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

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

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

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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.08.2010, 17:29
Помогаю со студенческими работами здесь

Набор задачь для тренировки и улучшения понимания программирования
Добрый вечер всем. Если кто знает модскажите где можно найти подобный набор задачь...

Проверить на правильность и закомментировать весь код для лучшего понимания
Всем здравствуйте. Условие задачи - Заданная матрица целых чисел размером (N, N). Найти среднее арифметическое элементов в окрашенной...

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

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

Нужны задачи для тренировки
Вот не давно был школьный этап по программирование в школе(олимпиады). Меня закинули на городскую, вот только писал ту олимпиаду на...


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

Или воспользуйтесь поиском по форуму:
620
Закрытая тема Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru