栈的应用:后缀表达式到中缀表达式的转换

摘要:(1)后缀表达式是给计算机看的,有些情况下我们需要将它转换成中缀表达式。
(2)这是一个重构的过程。
【1】首先考虑一些细节问题。作为表达式输入时要用空格将数字分开(1 2+),不能是(12+),因为数字没有用操作符隔开。那么在读入到的时候就要将空格给去掉,然后放入一个链表之中(放入数组不能区分间隔)。
【2】其次要考虑小数点的存在要将字符串(“12.35”)转换成数字(12.35);
【3】然后是基本的思路:首先遍历链表,直到遇到一个操作符号,然后找到该操作符号前面的两个节点(temp1,temp2),进行分类,如果两个都是数字,就是temp2 (符号)temp1的顺序保留,如果有一个或两个是操作符号,则按temp2,temp1的顺序放入一个字符串数组S里。
【4】同时注意后来的表达式转换后在S中的位置,需要判断应该插入在那个位置。执行代码:(strcpy(&S[strlen(S)],temp1->A);)
代码如下:

// chap3_计算后缀表达式.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "malloc.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
typedef struct Node *PtrtoNode;
#define operation 1
#define num 2
#define Expression 3
#define empty 0
#define Power 80
#define Multiply 50
#define Divide 50
#define Plus 40
#define Subtract 40
int mark = 0;

struct Node
{
    int Type;
    char symbol[1];
    char A[100];
    double number;
    PtrtoNode Next;
};
typedef PtrtoNode List;
List Create(int N)//用来创建一个单向链表
{
    List P,L ;
    L = (List)malloc(sizeof( struct Node));
    P = L;
    L->Type = empty;
    for (int i = 1;i<=N;i++)
    {
        P->Next = (List)malloc(sizeof( struct Node));
        P = P->Next;
        P->Type = empty;
        for(int i = 0;i<=99;i++)
            P->A[i] = '\0';

    }
    P->Next = NULL;
    return L;
}
double GetDigit(char *A)
{
    double number = 0;
    int i = 1;
    while(*A<='9'&&*A>='0')
        number = number*10 + *(A++) + (0-'0');
    if (*A == '.'){
        A++;
        while(*A<='9'&&*A>='0')
        number += pow((long double)10,-(i++))*(*(A++)+(0-'0'));
    }
    return number;
}
List FindPrevious(List L,List X)//找到X的前一个元素,也可能返回最后一个
{
    List P;
    P = L;
    while(P->Next!=NULL&&P->Next!=X)
    P = P->Next;
    return P;
}
void Delete(List L,List P)

{
    List temp;
    if (L->Next == NULL){
        puts("cannot delete an empty list");
        return;
    }

    temp = FindPrevious(L,P);
    temp->Next = P->Next;
    free(P);
}
void Fix(char *S)//用来添加括号
{
    int x = strlen( S);
    while(x)
    {
    S[x] = S[x-1];
    x--;
    }
    //x = 0
    S[0] = '(';
    S[strlen(S)] = ')';
}
List Convert(List L,List P,int * Last,int * This)
{
    char * S = P->A;
    double a,b;
    List temp1,temp2;
    int i = 0;
    switch(P->symbol[0])
    {
        case '+': *This = Plus;
            break;
        case '-': *This = Subtract;
            break;
        case '*': *This = Multiply;
            break;
        case '/': *This = Divide;
            break;
        case '^':*This= Power;
            break;
    }
    if (*This > *Last)
    {
        temp1 = FindPrevious(L,P);
        temp2 = FindPrevious(L,temp1);
        //判断是否给原来的表达式加括号
        if (temp1->Type == Expression){
            S = temp1->A;
            Fix(S);
        }
        if (temp2->Type == Expression)
        {
            S = temp2->A;
            Fix(S);
        }
    }
        S = P->A ;
        temp1 = FindPrevious(L,P);
        temp2 = FindPrevious(L,temp1);
        if(temp2->Type == Expression)
            {
            strcpy(S,temp2->A);
            }
            else
        {
            sprintf(S,"%f",temp2->number);
        }
            S[strlen(S)] = P->symbol[0];//输出操作符号

            if(temp1->Type == Expression)
            {
            strcpy(&S[strlen(S)],temp1->A);
            }
        else
        {
            sprintf(&S[strlen(S)],"%f",temp1->number);
        }
        *Last = *This;
        P->Type = Expression;
        Delete(L,temp1);
        temp1 = P->Next;
        Delete(L,temp2);
        P = temp1;
        return P;
}
int _tmain(int argc, _TCHAR* argv[])
{
    int i = 0;
    int Last = 100,This;
    char A[100] = {0};
    char S[100] = {0};
    List L = Create(20);
    List P = L->Next;
    puts("please input the expression: ");
    gets(A);
    while(A[i]!='\0')
    {
      while(A[i] == ' ')
     //去掉间隔的空格
     i++;
        if(A[i]>='0'&&A[i]<='9')
        {
            P->Type = num;
            P->number = GetDigit(&A[i]);
            while(A[i]>='0'&&A[i]<='9'||A[i] == '.')
                //直到下一个符号 operation or ' '
                i++;
                P = P->Next;
            continue;
        }
               //处理操作符号
                P->Type = operation;
                P->symbol[0] = A[i];
                i++;
                while(A[i] == ' ' )//去掉空格或者
                    i++;
                P = P->Next;
    }
    P = L->Next;
    while(P->Type!= empty)
    {
        while(P->Type == num)
            P = P->Next;
        if(P->Type == operation)
        P = Convert(L, P,&Last,&This);      //p进入时指向运算符号
    }
    puts(L->Next->A);
    return 0;
}

运行:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值