lotussilva Ответов: 3

Вычисление постфиксного выражения в языке c++


По какой-то причине эта программа запускается, но компилятор завершает работу и отправляет меня на отладку и завершение.

Есть идеи, почему? Я застрял, как Чак.

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


#include<iostream>
#include<conio.h>
#include<ctype.h>

using namespace std;

/*
	The program will evaluate a postfix expression that contains digits and operators.
	The program tries to simulate the microprocessor execution stack or evaluation
	of expression.
 */

//The class performing the evaluation
class Evaluation {
	public:
		int st[50];
		int top;
		char str[50];
		Evaluation() {
			top = -1;
		}

		//function to push the item
		void push(int item) {
			top++;
			st[top] = item;
		}

		//function to pop an item
		int pop() {
			int item = st[top];
			top--;
			return item;
		}

		//function to perform the operation depending on the operator.
		int operation(int a,int b,char opr) {
			switch(opr) {
				case '+':return a+b;
				case '-':return a-b;
				case '*':return a*b;
				case '/':return a/b;
				default: return 0;
			}
		}

		int calculatePostfix();
};

//This is the function that calculates the result of postfix expression.
int Evaluation::calculatePostfix() {
	int index = 0;
	while(str[index]!='#') {
		if(isdigit(str[index])) {
			push(str[index]-'0');
		}
		else {
			int x = pop();
			int y = pop();
			int result = operation(x,y,str[index]);
			push(result);
		}
		index++;
	}
	return pop();
}

/*
	main function that reads the postfix expression and	that prints the result.

	The input expression should be ending with a number
	An example input expression would be:
	123*+
	Its output will be 7.

*/
int main() {
	void clrscr();
	Evaluation eval;
	cout << "Enter the postfix: ";
	cin >> eval.str;
	int result = eval.calculatePostfix();
	cout << "the result is " << result;
	getch();
}

Sergey Alexandrovich Kryukov

"...компилятор завершает работу и отправляет меня на отладку и завершение работы..." Я не могу в это поверить. Может быть, это ваш код завершается, а не компилятор? Затем запустите его под отладчиком.
—СА

lotussilva

Я не знаю, как отлаживать код::Blocks

joshrduncan2012

Пожалуйста, ответьте на вышеприведенный пост, иначе СА никогда не узнает, что вы оставили ему сообщение.

Просто из любопытства, какую IDE вы используете?

lotussilva

блок кода

JackDingler

Фундаментальным навыком разработки является умение пользоваться отладчиком.

Кстати, эти поп-команды подозрительны. Что происходит, когда вы звоните pop и у вас нет данных?
Что происходит, когда вы вызываете pop() и top равен -1?

lotussilva

Тогда вы идете на стек под потоком!

3 Ответов

Рейтинг:
28

Fredrik Bornander

Нужно суффикса ваш входной строки с #.

Эта линия;

while(str[index]!='#') {

это означает, что он будет повторяться str пока он не найдет #, если этого нет в строке, то она потерпит неудачу.

Попробуйте ввести это;
123*+#


Надеюсь, это поможет,
Фредрик


nv3

Это очень похоже на проблему. Мой 5.

И кроме того, я бы рекомендовал проверить, достиг ли конец строки в виде нулевого символа; просто на случай, если пользователь забудет поставить # в конце. На самом деле, это окончание # - плохая идея в любом случае. Просто используйте конец строки, чтобы определить конец выражения. Надеюсь, ОП поймет мой намек. :-)

Fredrik Bornander

Спасибо.
Я согласен с вами в комментарии к синтаксическому анализу, вся часть, которая читает и анализирует строку, немного изворотлива, если не сказать больше.

lotussilva

Спасибо! Это сработало. Это учебник из книги, которую мне дали, и учебники иногда заставляют вас делать ненужные вещи, с которыми вы обычно не сталкиваетесь в реальном мире, только потому, что они хотят научить вас чему-то.

Я все еще немного не уверен со всей этой постфиксной экспрессией. Я не знаю, хорошо ли я его понимаю, или что он делает, или как эта программа связана с ним, если уж на то пошло :(

Fredrik Bornander

Рад, что смог помочь.

Постфиксное выражение означает сначала выдвинуть аргументы, а затем, когда оператор найден, выполнить его на операндах в стеке. В вашем примере;
<pre>
Шаг 1: Нажмите 1
Шаг 2: Нажмите 2
Шаг 3: Нажмите 3
Шаг 4: оператор*, поп 3 и 2 и умножьте их на 6, нажмите 6
Шаг 5: оператор+, поп 6 и 1 и добавьте их в 7, Нажмите 7
</pre>

lotussilva

Ооооооо! Теперь это имеет смысл! Вот почему я всегда прихожу сюда, когда застреваю. Спасибо снова

Fredrik Bornander

Рад, что снова смог помочь :)

Рейтинг:
2

Member 14640839

Вы можете отредактировать эту строку в своем коде, чтобы избежать завершения

while(str[index]!='\0')


Dave Kreskowiak

Я серьезно сомневаюсь, что ОП все еще ищет решение шесть лет спустя.

Рейтинг:
0

Member 14938840

В этом есть некоторые ошибки
Первый-while(str[index]!='#')

Измените '#' на '\0'

Вторая - это функция операции, в приведенном выше коде вы выполняете операции между первым выскочившим и вторым выскочившим элементом, но вам нужно выполнить операцию между вторым выскочившим и первым выскочившим(чтобы быть предустановленным в соответствии с заданным решением, если 43 - это постфиксное выражение, операция выполняется как 3-4=-1, но правильная-4-3=1)
так что немного изменитесь здесь :
еще {
int x = pop();
int y = pop();
int result = operation(x,y,str[index]);
толчок(результат);
}
Сделайте небольшое изменение в качестве операции(y,x,str[index])

Пример 4325*-+
Согласно коду, мы получаем 11 в качестве ответа, я думаю, но правильный ответ -3(Я проверил его в интернете)
Мы получим этот ответ, если внесем предложенные мной изменения....

Общий код выглядит следующим образом:

#include<iostream>
using namespace std;
class Evaluation {
	public:
		int st[50];
		int top;
		char str[50];
		Evaluation() {
			top = -1;
		}
		void push(int val) {
			top++;
			st[top] = val;
		}
		int pop() {
			int val = st[top];
			top--;
			return val;
		}
		int operation(int a,int b,char opr) {
			switch(opr) {
				case '+':return a+b;
				case '-':return a-b;
				case '*':return a*b;
				case '/':return a/b;
				default: return 0;
			}
		}
		int calculatePostfix();
};
int Evaluation::calculatePostfix() {
	int index = 0;
	while(str[index]!='\0') {
		if(isdigit(str[index])) {
			push(str[index]-'0');
		}
		else {
			int x = pop();
			int y = pop();
			int result = operation(y,x,str[index]);
			push(result);
		}
		index++;
	}
	return pop();
}
int main() {
	Evaluation eval;
	cout << "Enter the postfix: ";
	cin >> eval.str;
	int result = eval.calculatePostfix();
	cout << "The result is " << result;
	return 0;
}

P.S.Please correct me if I am wrong