В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
1

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

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

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

Список задач, решение которых присутствует в данной теме:
44
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.07.2010, 05:53
Ответы с готовыми решениями:

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

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

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

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

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

Не по теме:

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

0
fasked
06.08.2010, 21:15
  #602

Не по теме:

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

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

Не по теме:

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



Добавлено через 2 минуты
fasked, но написать компилятор для языка L нужет какой нить другой язык, так?
0
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
06.08.2010, 22:17 607
Цитата Сообщение от nikkka Посмотреть сообщение
но написать компилятор для языка L нужет какой нить другой язык, так?
ну логично же, если других компиляторов для этого языка больше не существует
1
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
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
Эксперт С++
5828 / 3479 / 358
Регистрация: 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
Мат в 32 хода
237 / 172 / 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
21276 / 8298 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
07.08.2010, 10:01 611
По поводу выражений очень много теории в этой теме: Пишем свой интерпретатор языка BASIC
Но там очень много букв, так что нужные места придётся поискать. Но в пределах первых 20 постов уже обозначена постановка задачи: вместо калькулятора простенький интерпретатор
2
Мат в 32 хода
237 / 172 / 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
21276 / 8298 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
07.08.2010, 10:48 613
nikkka, я в твоём коде не разбирался, но беглого взгляда оказалось достаточно, чтобы увидеть два потенциальных косяка. В функциях wisi и stoi у тебя возможен выход из процедуры с неинциализированным значением (например, при ошибке во внутренней логике в точке вызова). Такой код может вызвать трудноотлавливаемые ошибки исполнения, потому что точка проявления ошибки может оказаться слишком далеко от точки возникновения ошибки. Я бы в конце этих функций поставил ловушки недопустимых ситуаций (assert или на худой конец просто abort). Это позволит сократить дистанцию от точки возникновения ошибки до точки проявления. Вообще добавление статического контроля в виде assert'ов очень сильно упрощает жизнь и сокращает время отладки. 99% ошибок в моей практике ловится именно на assert'ах, а потому для их разбра в львиной доле случаев даже отладчик не нужен
1
Мат в 32 хода
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
07.08.2010, 10:53 614
Evg, поправлю.
а как зделать так что бы я мог написать к слову x=54+12?
0
Evg
Эксперт CАвтор FAQ
21276 / 8298 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
07.08.2010, 11:00 615
Как в твоей программе - не знаю, мне просто лень было с ней разбираться Как делать по науке - дал ссылку выше. Про грамматический анализ, насколько я понял, ты прочитал. Далее идут пояснения, как из всего этого сделать лексический анализ. Тут просто вещь такая, что это нужно взять и один раз сделать самому. После чего вдруг сразу станет ясно очень многое. #pragma по началу не верил в то, что самому можно написать интерпретатор, обладая лишь базовыми знаниями. Теперь, думаю, он понимает, что написать можно всё что угодно, вопрос лишь во времени
1
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 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
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
07.08.2010, 16:51 619
Цитата Сообщение от nikkka Посмотреть сообщение
так как я ничего не понял, удаляюсь в дебри википедии...
да тут все предельно просто. в постфиксной нотации в принципе нет проблем с приоритетами операций, так как нет скобок и оператор расположен после операндов, а не между как в привычной нам записи. соответственно считать проще и памяти уходит меньше. гуглить по словам "обратная польская запись"

Добавлено через 1 минуту
Цитата Сообщение от Lavroff Посмотреть сообщение
Красиво все через стек закручено. I like it
от switch-case конструкций надо бы избавиться. и еще там есть как минимум одна бесполезная функция.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.08.2010, 17:29
Помогаю со студенческими работами здесь

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

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

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

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru