1. 程式人生 > >資料結構——逆波蘭表示法

資料結構——逆波蘭表示法

沒想到第一次寫資料結構就把我折騰死了呀~

我看的是一本AOJ的書,然後以後的演算法也是跟著書的目錄來~

題目的話會結合TOJ的一起寫,可以對照著看哦~

這個逆波蘭表示法我就不多講了,AOJ我用的堆疊。

在這裡我們可以運用棧的特點來實現字尾表示式,思路如下:

1.首先當遇到運算運算元時將其進行push操作;

2.當遇到操作符是將此時的棧pop兩次,先取出的棧頂為右運算元;

3.執行此方法到整個陣列遍歷完。

AOJ ALDSQ_1_3_A:Stack

(簡單的四則運算,沒有(),符號在後,僅一組資料)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int S[1001],top;
void push(int x)
{
	S[++top]=x;//top加1之後將元素插入top所指的位置 
}
int pop()
{
	top--;//返回top所指的元素 
	return S[top+1];
}
int main()
{
	int a,b;
	top=0;
	char s[100];
	while(scanf("%s",s)!=EOF)
	{
		if(s[0]=='+')
		{
			a=pop();
			b=pop();
			push(a+b);
		} 
		else if(s[0]=='-')
		{
			a=pop();
			b=pop();
			push(a-b);
		} 
		else if(s[0]=='*')
		{
			a=pop();
			b=pop();
			push(a*b);
		} 
		else if(s[0]=='/')
		{
			a=pop();
			b=pop();
			push(a/b);
		} 
		else
		push(atoi(s));//atoi()用來將字串形式的數字轉換為整型數值
	}
	printf("%d\n",pop());
	return 0;
}

TOJ 1519

描述

逆波蘭表示式是一種把運算子放置的算術表示式,例如普通的表示式2+3的逆波蘭表示法+2 3.逆波蘭表示式的優點是運算子之間不必有優先順序關係,也不用括號,
例如(2+3)*4的逆波蘭的表示式為*+2 3 4;本題求解逆波蘭表示式的值,其中運演算法只有* + - /.每個資料最多不超過100

輸入

輸入資料有多組,每組一行表示式,其中運算子和運算數之間用空格表示

輸出

輸出結果值,保留六位小數。

樣例輸入

樣例輸出

用堆疊做的

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stack>
#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
	int i,j,l;
	double p,q;
	char a[1001],b[31],c[30];
	string d;
	while(gets(a)!=NULL)
	{
		stack<string>f;//建立堆疊
		l=strlen(a);
		for(i=0;i<l;i++)
		{
			if(a[i]!=' ')
			{
				if(a[i]>='0'&&a[i]<='9')
				{
					j=0;
					while(i<l&&a[i]!=' ')
					{
						b[j++]=a[i];
						i++;
					}
					b[j]=0;
					while(1)
					{
						d=f.top();
						for(j=0;j<d.length();j++)
						c[j]=d[j];
						c[j]=0;
						if(c[0]>='0'&&c[0]<='9')
						{
							p=atof(b);
							q=atof(c);
							f.pop();
							d=f.top();
							f.pop();
							if(d[0]=='+')
							p+=q;
							else if(d[0]=='-')
							p=q-p;
							else if(d[0]=='*')
							p*=q;
							else if(d[0]=='/')
							p=q/p;
							b[0]=0;
							sprintf(b,"%.6f",p);
							//f.push(b);
						}
						else
						{
							p=atof(b);
							sprintf(b,"%.6f",p);
							f.push(b);
							break;
						}
						if(f.empty())
						{
							p=atof(b);
							sprintf(b,"%.6f",p);
							f.push(b);
							break;
						}
					}
				}
				else
				{
					b[0]=a[i];
					b[1]=0;
					f.push(b);
				}
			}
		}
		while(!f.empty())
		{
			d=f.top();
			for(j=0;j<d.length();j++)
			c[j]=d[j];
			c[j]=0;
			f.pop();
			printf("%s\n",c);
		}
		
	}
}

然後這是用的dp做。(我感覺更方便了?)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>//1519
char s[101];
int i,n;
double f()
{
	int j,k;
	double l;
	char a[10];
	memset(a,0,sizeof(a));
	for(j=i,k=0;j<n;j++,k++)
	if(s[j]!=' ')a[k]=s[j];
	else if(s[j]==' '&&a[j+1]!=' ')break;
	i=j+1;	
	switch(a[0])
	{
		case'+':return f()+f();
    		case'-':return f()-f();
    		case'*':return f()*f();
    		case'/':return f()/f();
    		default: return atof(a); //把字串轉換成浮點數名字
    	}
}
int main()
{
    double sum;
    while(gets(s)!=NULL)
    {
    	 i=0;
    	 n=strlen(s);
    	 sum=f();
    	 printf("%f\n",sum);
    }
}