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

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

15.07.2010, 05:53. Показов 463051. Ответов 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
08.08.2010, 16:52 641
Author24 — интернет-сервис помощи студентам
Опять! Теперь череез простую матрицу...
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;
}
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
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);
}
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
08.08.2010, 17:28 643
nikkka, ты объявил массив указателй, но указатели у тебя все неинициализированы (т.е. память под них не выделена). В процессе нарезки на токены ты должен найти в строке позицию начала токена, затем позицию конца токена, после чего ты можешь вычислить длину строки для токена, после этого нужно заказать память такого размера и только потом скопировать в эту память значение токена

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

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

Добавлено через 48 секунд
Я писал про пост #657. А тут ты скорее всего NULL-терминатор потерял
1
Мат в 32 хода
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
08.08.2010, 17:31 644
Цитата Сообщение от Evg Посмотреть сообщение
А тут ты скорее всего NULL-терминатор потерял
чегой?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
08.08.2010, 17:32 645
Цитата Сообщение от nikkka Посмотреть сообщение
чегой?
В строках 20-24 ты формируешь массив char'ов. Чтобы он нормально мог трактоваться как строка, в конец надо ещё налепить символ '\0'
1
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 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;
перемудрил?
0
Мат в 32 хода
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
08.08.2010, 17:51 647
Цитата Сообщение от Evg Посмотреть сообщение
В строках 20-24 ты формируешь массив char'ов. Чтобы он нормально мог трактоваться как строка, в конец надо ещё налепить символ '\0'
а разве это не происходит автомат.?
0
2022 / 1621 / 489
Регистрация: 31.05.2009
Сообщений: 3,005
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; 
}
думаю этого вполне достаточно
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
08.08.2010, 18:40 649
Цитата Сообщение от nikkka Посмотреть сообщение
а разве это не происходит автомат.?
Си - язык низкого уровня. Там ничто автоматом не делается
0
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 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;
}
2
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
08.08.2010, 21:53 651
c такой задачей справляются простейшие s-грамматики рекурсивным спуском
0
Мат в 32 хода
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
08.08.2010, 22:23 652
Не удержался

Не по теме:

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

0
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 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
Как я уже сказал, что пробелы не убирал и определение типа токена тоже не делал.
Поэтому видно, что все токены имеют неизвестный тип, а каждый пробел представлен как отдельный токен.

Почистить от пробелов и такой список можно легко подавать на конвертирование в постфиксную нотацию, а потом уже и на вычисление.
Получается три абстрактных модуля. Которые в принципе не зависят друг от друга, а только от входящих данных.
1
Мат в 32 хода
237 / 172 / 18
Регистрация: 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;
}
1
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
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
0
Мат в 32 хода
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
09.08.2010, 18:06 656
Lavroff, странно, а у меня в Dev C++ всё работает...
0
Мат в 32 хода
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
09.08.2010, 18:16 657
вот тогда вам ехе.шник.
Вложения
Тип файла: rar calculator.rar (112.3 Кб, 20 просмотров)
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
09.08.2010, 18:28  [ТС] 658
nikkka, Пробелы при выводе бы не помешали. А то ввел 2+4+5, он мне вывел 911 + Сообщение о том что надо что-то ввести.
0
Мат в 32 хода
237 / 172 / 18
Регистрация: 10.09.2009
Сообщений: 1,096
09.08.2010, 18:31 659
Цитата Сообщение от Lavroff Посмотреть сообщение
он мне вывел 911
и я об этом. конечный результ 11, а 9 это промежуточное значение (4+5)...

Не по теме:

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

0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
09.08.2010, 18:34  [ТС] 660
nikkka, А кстати. Операции выполняются справа налево?
0
09.08.2010, 18:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.08.2010, 18:34
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
660
Закрытая тема Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru