1. 程式人生 > >藍橋演算法訓練 表示式計算

藍橋演算法訓練 表示式計算

本文參考部落格http://www.cnblogs.com/z-y-p/p/3676945.html

問題描述   輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。 輸入格式   輸入一行,包含一個表示式。 輸出格式   輸出這個表示式的值。 樣例輸入 1-2+3*(4-5) 樣例輸出 -4 資料規模和約定   表示式長度不超過100,表示式運算合法且運算過程都在int內進行。

思路:

      之前刷題注重速度,許多問題不是十分透徹就上傳了,導致遺忘的很快。。。我在寫這道題的時候花費了

不少腦筋,下面我來講講思路

做此題第一步:

           將中綴表示式轉換成字尾表示式,這個不能熟練轉換那麼這道題就沒法做,轉換方法參考這裡http://www.nowamagic.net/librarys/veda/detail/2307 網上有很多教程我就不重複了

會轉成字尾表示式後我們再來,以表示式2*(3+5)為例,用圖模擬程式碼執行過程

最開始將符號棧入一個“(”,防止棧空,會出錯


2進入數值棧


*號進符號棧


 ( 進符號棧


3進數值棧


+ 進符號棧


5進數值棧


檢測到"(" 不入棧, 而是將符號棧中的")" 之上的運算子提出來,供給棧頂次頂元素運算,並將棧頂和次頂兩個元素刪除得到的新的值存入數值棧,在將"("也刪掉,得到如圖


然後中綴表示式遍歷結束了,但還有8和2沒有通過*運算,這時候最開始通過strcat將“.”連線到中綴表示式後面

就起作用了,碰到“.”,就按碰到+-運算子的處理方案一樣,運算後如圖


最後在將數值棧棧頂取出列印就ok啦

程式碼

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stack>
using namespace std;
stack<char> stack_ch;//符號棧 
stack<int> stack_num; //數值棧 
char str[1000]; //輸入的中綴表示式 
char number[100]; //用來將字串中的數字變成int型的陣列 

void js1()//這個函式只接收+-號,+-號等級最低,運算子棧中除了括號外 都可以取出運算 
{
	int num1,num2;
	while (stack_ch.top()!='(')  //從運算子棧中取一個運算子 對數值棧頂和次頂元素進行運算 
	{
		num1=stack_num.top();//取出一個數
		stack_num.pop();//彈出這個數
		num2=stack_num.top();
		stack_num.pop();
		switch (stack_ch.top())
		{
			case '+':
				num2+=num1;
			    break;
			case '-':
				num2-=num1;
				break;
			case '*':
				num2*=num1;
				break;
			case '/':
				num2/=num1;
				break;
		 } 
		 stack_num.push(num2);//將計算結果入數值棧
		  stack_ch.pop();//刪除已經用過的符號 
	}
}
void js2()//只接收*/運算子 
{
	int num1,num2;
	while (stack_ch.top()=='*' || stack_ch.top()=='/') //棧中只有*/優先順序大於*/  
	{
		num1=stack_num.top();
		stack_num.pop();
		num2=stack_num.top();
		stack_num.pop();
		switch (stack_ch.top())
		{
			case '*':
			    num2*=num1;
				break;
			case '/':
			    num2/=num1;
				break; 
		}
		stack_ch.pop();
		stack_num.push(num2);
	}
}
int main()
{
	int i,k=0,s;
	char c[5]=".";
	stack_ch.push('(');
	gets(str);
	strcat(str,c);
	for (i=0;str[i];i++)
	{
		if (str[i]>='0'&&str[i]<='9')//為數字
		  {
		  	number[k++]=str[i];
		  	continue;
		  }
		  number[k]='\0'; //變成字串\0結尾 
		  if (number[0]!='\0')
		  {
		  s=atoi(number);
		  number[0]='\0';
		  stack_num.push(s); //將字串轉換成整型,放入數值棧中 
	      }
		  k=0; 
	    	switch(str[i])//+-(這3個符號入js1函式,*/入js2函式 ,優先順序不同要分開計算 
	    	{
	    		case '+':  
	    			js1();
	    			stack_ch.push('+');
	    			break;
	    		case '-':
	    			js1();
	    			stack_ch.push('-');
	    			break;
	    		case '*':
	    			js2();
	    			stack_ch.push('*');
	    			break;
	    		case '/':
	    			js2();
	    			stack_ch.push('/');
	    			break;
	    		case '(':
	    			stack_ch.push('(');
	    			break;
	    		case ')':
	    			js1();
	    			stack_ch.pop();
	    			break;
	    		case '.':
	    			{
	    				js1();
	    				stack_ch.pop();
					}
			}
	}
			printf("%d\n",stack_num.top());
}