#include<stdio.h>
#include<stdlib.h>
typedef char Element;//
struct snode{
Element data;
struct snode* next;
};
typedef struct snode* Stack;
Stack createstack();//建立空栈
void push(Element item,Stack S);
int isempty(Stack S);
void pop(Stack S);
int compare(Element item,Element ch);
int sign=0;
int main(){
Stack L;
L=createstack();
Element ch;
int flag=1;
int fuhao=0;
while(1){
scanf("%c",&ch);
if(ch==')')sign=1;
if(ch=='\n')break;//
else if(ch>='0'&&ch<='9'){
if(flag==1)printf("%c",ch);
else printf(" %c",ch);
flag=0;
fuhao=1;
}
else if(fuhao==0){
printf("%c",ch);
}
else push(ch,L);
}
Stack p=L;
while(p->next !=NULL){////剩下的符号
printf(" %c",p->next->data );
p=p->next ;
}
}
Stack createstack(){
Stack S;
S=(Stack)malloc(sizeof(struct snode));
S->next =NULL;
return S;
}
int isempty(Stack S){
return (S->next ==NULL);
}
void push(Element item,Stack S){
while(sign==1){//遇到右括号打印括号里面的内容
pop(S);
if(S->next->data =='(' )break;
}
if(sign==1){
pop(S);
sign=0;
return ;
}
while(S->next !=NULL&&compare(S->next->data ,item)){//熔断
pop(S);
}
if(item!=')'){
Stack tmpcell;
tmpcell=(Stack)malloc(sizeof(struct snode));
tmpcell->data=item;
tmpcell->next=S->next;
S->next =tmpcell;
}
}
void pop(Stack S){
if(isempty(S))return;
struct snode* first;
Element ch;
first=S->next ;
S->next =first->next ;
ch=first->data ;
free(first);
if(ch!='('&&ch!=')')printf(" %c",ch);//左右括号不打印
}
int compare(Element top,Element ch){
if(ch=='('||top=='(')return 0;//算法
if(ch==')')return 1;
switch(ch){//1顶弹出
case '+':
case '-':
return 1;
case '*':
case '/':
switch(top){
case '*':
case '/':
return 1;
case '+':
case '-':
return 0;
}
}
}
感觉已经写的差不多了,输出结果似样例,为什么还是答案错误?还有嵌套括号处理的不对么?
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
//用一个结构体来绑定一个运算项和其优先级
typedef struct Number number;
struct Number {
char c;//运算数或运算符
int priority;//优先级
};
/*
各项的类型 优先级
数字 0
+ - 1
* / 2
( ) 3
*/
//链栈的节点
typedef struct StackNode* stack;
struct StackNode {
number* data;
stack next;
};
//栈的生成方法
stack makeStack() {
stack s = (stack)malloc(sizeof(struct StackNode));
s->data = (number*)malloc(sizeof(struct Number));
s->next = NULL;
return s;
}
//判断栈是否空
bool isEmpty(stack s) {
return s->next == NULL;
}
//入栈
bool Push(stack s, number* x) {
stack newnode = (stack)malloc(sizeof(struct StackNode));
newnode->data = x;
newnode->next = s->next;
s->next = newnode;
return true;
}
//出栈
char Pop(stack s) {
if (isEmpty(s)) {
return -1;
}
stack temp = s->next;
char back = temp->data->c;
s->next = temp->next;
free(temp);
return back;
}
//中缀转后缀方法
void FromMiddleToPost() {
char c = '\0';//用来接收读取到的字符
int count = 0;//记录数组内的元素个数
number num[100];//结构体数组 用来记录读取到的中缀表达式并给各项附上优先级
while (1) {
scanf("%c", &c);//根据读取到的各项做具体处理
if (c == ' ') {//空格的情况 直接跳过
continue;
}
else if (c == '+' || c == '-') {
num[count].c = c;
num[count++].priority = 1;
}
else if (c == '*' || c == '/') {
num[count].c = c;
num[count++].priority = 2;
}
else if (c == '(') {
num[count].c = c;
num[count++].priority = 3;//左括号
}
else if (c == ')') {
num[count].c = c;
num[count++].priority = 4;//右括号
}
else {//数字的情况
num[count].c = c;
num[count++].priority = 0;
}
if (c == '\n') {//读取到回车 结束输入
break;
}
}
num[count].c = '\0';//数组的最后放入\0
stack s = makeStack();//创建栈
//开始从num数组中读取各种并转化成后缀表达式
for (int i = 0; i < count; i++) {
if (num[i].c == '\n') {//扔掉回车符
continue;
}
if (num[i].priority == 0) {//读取到数字 直接输出
printf("%c", num[i].c);
}
else {
if (isEmpty(s)) {//空表的情况下 无论什么运算符 直接插入
Push(s, &num[i]);
}
else {
if (num[i].priority == 3) {//处理左右括号的情况
Push(s, &num[i]);
}
else if (num[i].priority == 4) {//右括号
char temp = Pop(s);
printf("%c", temp);
while (s->next != NULL && temp != '(') {
temp = Pop(s);
if (temp != '(') {
printf("%c", temp);
}
}
}
else if (s->next->data->priority < num[i].priority) {//后插入的优先级 比 栈顶的优先级高
Push(s, &num[i]);
}
else {//后插入的优先级 小于等于 栈顶元素
while (s->next != NULL && s->next->data->priority >= num[i].priority) {//弹出栈 直到栈顶元素的优先级 小于 当前元素的优先级
if (s->next->data->priority == 3) break;//当栈顶字符是'('时 直接入栈即可
char temp = Pop(s);
printf("%c", temp);
}
Push(s, &num[i]);
}
}
}
}
while (s->next != NULL) {//弹出栈内剩余的运算符
char temp = Pop(s);
printf("%c", temp);
}
printf("\n");
}
int main()
{
FromMiddleToPost();
return 0;
}
你的出栈和入栈逻辑不对
空格等等格式检查一下
你没有处理两位数的情况,输入22+8
,得到的结果却是2 2 8 +·
。输入(-4+6)*5
得到的结果却是(-4 6 +
,显然括号处理不对
你看看:
#include<iostream>
#include<string>
#include<vector>
#include<stack>
using namespace std;
int main()
{
vector<string>v;
string s; cin >> s;
string data;
for (int i = 0; i < s.length(); i++)//数据预处理
{
if (i == 0 && s[i] == '+')continue;//忽略第一个数字的+
if (i == 0 && s[i] == '-')//当第一个数是负数时
{
data += s[i];
continue;
}
//+的前面是 + - * / ( 且后面是数字时说明该数据是正数,忽略+
if (i != 0 && s[i] == '+' && ((s[i - 1] < '0' || s[i - 1] > '9') && (s[i - 1] != ')')) && (s[i + 1] >= '0' && s[i + 1] <= '9'))
continue;
//-的前面是 + - * / ( 是数字时说明该数据是负数
if (i != 0 && s[i] == '-' && ((s[i - 1] < '0' || s[i - 1]>'9') && s[i - 1] != ')') && (s[i + 1] >= '0' || s[i + 1] <= '9'))
{
data += s[i];
continue;
}
//运算符前后都是数字的时候
if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || s[i] == '(' || s[i] == ')')
{
v.push_back(data);
data = s[i];
v.push_back(data);
data = "";
continue;
}
data += s[i];//连接前一个字符
if (i == s.size() - 1)v.push_back(data);
}
stack<string>s1, s2;//借助辅助栈s2用于存运算符
string ch;
for (int i = 0; i < v.size(); i++)
{
ch = v[i];
if (ch == "")continue;
if (ch == "+" || ch == "-")
{
if (!s2.empty())//符号非空
{
if (s2.top() == "(") //遇到( 直接插入
s2.push(ch);
else
{
//s2栈顶为+-*/时取出
while (!s2.empty() && (s2.top() == "+" || s2.top() == "-" || s2.top() == "*" || s2.top() == "/"))
{
s1.push(s2.top());
s2.pop();
}
s2.push(ch);
}
}
else s2.push(ch); //符号空直接插入
}
else if (ch == "*" || ch == "/")
{
if (!s2.empty())
{
//s2栈顶是+-(时插入
if (s2.top() == "+" || s2.top() == "-" || s2.top() == "(")
s2.push(ch);
else
{
//s2栈顶是* /时出去(循环)
while ((s2.top() == "*" || s2.top() == "/") && !s2.empty())
{
s1.push(s2.top());
s2.pop();
}
s2.push(ch);
}
}
else s2.push(ch);//符号空直接插入
}
else if (ch == "(")
s2.push(ch);
else if (ch == ")")
{
while (!s2.empty())
{
if (s2.top() == "(")
{
s2.pop();
break;
}
s1.push(s2.top());
s2.pop();
}
}
else s1.push(ch);
}
while (!s2.empty())
{
s1.push(s2.top());
s2.pop();
}
stack<string>ans;
while (!s1.empty())
{
ans.push(s1.top());
s1.pop();
}
int flag = 0;
while (!ans.empty())
{
if (flag++)cout << " ";
cout << ans.top();
ans.pop();
}
return 0;
}
清晰明了,参考下
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<ctype.h>
#define INITSIZE 20
#define INCREMENT 10
#define MAXBUFFER 10
#define LEN sizeof(Elemtype)
/*栈的动态分配顺序存储结构*/
typedef double Elemtype;
typedef struct{
Elemtype *base;
Elemtype *top;
int StackSize;
}SqStack;
void InitStack(SqStack *S)
{
S->base=(Elemtype*)malloc(LEN*INITSIZE);
assert(S->base != NULL);
S->top=S->base;
S->StackSize=INITSIZE;
}
void PushStack(SqStack *S,Elemtype e)
{
if(S->top - S->base >= S->StackSize)
{
S->base=(Elemtype*)realloc(S->base,(S->StackSize+INCREMENT)*LEN);
assert(S->base !=NULL);
S->top=S->base+S->StackSize;
S->StackSize+=INCREMENT;
}
*S->top =e;
S->top++;
}
void PopStack(SqStack *S,Elemtype *e)
{
*e=*--S->top;
}
void CalFunction(SqStack *S,char str[])
{
Elemtype number,e,d;
char arr[MAXBUFFER];
int i=0,j=0;
InitStack(S);
while(str[i]!='\0')
{
while(isdigit(str[i])||str[i]=='.') //过滤数字
{
arr[j++]=str[i++];
arr[j]='\0';
if( j >= MAXBUFFER )
{
printf("输入单个数据过大!\n");
return ;
}
if(str[i]==' ')
{
number=atof(arr); //利用atof函数将数字字符转化为double型数据
PushStack(S,number); //将转换的数进行压栈
j=0;
break;
}
}
switch(str[i])
{
case '+':
PopStack(S,&e);
PopStack(S,&d);
PushStack(S,d+e);
break;
case '-':
PopStack(S,&e);
PopStack(S,&d);
PushStack(S,d-e);
break;
case '*':
PopStack(S,&e);
PopStack(S,&d);
PushStack(S,d*e);
break;
case '/':
PopStack(S,&e);
PopStack(S,&d);
if(e == 0)
{
printf("输入出错,分母为零!\n");
return ;
}
PushStack(S,d/e);
break;
}
i++;
}
PopStack(S,&e);
printf("计算结果为:%lf",e);
}
int main()
{
char str[100];
SqStack S;
printf("请按逆波兰表达式输入数据,每个数据之间用空格隔开:");
gets(str);
CalFunction(&S,str);
return 0;
}