Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 2744, средняя оценка - 4.89
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
#1

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

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

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

Список задач, решение которых присутствует в данной теме:
Лучшие ответы (59)
Сообщение: #857841 Сообщение: #857861 Сообщение: #858352 Сообщение: #859371 Сообщение: #860160 Сообщение: #860255 Сообщение: #860259 Сообщение: #860317 Сообщение: #860368 Сообщение: #860466 Сообщение: #860508 Сообщение: #860720 Сообщение: #861091 Сообщение: #862174 Сообщение: #862617 Сообщение: #867259 Сообщение: #870298 Сообщение: #872053 Сообщение: #876456 Сообщение: #880114 Сообщение: #882889 Сообщение: #884418 Сообщение: #886414 Сообщение: #886989 Сообщение: #887733 Сообщение: #888464 Сообщение: #888487 Сообщение: #888941 Сообщение: #888947 Сообщение: #889040 Сообщение: #889450 Сообщение: #889587 Сообщение: #891772 Сообщение: #891790 Сообщение: #891862 Сообщение: #897758 Сообщение: #897782 Сообщение: #906325 Сообщение: #907991 Сообщение: #943672 Сообщение: #943700 Сообщение: #967735 Сообщение: #1053777 Сообщение: #1054209 Сообщение: #1083853 Сообщение: #1083928 Сообщение: #1131058 Сообщение: #1131359 Сообщение: #1273743 Сообщение: #1275465 Сообщение: #1276743 Сообщение: #1279215 Сообщение: #1282583 Сообщение: #1309088 Сообщение: #1315633 Сообщение: #1366395 Сообщение: #1550164 Сообщение: #1603678 Сообщение: #1604364
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.07.2010, 05:53     Задачи для тренировки и лучшего понимания
Посмотрите здесь:

C++ Какой компилятор выбрать для лучшего изучения С++ по книге Берна Страуструпа?п
C++ Элементарные программы, для лучшего понимания языка...
Нужны задачи для тренировки C++
C++ Киньте задачки для тренировки
C++ Нужны простые задачи для тренировки
Нужны задачи для тренировки C++
На соревнованиях по фигурному катанию оценки заносятся в компьютер. Составить программу для вывода на экран лучшего результата после каждого выступлен C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nikkka
Мат в 32 хода
235 / 170 / 8
Регистрация: 10.09.2009
Сообщений: 1,096
08.08.2010, 16:52     Задачи для тренировки и лучшего понимания #641
Опять! Теперь череез простую матрицу...
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
#include <iostream>
#include <string>
#include <conio.h>
int main()
{
    int sizee=0;
    std::string s=" a bc def ghik ";
    for(int j=0;j<s.length();j++)
        if(s[j]==' ')
            sizee++;
    char c[sizee-1][10];
    int k=0;
    int isfree=0;
    for(int i=0;i<s.length();i++)
    {
        if(s[i]==' ')
        {
            k=i+1;
            std::cout<<s[k];
            while(s[k]!=' ')
            {    
                c[isfree][k+1-i]=s[k];
                k++;
            }
            isfree++;
        }
    }
    for(int l;l<sizee-1;l++)
        std::cout<<c[l]<<"\n";
    getch();
    return 0;
}
easybudda
Эксперт С++
9438 / 5461 / 925
Регистрация: 25.07.2009
Сообщений: 10,481
08.08.2010, 17:15     Задачи для тренировки и лучшего понимания #642
Цитата Сообщение от nikkka Посмотреть сообщение
Опять! Теперь череез простую матрицу...
На С++ по-моему незачем так делать... вот на С с массивом:
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define DELIM " \t\n"
    
int main(void){
    char buf[BUFSIZ], **array, * p;
    int cnt, i;
    
    while ( 1 ){
        printf("\nString: ");
        if ( ! fgets(buf, BUFSIZ, stdin) ){
            perror("fgets");
            exit(1);
        }
        if ( *buf == '\n' )
            break;
        
        array = NULL;
        cnt = 0;
        for ( p = strtok(buf, DELIM); p; p = strtok(NULL, DELIM) ){
            if ( ( array = (char**)realloc(array, sizeof(char*) * (cnt + 1)) ) == NULL ){
                perror("realloc");
                exit(1);
            }
            if ( ( array[cnt++] = strdup(p) ) == NULL ){
                perror("strdup");
                exit(1);
            }
        }
        if ( ! array || ! cnt ){
            fprintf(stderr, "No words found!\n");
            exit(1);
        }
        printf("*** %d words:\n", cnt);
        for ( i = 0; i < cnt; ++i )
            printf("%s\n", array[i]);
        
        for ( i = 0; i < cnt; ++i )
            free(array[i]);
        free(array);
    }
    
    exit(0);
}
Evg
Эксперт CАвтор FAQ
17378 / 5616 / 350
Регистрация: 30.03.2009
Сообщений: 15,374
Записей в блоге: 26
08.08.2010, 17:28     Задачи для тренировки и лучшего понимания #643
nikkka, ты объявил массив указателй, но указатели у тебя все неинициализированы (т.е. память под них не выделена). В процессе нарезки на токены ты должен найти в строке позицию начала токена, затем позицию конца токена, после чего ты можешь вычислить длину строки для токена, после этого нужно заказать память такого размера и только потом скопировать в эту память значение токена

Это что касается того, что ты сейчас написал. Но в реальной жизни у тебя не будет разделения пробелами. Т.е. при твоём подходе ты не сможешь вычислить "2+3", потому как у тебя это одним токеном запишется.

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

Добавлено через 48 секунд
Я писал про пост #657. А тут ты скорее всего NULL-терминатор потерял
nikkka
Мат в 32 хода
235 / 170 / 8
Регистрация: 10.09.2009
Сообщений: 1,096
08.08.2010, 17:31     Задачи для тренировки и лучшего понимания #644
Цитата Сообщение от Evg Посмотреть сообщение
А тут ты скорее всего NULL-терминатор потерял
чегой?
Evg
Эксперт CАвтор FAQ
17378 / 5616 / 350
Регистрация: 30.03.2009
Сообщений: 15,374
Записей в блоге: 26
08.08.2010, 17:32     Задачи для тренировки и лучшего понимания #645
Цитата Сообщение от nikkka Посмотреть сообщение
чегой?
В строках 20-24 ты формируешь массив char'ов. Чтобы он нормально мог трактоваться как строка, в конец надо ещё налепить символ '\0'
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
08.08.2010, 17:32     Задачи для тренировки и лучшего понимания #646
такой вопрос:
допустим есть список константных ключевых выражений:
C++
1
2
3
4
5
6
const std::string Addition       = "+";
const std::string Substraction   = "-";
const std::string Multiplication = "*";
const std::string Division       = "/";
const std::string LeftBracket    = "(";
const std::string RightBracket   = ")";
к каждому ключевому выражению следует определить приоритет. можно ли сделать это с помощью std::map? например, вот так.
C++
1
2
3
std::map<std::string, int> priority;
priority[Addition] = 1;
priority[Substraction] = 1;
а потом осуществять определение приоритета кейворда таким образом:
C++
1
2
3
4
5
6
int code = 0;                /* приоритет */
std::string word = Addition; /* или любое другое ключевое слово */
std::map<std::string, int>::iterator it;
 
if((it = priority.find(word)) != priority.end())
   code = it->second;
перемудрил?
nikkka
Мат в 32 хода
235 / 170 / 8
Регистрация: 10.09.2009
Сообщений: 1,096
08.08.2010, 17:51     Задачи для тренировки и лучшего понимания #647
Цитата Сообщение от Evg Посмотреть сообщение
В строках 20-24 ты формируешь массив char'ов. Чтобы он нормально мог трактоваться как строка, в конец надо ещё налепить символ '\0'
а разве это не происходит автомат.?
rangerx
1931 / 1540 / 141
Регистрация: 31.05.2009
Сообщений: 2,905
08.08.2010, 18:04     Задачи для тренировки и лучшего понимания #648
Цитата Сообщение от fasked Посмотреть сообщение
перемудрил?

