Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.09.2014, 14:43   #1
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию Стэк и символьный тип данных C++.

Всем привет. У меня возник следующий вопрос: наткнулся на пример из книги Лафоре (ООП). Там программа предлагает пользователю ввести строку типа стринг наподобие: 2+3*4/3-2. Программа обрабатывает эту строку. Посимвольно добавляет в стэк и производит вычисление. Каким образом? Ведь пользователь вводит не int и не float?
Вот код:
Код:
// parse.cpp 
// программа разбора арифметических выражений 
#include <iostream> 
#include <cstring> 
using namespace std; 
const int LEN = 80; // максимальная длина выражения 
const int MAX = 40; 
/////////////////////////////////////////////////////////// 
class Stack 
{ 
  private: 
    char st[MAX]; // массив данных 
    int top; // количество сохраненных данных 
  public: 
    Stack() // конструктор 
   { top = 0; } 
    void push(char var) // поместить в стек 
    { st[++top] = var; } 
    char pop() // взять из стека 
    { return st[top--]; } 
   int gettop() // узнать количество элементов 
   { return top; } 
};
/////////////////////////////////////////////////////////// 
class express 
{ 
  private: 
    Stack s; // стек данных 
    char* pStr;  // строка для ввода 
    int len; // длина строки 
  public: 
    express (char* ptr) // конструктор 
    { 
       pStr = ptr; // запоминаем указатель на строку 
       len = strlen(pStr); // устанавливаем длину 
    }
    void parse(); // разбор выражения 
    int solve(); // получение результата 
}; 
/////////////////////////////////////////////////////////// 
void express::parse() // добавляем данные в стек 
{ 
  char ch; // символ из строки 
  char lastval; // последнее значение 
  char lastop; // последний оператор 
  for(int j = 0; j < len; j++) //для всех символов в строке 
  { 
   ch = pStr[j]; // получаем символ 
   if(ch >= '0' && ch <= '9') // если это цифра, 
s.push(ch - '0'); // то сохраняем ее значение 
else 
if(ch == '+' || ch == '-' || ch == '*' || ch == '/') 
{ 
  if(s.gettop() == 1) // если это первый оператор, 
  s.push(ch); // помещаем его в стек 
  else // иначе 
  { 
    lastval = s.pop(); // получаем предыдущее число 
    lastop = s.pop(); // получаем предыдущий оператор
    // если это * или /, а предыдущий был + или -, то 
    if((ch == '*' || ch == '/') && (lastop == '+' || lastop == '-')) 
    { 
      s.push(lastop); // отменяем последние два взятия из стека 
      s.push(lastval); 
    } 
    else 
    { 
      // помещаем в стек результат операции 
      switch(lastop) 
      { 
        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 << "\nНеизвестный оператор"; exit(1); 
      } 
     } 
        s.push(ch); // помещаем в стек текущий оператор 
      } 
     } 
     else // какая-то ерунда... 
    { 
      cout << "\nНеизвестный символ"; 
      exit(1); 
    } 
  } 
} 
/////////////////////////////////////////////////////////// 
int express::solve() // убираем данные из стека 
{ 
  char lastval; // предыдущее значение 
  while(s.gettop() > 1) 
  { 
    lastval = s.pop(); // получаем предыдущее значение 
    switch(s.pop()) // получаем предыдущий оператор 
    { 
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 << "\nНеизвестный оператор"; exit(1); 
   } 
  } 
  return int(s.pop()); // последний оператор в стеке - это результат 
} 
///////////////////////////////////////////////////////////
int main() 
{ 
char ans; // 'д' или 'н' 
char string[LEN]; // строка для разбора 
cout << "\nВведите арифметическое выражение в виде 2+3*4/3-2" 
"\nЧисла должны быть из одной цифры" 
"\nНе используйте пробелы и скобки"; 
do 
{ 
cout << "\nВыражение: "; 
cin >> string; // вводим строку 
express* eptr = new express(string); // создаем объект для разбора 
eptr->parse(); // разбираем 
cout << "\nРезультат: " 
<< eptr->solve(); // решаем 
delete eptr; // удаляем объект 
cout << "Еще одно выражение (д/н)? "; 
cin >> ans; 
}
while(ans == 'д'); 
return 0; 
}
Пробовал написать в упрощенной форме (предлагал ввести стринг - 1+1 к примеру) а результатом был символ из ASCII таблицы!
Заранее благодарен!

Последний раз редактировалось ACE Valery; 26.09.2014 в 18:27.
igoreshka3333 вне форума Ответить с цитированием
Старый 26.09.2014, 15:27   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,833
По умолчанию

Цитата:
Каким образом?
Цитата:
Программа обрабатывает эту строку. Посимвольно добавляет в стэк и производит вычисление.
что конкретно вам не понятно?
p51x вне форума Ответить с цитированием
Старый 26.09.2014, 15:37   #3
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Не понятно каким образом производятся арифметические действия именно над над символьными типами переменных! За счет добавления в стек?
igoreshka3333 вне форума Ответить с цитированием
Старый 26.09.2014, 15:41   #4
igoreshka3333
Форумчанин
 
Аватар для igoreshka3333
 
Регистрация: 26.09.2014
Сообщений: 176
По умолчанию

Небольшой оффтоп: как пользовать тегами [ CODE ][ / CODE ]?
igoreshka3333 вне форума Ответить с цитированием
Старый 26.09.2014, 15:58   #5
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

Пишете код.. Выделяете его.. Тыкаете на кнопочку с решеткой.. Радуетесь
Poma][a вне форума Ответить с цитированием
Старый 26.09.2014, 17:56   #6
challengerr
Участник клуба
 
Аватар для challengerr
 
Регистрация: 30.07.2008
Сообщений: 1,609
По умолчанию

char это один байт. В байте может храниться от -127 до 128, если один бит знаковый. Если знаковых битов нет, то char вмещает от 0 до 255. Int отличается от char тем, что в нем 4 байта, как правило, но зависит от архитектуры.
"SPACE.THE FINAL FRONTIER.This's a voyage of starship Enterprise. It's 5-year mission to explore strange new worlds,to seek out new life and civilizations,to boldly go where no man has gone before"
challengerr вне форума Ответить с цитированием
Старый 26.09.2014, 18:27   #7
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,365
По умолчанию

Цитата:
Небольшой оффтоп: как пользовать тегами [ CODE ][ / CODE ]?
Без пробелов их писать
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Символьный тип данных Grenki Паскаль, Turbo Pascal, PascalABC.NET 5 25.03.2014 15:01
Символьный Тип Данных И Строки. николас Помощь студентам 6 05.04.2013 06:38
символьный тип kop Общие вопросы C/C++ 3 15.05.2011 15:14
Символьный тип kop Общие вопросы C/C++ 0 15.05.2011 01:10
Символьный тип данных. acho Помощь студентам 0 19.06.2010 22:55