0 / 0 / 0
Регистрация: 15.09.2019
Сообщений: 2
1

Лафоре, код из 10 главы

15.09.2019, 00:56. Показов 1532. Ответов 4
Метки нет (Все метки)

Как не ломал голову, не могу понять, зачем тут префиксная запись инкремента на 16-ой строке кода :
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
#include <iostream>
#include <cstring>                   //for strlen(), etc
using namespace std;
const int LEN = 80;    //length of expressions, in characters
const int MAX = 40;    //size of stack
////////////////////////////////////////////////////////////////
class Stack
   {
   private:
      char st[MAX];                  //stack: array of chars
      int top;                       //number of top of stack
   public:
      Stack()                        //constructor
         { top = 0; }
      void push(char var)            //put char on stack
         { st[++top] = var; }
      char pop()                     //take char off stack
         { return st[top--]; }
      int gettop()                   //get top of stack
         { return top; }
   };
////////////////////////////////////////////////////////////////
class express                        //expression class
   {
   private:
      Stack s;                       //stack for analysis
      char* pStr;                    //pointer to input string
      int len;                       //length of input string
   public:
      express(char* ptr)             //constructor
         {
         pStr = ptr;                 //set pointer to string
         len = strlen(pStr);         //set length
         }
      void parse();                  //parse the input string
      int solve();                   //evaluate the stack
   };
//--------------------------------------------------------------
void express::parse()                //add items to stack
   {
   char ch;                          //char from input string
   char lastval;                     //last value
   char lastop;                      //last operator
 
   for(int j=0; j<len; j++)          //for each input character
      {
      ch = pStr[j];                  //get next character
 
      if(ch>='0' && ch<='9')         //if it's a digit,
         s.push(ch-'0');             //save numerical value
                                     //if it's operator
      else if(ch=='+' || ch=='-' || ch=='*' || ch=='/')
         {
         if(s.gettop()==1)           //if it's first operator
            s.push(ch);              //put on stack
         else                        //not first operator
            {
            lastval = s.pop();       //get previous digit
            lastop = s.pop();        //get previous operator
            //if this is * or / AND last operator was + or -
            if( (ch=='*' || ch=='/') &&
                (lastop=='+' || lastop=='-') )
               {
               s.push(lastop);       //restore last two pops
               s.push(lastval);
               }
            else                     //in all other cases
               {
               switch(lastop)        //do last operation
                  {                  //push result on stack
                  case '+': s.push(s.pop() + lastval); break;
                  case '-': s.push(s.pop() - lastval); break;
                  case '*': s.push(s.pop() * lastval); break;
                  case '/': s.push(s.pop() / lastval); break;
                  default:  cout << "\nUnknown oper"; exit(1);
                  }  //end switch
               }  //end else, in all other cases
            s.push(ch);              //put current op on stack
            }  //end else, not first operator
         }  //end else if, it's an operator
      else                           //not a known character
         { cout << "\nUnknown input character"; exit(1); }
      }  //end for
   }  //end parse()
//--------------------------------------------------------------
int express::solve()                 //remove items from stack
   {
   char lastval;                     //previous value
 
   while(s.gettop() > 1)
      {
      lastval = s.pop();             //get previous value
      switch( s.pop() )              //get previous operator
         {                           //do operation, push answer
         case '+': s.push(s.pop() + lastval); break;
         case '-': s.push(s.pop() - lastval); break;
         case '*': s.push(s.pop() * lastval); break;
         case '/': s.push(s.pop() / lastval); break;
         default:  cout << "\nUnknown operator"; exit(1);
         }  //end switch
      }  //end while
   return int( s.pop() );            //last item on stack is ans
   }  //end solve()
////////////////////////////////////////////////////////////////
int main()
   {
   char ans;                         //'y' or 'n'
   char string[LEN];                 //input string from user
   
   cout << "\nEnter an arithmetic expression"
           "\nof the form 2+3*4/3-2."
           "\nNo number may have more than one digit."
           "\nDon't use any spaces or parentheses.";
   do {
      cout << "\nEnter expresssion: ";
      cin >> string;                        //input from user
      express* eptr = new express(string);  //make expression
      eptr->parse();                        //parse it
      cout << "\nThe numerical value is: " 
           << eptr->solve();                //solve it
      delete eptr;                          //delete expression
      cout << "\nDo another (Enter y or n)? ";
      cin >> ans;
      } while(ans == 'y');
   return 0;
   }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.09.2019, 00:56
Ответы с готовыми решениями:

Задача 7 главы 7 из книги Р. Лафоре. Строки
Добрый день! Недавно начал изучать С++ по, наверное, уже всем поднадоевшему, учебнику Роберта...

Работа с Классами или разбираем 10 Упражнение 6 главы книги ООП в С++ Р.Лафоре
Доброго времени суток господа. Подскажите пожалуйста каким образом можно объединить классы? Почему...

Считывание числа поциферно (задача Лафоре, 3 глава, объяснить код)
Напишите программу,которая позволяет пользователю ввести 6 цифр,а затем выводит результат типа long...

Код из "Р.Лафоре. ООП в С++"
Р.Лафоре. &quot;ООП в С++ &quot; (4-е издание). 2012. Глава 12, стр.574, листинг 12.17, программа EMPL_IO. В...

4
Модератор
Эксперт С++
12785 / 10240 / 6151
Регистрация: 18.12.2011
Сообщений: 27,426
15.09.2019, 09:48 2
Все логично:
top указывает на последний элемент.
Когда вставляется новый элемент (push), то указатель надо сначала увеличить на 1(префиксный ++), и потом записать новый элемент.

И, наоборот, при извлечении элемента (pop), его надо сначала прочитать, а потом перейти к предыдущему (постфиксный --).
0
0 / 0 / 0
Регистрация: 15.09.2019
Сообщений: 2
16.09.2019, 11:48  [ТС] 3
Так получается первый элемент (нулевой индекс) массива не используется. Если использовать постфиксную форму, то все так же будет работать, т е мы поместим в первый элемент (нулевой индекс) массива информацию, а потом увеличим индекс (топ). Или я снова что-то не понимаю?)

Добавлено через 2 минуты
Заранее спасибо.
0
Модератор
Эксперт С++
12785 / 10240 / 6151
Регистрация: 18.12.2011
Сообщений: 27,426
16.09.2019, 13:12 4
Вы не понимаете идеологию работы стека.
1. На верху стека всегда есть элемент, который можно прочитать.
2. Операция push сдвигает этот элемент вниз, а наверху оказывается новый элемент.
3. Операция pop удаляет верхний элемент, а на его место ставит нижний элемент.

Как Вы будете рассматривать пустой стек - это другой вопрос.
Простейший способ как раз и заключается в том, что нулевой элемент массива отводится для пустого стека.
0
5226 / 3198 / 362
Регистрация: 12.12.2009
Сообщений: 8,111
Записей в блоге: 2
16.09.2019, 13:12 5
Цитата Сообщение от Edisolt Посмотреть сообщение
Так получается первый элемент (нулевой индекс) массива не используется.
Да, ты прав, очередная ошибка в книге Лафоре.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.09.2019, 13:12
Помогаю со студенческими работами здесь

Колонтитул из названия главы
Как сделать так, чтобы колонтитул брал своё значение из названия главы?

Задачка из первой главы Дейтелов.
Программа вводит три целых числа с клавиатуры, печатает сумму, среднее значение, произведение,...

Трудности прохождения 1 главы Two Worlds 2
При прохождении 1-ой главы возникла проблема после прохождения задания &quot;без шума и пыли&quot;... после...

9 Задача 4 главы Стивен Прата
Выполните упражнение 6, но вместо объявления массива из трех структур CandyBar используйте операцию...


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

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

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