您的位置:首页 > 编程语言 > C语言/C++

栈应用之中缀转后缀表达式(C语言版)

2017-01-28 17:22 344 查看
数学定义请自行百度,这里仅用大白话讲一下转换规则。

完整代码下载

中缀转后缀表达式转换规则:

文字说明:

1、如果是数字(包括小数点)则直接存放到数组suffix中(或者输出)

2、如果是左括号,则直接入栈

3、如果是右扩号,则出栈,直到遇到‘(’为止,并把‘(’出栈

4、如果是+-,若栈中无元素或者栈顶有‘(’,则直接入栈,否则全部出栈(遇到’(‘也停止)后再入栈(因为+-运算符优先级最低)

5、如果是*/,若栈顶优先级低于当前运算符,则直接入栈,否则先出栈再入栈

6、最后把栈中的运算符都出栈

图解示例:



1、



2、



3、



4、



5、



中缀转后缀表达式代码(部分):

//判断是否是数字
bool IsDigit(char ch)
{
return (ch >= '0' && ch <= '9') || ch == '.' ? true : false;
}

//判断是否是操作符
bool IsOperator(char ch)
{
return ch == '+' || ch == '-' || ch == '*' || ch == '/'? true : false;
}

//判断运算符的优先级,-1表示小于,0表示等于,1表示大于
int GetPriority(char op1 , char op2)
{
if ((op1 == '+' || op1 == '-') && (op2 == '-' || op2 == '+'))
return 0;
else if (op1 == op2)
return 0;
else if ((op1 == '+' || op1 == '-') && (op2 == '*' || op2 == '/'))
return 1;
else if ((op1 == '*' || op1 == '/') && (op2 == '-' || op2 == '+'))
return -1;
else if ((op1 == '*' || op1 == '/') && (op2 == '*' || op2 == '/') && op1 != op2)
return 0;
}

//根据运算符计算两数
double Calc(double op1, double op2, char op)
{
switch (op)
{
case '+': return op2 + op1;
case '-': return op2 - op1;
case '*': return op2 * op1;
case '/': if (op1 != 0) return op2 / op1;
else return 0;
default:  return 0;
}
}

//中缀转后缀表达式
void InfixToSuffix(const char* infix, char* suffix)
{
LPLINKSTACK stack = CreateStack();   //创建一个栈
int iLen = strlen(infix);            //计算长度用来控制循环
double num = 0;
int k = 0;
for (int i = 0;i < iLen;i++)
{
//1.略过空格
if(infix[i] == ' ')
continue;
//2.如果是数字(包括小数)直接输出
else if (IsDigit(infix[i]))
suffix[k++] = infix[i];
//3.如果是左括号,则直接入栈
else if (infix[i] == '(')
PushC(stack, infix[i]);
//4.如果是右扩号,则出栈,直到遇到‘(’为止,并把‘(’出栈
else if (infix[i] == ')')
{
while (GetTopC(stack) != '(')
suffix[k++] = PopC(stack);
Pop(stack);
}
//5.如果是+-,若栈中无元素或者栈顶有‘(’,则直接入栈,否则全部出栈(遇到'('也停止)后再入栈(因为+-运算符优先级最低)
else if (infix[i] == '+' || infix[i] == '-')
{
//加一个分隔符,区分2位以上的数字
suffix[k++] = ' ';
if (IsEmpty(stack) || GetTopC(stack) == '(')
PushC(stack, infix[i]);
else
{
do
{
suffix[k++] = PopC(stack);
} while (!IsEmpty(stack) && GetTopC(stack) != '(');
PushC(stack, infix[i]);
}
}
//6.如果是*/,若栈顶优先级低于当前运算符,则直接入栈,否则先出栈再入栈
else if (infix[i] == '*' || infix[i] == '/')
{
//加一个分隔符,区分2位以上的数字
suffix[k++] = ' ';
//当前运算符的优先级大于栈顶的优先级的时候直接入栈
if (GetPriority(GetTopC(stack), infix[i]) == 1)
PushC(stack, infix[i]);
else
{   //当栈不为空,且当前运算符的优先级小于等于栈顶的优先级,栈顶不是‘(’,才能出栈
while (!IsEmpty(stack) && (GetPriority(GetTopC(stack), infix[i]) < 1) && GetTopC(stack) != '(')
suffix[k++] = PopC(stack);
PushC(stack, infix[i]);
}
}
}
//7.最后把栈中的运算符都出栈
while (!IsEmpty(stack))
suffix[k++] = PopC(stack);
}


约瑟夫问题详解+源码

线性表之循环队列

线性表之链队列

线性表之顺序队列

线性表之链栈

线性表之顺序栈

线性表之双向链表

线性表之循环链表

线性表之单链表

线性表之顺序表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: