堆栈 表达式的转换(后缀表达式)


#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;
            }
    }
}

img

img

感觉已经写的差不多了,输出结果似样例,为什么还是答案错误?还有嵌套括号处理的不对么?

#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;
}

img

你的出栈和入栈逻辑不对

空格等等格式检查一下

你没有处理两位数的情况,输入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;
}