补全括号表达式(C语言实现)

**问题描述**

编写一栈程序,从标准输入得到一个缺少左括号的表达式并打印出补全括号之后的中序表达式。

例如: 给定输入:

1+2 ) \*3-4) \*5-6)))

补齐左括号之后的表达式为:((1+2)\*((3-4)\*(5-6)))

**基本要求及提示**

(1)初始化栈s。

(2)从键盘输入一个缺少左括号的表达式,并打印出补全括号之后的中序表达式。

**其他说明**

输入的字符只允许为数字、空格、+、-、\*、/、),长度不得超过MAX

补全左括号后的中序表达式。转换时,需要将空格过滤掉。即:result中不会出现空格字符。

举例说明: 1、输入="123 + 123",是一个正确的表达式,且有空格,因此,转换后,result="123+123"

2、输入="123 + 123)",且有空格,因此,转换后,result="(123+123)"

3、输入="1+2)\*3-4) \*5-6 ) ) )",且有空格,因此,转换后,result="((1+2)\*((3-4)\*(5-6)))"

4、输入="12-3\*\*3)",是非法的表达式,有两个连续的\*\*,函数返回false;

5、输入="12-3\*",是非法的表达式,*后面没有操作数了,函数返回false;

6、输入="12-5 5\*3)",是非法的表达式,操作数5与5之间,缺少操作符,函数返回false;

等等。

代码实现

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<malloc.h>

#define bool char

#define true 1

#define false 0

#define MAX 50 //定义输入的缺少左括号的表达式的最大长度

typedef struct Stack{

    char data[MAX][MAX*2]; //用来保存数据

    int top; //用来记录栈顶位置,初始值为-1,为0时表示该栈中有一个元素。

}Stack;

void  initStack(Stack* s){

    s->top = -1;

}

void Push(Stack*s, char*data){

    s->top++;

    strcpy(s->data[s->top], data);

}

char* Pop(Stack*s){

    return s->data[s->top--];

}

/*

TODO:完成给表达式补充左括号的功能。

函数功能:将一个缺少左括号的表示式,转换成补全左括号的中序表达式。

参数说明: express-需要被转换的缺少左括号的表达式。只允许为数字、空格、+、-、*、/、),长度不得超过MAX

           result-补全左括号后的中序表达式。转换时,需要将空格过滤掉。即:result中不会出现空格字符。

返回值说明:true-如果能成功转换,则返回true。

            false-否则,返回false。表示转换出错或输入的表达式非法。

举例说明: 1、express="123 + 123",是一个正确的表达式,且有空格,因此,转换后,result="123+123"

           2、express="123 + 123)",且有空格,因此,转换后,result="(123+123)"

           3、express="1+2)*3-4) *5-6 ) ) )",且有空格,因此,转换后,result="((1+2)*((3-4)*(5-6)))"

           4、express="12-3**3)",是非法的表达式,有两个连续的**,函数返回false;

           5、express="12-3*",是非法的表达式,*后面没有操作数了,函数返回false;

           6、express="12-3*5 5*3)",是非法的表达式,操作数5与5之间,缺少操作符,函数返回false;

           等等。

*/

bool completeParentese(char* express, char* result){

    int iLength = strlen(express);

    if(iLength >=MAX){ //输入的字符串长度超过预定值。则不处理了。

        return false;

    }

    char tempData[MAX*2]={0};

    Stack dataStack, operStack;

    initStack(&dataStack); //初始化栈

    initStack(&operStack); //初始化栈

    int j=0;

    for(int i=0; i < iLength; i++){

        char element = express[i];

        if(element>='0' && element <='9'){ //获取操作数

            tempData[j++]=element;

            i++;

            while(i<iLength){

                char element1 = express[i];

                if(element1>='0' && element1 <='9') {

                    tempData[j++] = element1;

                    i++;

                } else{

                    i--;

                    break;

                }

            }

            Push(&dataStack, tempData);

            if(dataStack.top - operStack.top != 1){

                return false;

            }

            memset(tempData, 0, MAX*2);

            j=0;

        } else if(element == '+' || element == '-' || element == '*' || element == '/'){//操作符

            char operate[2]={0};

            operate[0]=element;

            Push(&operStack, operate);

            

        }else if(element==' '){

            continue;

        }

        else if (element==')'){

            char tmp[MAX*2]={0};

            if(dataStack.top - operStack.top != 1){

                return false;

            }

            char*right=Pop(&dataStack);

            char*left;

            if(dataStack.top == -1){ //如果操作数栈中已经没有元素了,则直接在表达式左边添加左括号。

                strcat(tmp, "(");

                strcat(tmp, right);

                strcat(tmp, ")");

                Push(&dataStack, tmp);

            }else{

                left=Pop(&dataStack);

                strcat(tmp, "(");

                strcat(tmp, left);

                strcat(tmp, operStack.data[operStack.top--]);

                strcat(tmp, right);

                strcat(tmp, ")");

                Push(&dataStack, tmp);

            }

        }else{ //非法字符,如abc[.等等

            return false;

        }

    }

    //如果操作数栈中有元素,则将元素拿出来组装成表达式。如: 123+322

    while (dataStack.top>-1){

        char tmp[MAX*2]={0};

        char*right=Pop(&dataStack);

        char*left;

        if(dataStack.top == -1){//操作数已经全部取出,返回表达式

            strcat(tmp, right);

            strcpy(result,tmp);

            if(operStack.top!=-1){ //还有操作符,说明表示式非法。如123*324****。

                return false;

            }

            return true;

        }else{

            if(operStack.top==-1){ //只有操作数,没有操作符。说明输入表达式非法。

                return false;

            }

            left=Pop(&dataStack);

            strcat(tmp, left);

            strcat(tmp, operStack.data[operStack.top--]);

            strcat(tmp, right);

            Push(&dataStack, tmp);

        }

    }

    return true;

}

int main(){

    printf("请输入缺少左括号的表达式.\n");

    char express[MAX]={0};

    char result[MAX*2]={0};

    gets(express);

    bool bResult = completeParentese(express, result);

    if(bResult){

        printf("补齐左括号之后的表达式为:%s\n", result);

    } else{

        printf("转换失败,输入的表达式可能不合法");

    }

    return 0;

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值