C++
1
2
3
4
5
6
7
8
int getPriority(const std::string& lexeme)
{
    if(lexeme == "*" || lexeme == "/") return 3;
    if(lexeme == "+" || lexeme == "-") return 2;
    if(lexeme == "(") return 1;
 
    return 0; 
}
думаю этого вполне достаточно
Evg
Эксперт CАвтор FAQ
17378 / 5616 / 350
Регистрация: 30.03.2009
Сообщений: 15,374
Записей в блоге: 26
08.08.2010, 18:40     Задачи для тренировки и лучшего понимания #649
Цитата Сообщение от nikkka Посмотреть сообщение
а разве это не происходит автомат.?
Си - язык низкого уровня. Там ничто автоматом не делается
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
08.08.2010, 19:03     Задачи для тренировки и лучшего понимания #650
вот она, ужасная и нечищенная, первая версия калькулятора. сейчас буду это упрощать, очищать и разбивать на классы. но работает
выполняет операции деления, сложения, умножения и вычитания с учетом скобок.

Выражения вводятся через пробел (пока что только через пробел). каждый операнд и операция должны быть отделены пробелом (даже скобка). то есть в таком виде:
Код
15 + 20 * ( 21 - 5.8 )
сильно не бейте, я тут вставляю код со всеми перемудреностями и избыточностями
никаких проверок на ошибки я тоже не делал.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <iostream>
#include <iterator>
 
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
 
#include <stack>
#include <map>
 
std::vector<std::string> InitialiseKeywords()
{
   std::vector<std::string> Keywords;
 
   Keywords.push_back("+");
   Keywords.push_back("-");
   Keywords.push_back("*");
   Keywords.push_back("/");
 
   return Keywords;
}
 
std::vector<std::string> DivideExpressionOnTokens(const std::string &line)
{
   std::stringstream ss(line);
   std::vector<std::string> res;
 
   std::copy(std::istream_iterator<std::string>(ss), std::istream_iterator<std::string>(), std::back_inserter(res));
   
   return res;
}
 
std::map<std::string, int> InitialisePriorityTable()
{
   std::map<std::string, int> priority;
 
   priority["+"] = 1;
   priority["-"] = 1;
   priority["*"] = 2;
   priority["/"] = 2;
   priority["("] = 3;
   priority[")"] = 4;
 
   return priority;
}
 
std::vector<std::string> ConvertInfixToPostfixNotation(const std::vector<std::string> &Expression)
{
   int ActionCodesMatrix[5][4] = {
      { 0, 0, 0, 0 },
      { 1, 2, 2, 1 },
      { 1, 1, 2, 1 },
      { 1, 1, 1, 1 },
      { 4, 2, 2, 3 }
   };
 
   std::vector<std::string> OutTokens;
 
   std::map<std::string, int> Priorities = InitialisePriorityTable();
   std::stack<std::string> TokenStack;
 
   for(std::vector<std::string>::size_type i = 0; i < Expression.size(); ++i)  
   {
      // Set Priority Code
      int ExpressionCode = 0;
      int TokenStackCode = 0;
      std::map<std::string, int>::iterator it;
 
      if((it = Priorities.find(Expression[i])) != Priorities.end())
         ExpressionCode = it->second;
      if(TokenStack.empty() != true && (it = Priorities.find(TokenStack.top())) != Priorities.end())
         TokenStackCode = it->second;
 
      // Set Action Code
      int ActionCode = ActionCodesMatrix[ExpressionCode][TokenStackCode];
 
      // Action
      if(ActionCode == 0)
      {
         OutTokens.push_back(Expression[i]);
      }
 
      else if(ActionCode == 1)
      {
         TokenStack.push(Expression[i]);
      }
 
      else if(ActionCode == 2)
      {
         OutTokens.push_back(TokenStack.top());
         TokenStack.pop();
 
         --i;
      }
 
      else if(ActionCode == 3)
      {
         TokenStack.pop();
      }
 
      else
      {
         // TODO Error
      }
   }
 
   // Pop Stack
   while(TokenStack.empty() != true)
   {
      if(TokenStack.top() != "(" && TokenStack.top() != ")")
         OutTokens.push_back(TokenStack.top());
 
      TokenStack.pop();
   }
 
   return OutTokens;
}
 
double CalculatePostfixExpression(const std::vector<std::string> &PostfixExpression)
{
   std::stack<double> TokenStack;
   std::vector<std::string> Keywords = InitialiseKeywords();
 
   for(std::vector<std::string>::size_type i = 0; i < PostfixExpression.size(); ++i)
   {
      std::vector<std::string>::iterator it;
 
      if((it = std::find(Keywords.begin(), Keywords.end(), PostfixExpression[i])) == Keywords.end())
      {
         TokenStack.push(std::stod(PostfixExpression[i]));
      }
 
      else if(it->compare("+") == 0)
      {
         double op1 = TokenStack.top();
         TokenStack.pop();
 
         double op2 = TokenStack.top();
         TokenStack.pop();
 
         TokenStack.push(op2 + op1);
      }
 
      else if(it->compare("-") == 0)
      {
         double op1 = TokenStack.top();
         TokenStack.pop();
 
         double op2 = TokenStack.top();
         TokenStack.pop();
 
         TokenStack.push(op2 - op1);
      }
 
      else if(it->compare("*") == 0)
      {
         double op1 = TokenStack.top();
         TokenStack.pop();
 
         double op2 = TokenStack.top();
         TokenStack.pop();
 
         TokenStack.push(op2 * op1);
      }
 
      else if(it->compare("/") == 0)
      {
         double op1 = TokenStack.top();
         TokenStack.pop();
 
         double op2 = TokenStack.top();
         TokenStack.pop();
 
         TokenStack.push(op2 / op1);
      }
   }
 
   return TokenStack.top();
}
 
int main()
{
   //
   std::string SourceExpression;
 
   std::vector<std::string> InfixTokens;
   std::vector<std::string> PostfixTokens;
 
   std::cout << "Input Infix Expression: ";
   std::getline(std::cin, SourceExpression);
 
   InfixTokens = DivideExpressionOnTokens(SourceExpression);
 
   PostfixTokens = ConvertInfixToPostfixNotation(InfixTokens);
 
   std::cout << "Expression in Postfix Notation: ";
   std::copy(PostfixTokens.begin(), PostfixTokens.end(), std::ostream_iterator<std::string>(std::cout, " "));
   std::cout << std::endl;
 
   std::cout << "RESULT: " << CalculatePostfixExpression(PostfixTokens) << std::endl;
 
   system("pause");
   return 0;
}
alex_x_x
бжни
2445 / 1650 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
08.08.2010, 21:53     Задачи для тренировки и лучшего понимания #651
c такой задачей справляются простейшие s-грамматики рекурсивным спуском
nikkka
Мат в 32 хода
235 / 170 / 8
Регистрация: 10.09.2009
Сообщений: 1,096
08.08.2010, 22:23     Задачи для тренировки и лучшего понимания #652
Не удержался

Не по теме:

Цитата Сообщение от fasked Посмотреть сообщение
сильно не бейте
И тут fasked понял что его будут бить. Может даже ногами. ©

fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
09.08.2010, 00:37     Задачи для тренировки и лучшего понимания #653
Цитата Сообщение от nikkka Посмотреть сообщение
И тут fasked понял что его будут бить. Может даже ногами.
я исправлюсь! обязательно, обязательно!
Вот даже простейший анализатор арифметического выражения сочинил. Потом прикручу его к калькулятору.
В общем суть такова: анализатор принимает на вход строку и возвращает список токенов.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "parser.h"
 
int main()
{
   Parser pars;
   std::list<Token> expr = pars.DivideTextOnTokens("VAL + B/C *       2");
 
   for(auto it = expr.begin(); it != expr.end(); ++it)
      if(it->GetTokenText() != " ")
         std::cout << it->GetTokenText();
   std::cout << std::endl;
 
   system("PAUSE");
}
пробелы я решил не удалять из списка токенов. не знаю почему. может пригодятся
определение типа токена еще тоже не сделал... устал чего-то

HEADER_TOKEN_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
#pragma once
 
#include <string>
 
enum TokenTypes
{
   Unknown = 0,
   Integer,
   Operator
};
 
class Token
{
public:
   Token();
   Token(const Token &w);
   Token(const std::string &TokenText, TokenTypes TokenType);
 
   TokenTypes GetTokenType() const;
   std::string GetTokenText() const;
 
private:
   TokenTypes Type; 
   std::string Text;
};
 
 
Token::Token() : Type(Unknown)
{
}
 
Token::Token(const Token &w) : Type(w.Type), Text(w.Text)
{
}
 
Token::Token(const std::string &TokenText, TokenTypes TokenType)
{
   Text = TokenText;
   Type = TokenType;
}
 
 
TokenTypes Token::GetTokenType() const
{
   return Type;
}
 
std::string Token::GetTokenText() const
{
   return Text;
}

HEADER_PARSER_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
#pragma once
 
#include "token.h"
#include <list>
#include <vector>
#include <algorithm>
 
#include <iostream>
 
class Parser
{
public:
   Parser();
 
public:
   std::list<Token> DivideTextOnTokens(const std::string &Text);
 
private:
   Token GetFirstTokenFromText(const std::string &Text);
 
private: 
   static const std::string::size_type EndOffset = -1;
   std::string::size_type Offset;
 
   std::list<Token> Tokens;
 
   //std::vector<std::string> Keywords;
   std::string Operators;
   std::string Dividers;
};
 
Parser::Parser() : Offset(0)
{
   Operators = "-+*/()";
   Dividers = " ";
}
 
 
Token Parser::GetFirstTokenFromText(const std::string &Text)
{
   std::string ReturnTokenText;
   std::string Delimeters = Operators + Dividers;
   std::string::size_type DelimPosition = Text.find_first_of(Delimeters, Offset);
 
   if(DelimPosition == Text.npos)
   {
      ReturnTokenText = Text.substr(Offset);
      Offset = EndOffset;
   }
   else
   {
      ReturnTokenText = Text.substr(Offset, std::max((std::string::size_type)1, DelimPosition - Offset));
      Offset = std::max(DelimPosition, Offset + 1);
   }
 
   return Token(ReturnTokenText, TokenTypes::Unknown);
}
 
std::list<Token> Parser::DivideTextOnTokens(const std::string &Text)
{
   if(Text.empty())
   {
      std::cerr << "Parser::DivideTextOnTokens - Text is Empty" << std::endl;
   }
 
   while(Offset != EndOffset)
   {
      Token CurrentToken(GetFirstTokenFromText(Text));
      Tokens.push_back(CurrentToken);
   }
 
   return Tokens;
}


Вроде так неплохо вышло, а главное, что потом в принципе можно будет расширить.
В смысле на следующих этапах вычислений калькулятора можно предполагать, что список токенов уже составлен правильно, ну на край для тестирования составить его вручную.

Да и чуть самое главное не забыл. После запуска программки, текст которой приведен выше на экран выводится следующее:
Код
VAL+B/C*2
Сам список содержит такие элементы:
Код
+		[0]	{Type=Unknown Text="VAL" }	Token
+		[1]	{Type=Unknown Text=" " }	Token
+		[2]	{Type=Unknown Text="+" }	Token
+		[3]	{Type=Unknown Text=" " }	Token
+		[4]	{Type=Unknown Text="B" }	Token
+		[5]	{Type=Unknown Text="/" }	Token
+		[6]	{Type=Unknown Text="C" }	Token
+		[7]	{Type=Unknown Text=" " }	Token
+		[8]	{Type=Unknown Text="*" }	Token
+		[9]	{Type=Unknown Text=" " }	Token
+		[10]	{Type=Unknown Text=" " }	Token
+		[11]	{Type=Unknown Text=" " }	Token
+		[12]	{Type=Unknown Text=" " }	Token
+		[13]	{Type=Unknown Text=" " }	Token
+		[14]	{Type=Unknown Text=" " }	Token
+		[15]	{Type=Unknown Text=" " }	Token
+		[16]	{Type=Unknown Text="2" }	Token
Как я уже сказал, что пробелы не убирал и определение типа токена тоже не делал.
Поэтому видно, что все токены имеют неизвестный тип, а каждый пробел представлен как отдельный токен.

Почистить от пробелов и такой список можно легко подавать на конвертирование в постфиксную нотацию, а потом уже и на вычисление.
Получается три абстрактных модуля. Которые в принципе не зависят друг от друга, а только от входящих данных.
nikkka
Мат в 32 хода
235 / 170 / 8
Регистрация: 10.09.2009
Сообщений: 1,096
09.08.2010, 17:59     Задачи для тренировки и лучшего понимания #654
Вот мой калькулятор. Вводите что хотите (отрицательные, положительные, дробные числа) с любым кол. скобок. Он выведит ответ. Но есть проблемма. Непонятно почему, он выводит так же все числа полученные в процесе вычисления. Ищу причину...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include <iostream>
#include <string>
#include <conio.h>
#include <sstream>
const int size=20;
std::ostringstream stm;
void strcpy(char c[], std::string s)
{
    int i;
    for(i=0;i<s.length();i++)
        c[i]=s[i];
    c[i]='\0';
}
class stek
{
    private:
        char array[size];
    public:
        stek();
        void additem(char c);
        void substractitem(void);
        std::string stekins(void);
        char upperitem(void);
};
stek::stek()
{
    for(int i=0;i<size;i++)
        array[i]='\0';
}
void stek::additem(char c)
{
    for(int i=size-1;i>=0;i--)
        array[i]=array[i-1];
    array[0]=c;
}
void stek::substractitem(void)
{
    for(int i=0;i<size-1;i++)
        array[i]=array[i+1];
    array[size-1]='\0';
}
std::string stek::stekins(void)
{
    std::string s0;
    for(int i=0;i<size;i++)
        if(array[i]!='\0')
           s0=s0+array[i]+" ";
    return s0;
}
char stek::upperitem(void)
{
    return array[0];
}
class stek2
{
    private:
        std::string s[size];
    public:
        stek2();
        void addtoken(std::string a);
        void evaluate(void);
        std::string uppertoken(void);
        void substracttoken(void);
        void clear(void);
};
void stek2::clear(void)
{
    for(int i=0;i<size;i++)
        s[i]=" ";
}
stek2::stek2()
{
    for(int i=0;i<size;i++)
        s[i]=" ";
}
void stek2::substracttoken(void)
{
    for(int i=0;i<size-1;i++)
        s[i]=s[i+1];
    s[size-1]=" ";
}
std::string stek2::uppertoken(void)
{
    return s[0];
}
void stek2::addtoken(std::string a)
{
    for(int i=size;i>0;i--)
        if(i!=size)
            s[i]=s[i-1];
    s[0]=a;
}
void stek2::evaluate(void)
{
    char c1[10];
    char c2[10];
    strcpy(c1,s[1]);
    strcpy(c2,s[2]);
    if(s[0]=="+")
    {
        double temp=atof(c1)+atof(c2);
        substracttoken();
        substracttoken();
        substracttoken();
        stm<<temp;
        addtoken(stm.str());
    }
    else if(s[0]=="*")
    {
        double temp=atof(c1)*atof(c2);
        substracttoken();
        substracttoken();
        substracttoken();
        stm<<temp;
        addtoken(stm.str());
    }
    if(s[0]=="-")
    {
        double temp=atof(c2)-atof(c1);
        substracttoken();
        substracttoken();
        substracttoken();
        stm<<temp;
        addtoken(stm.str());
    }
    else if(s[0]=="/")
    {
        double temp=atof(c2)/atof(c1);
        substracttoken();
        substracttoken();
        substracttoken();
        stm<<temp;
        addtoken(stm.str());
    }
}
std::string itorpn(std::string s)
{
    std::string s0;
    stek st;
    for(int i=0;i<s.length();i++)
    {
        if(isdigit(s[i]) && isdigit(s[i+1]))
            s0=s0+s[i];
        else if(isdigit(s[i]))
                 s0=s0+s[i]+" ";
        if(s[i]=='.')
            s0=s0+s[i];
        if(s[i]=='-' && (s[i-1]=='(' || i==0))
        {
            s0=s0+s[i];
            goto skip;
        }
        if(s[i]=='+' || s[i]=='-' || s[i]=='*' || s[i]=='/')
        {
            if((s[i]=='-' || s[i]=='+') && (st.upperitem()=='/' || st.upperitem()=='*'))
            {
                again:
                s0=s0+st.upperitem()+" ";
                st.substractitem();
            }
            if((s[i]=='-' || s[i]=='+') && (st.upperitem()=='/' || st.upperitem()=='*'))
                goto again;
            st.additem(s[i]);
        }
        skip:
        if(s[i]=='(')
            st.additem('(');
        if(s[i]==')')
            {
                while(st.upperitem()!='(')
                {
                    s0=s0+st.upperitem()+" ";
                    st.substractitem();
                }
                st.substractitem();
            }
    }
    s0=s0+st.stekins();
    return s0;
}
int main()
{
    std::string sd;
    std::cin>>sd;
    std::string ss=itorpn(sd);
    int sizee=0;
    for(int k=0;k<ss.length();k++)
    {
        if(ss[k]==' ') sizee++;
    }
    std::string c[sizee];
    int isfree=0;
    for(int i=0;i<ss.length();i++)
    {
        if(ss[i]==' ') isfree++;
        else 
        {
            c[isfree]=c[isfree]+ss[i];
        }
    }
    stek2 st;
    int l=0;
    while(l<sizee)
    {
        st.addtoken(c[l]);
        if(!isdigit(c[l][0]) && isdigit(c[l-1][0]) && isdigit(c[l-2][0]))
            st.evaluate();
        if(!isdigit(st.uppertoken()[0]))
            st.evaluate();
        l++;
    }
    std::cout<<st.uppertoken();
    getch();
    return 0;
}
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
09.08.2010, 18:03  [ТС]     Задачи для тренировки и лучшего понимания #655
nikkka, А у меня не работает...

Error 4 error C2057: expected constant expression c:\documents and settings\admin\мои документы\visual studio 2005\projects\дейтлы\глава 4\proh\proh.cpp 191
Error 5 error C2466: cannot allocate an array of constant size 0 c:\documents and settings\admin\мои документы\visual studio 2005\projects\дейтлы\глава 4\proh\proh.cpp 191
Error 6 error C2133: 'c' : unknown size c:\documents and settings\admin\мои документы\visual studio 2005\projects\дейтлы\глава 4\proh\proh.cpp 191
nikkka
Мат в 32 хода
235 / 170 / 8
Регистрация: 10.09.2009
Сообщений: 1,096
09.08.2010, 18:06     Задачи для тренировки и лучшего понимания #656
Lavroff, странно, а у меня в Dev C++ всё работает...
nikkka
Мат в 32 хода
235 / 170 / 8
Регистрация: 10.09.2009
Сообщений: 1,096
09.08.2010, 18:16     Задачи для тренировки и лучшего понимания #657
вот тогда вам ехе.шник.
Вложения
Тип файла: rar calculator.rar (112.3 Кб, 19 просмотров)
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
09.08.2010, 18:28  [ТС]     Задачи для тренировки и лучшего понимания #658
nikkka, Пробелы при выводе бы не помешали. А то ввел 2+4+5, он мне вывел 911 + Сообщение о том что надо что-то ввести.
nikkka
Мат в 32 хода
235 / 170 / 8
Регистрация: 10.09.2009
Сообщений: 1,096
09.08.2010, 18:31     Задачи для тренировки и лучшего понимания #659
Цитата Сообщение от Lavroff Посмотреть сообщение
он мне вывел 911
и я об этом. конечный результ 11, а 9 это промежуточное значение (4+5)...

Не по теме:

хана! срочно звоните 2+4+5!!!!!

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.08.2010, 18:34     Задачи для тренировки и лучшего понимания
Еще ссылки по теме:

C++ Какая база требуется для понимания C++?
C++ Нужен пример рекурсивной функции для понимания ее назначения и практической пользы
C++ Builder Прошу примеров для понимания INDY
Книги для тренировки/развития котелка и просто убийства времени C++
Дайте задания для тренировки C++

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

Или воспользуйтесь поиском по форуму:
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
09.08.2010, 18:34  [ТС]     Задачи для тренировки и лучшего понимания #660
nikkka, А кстати. Операции выполняются справа налево?
Yandex
Объявления
09.08.2010, 18:34     Задачи для тренировки и лучшего понимания
Закрытая тема Создать тему
Опции темы

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