コード:
LinkList.h
LinkList.c
LinkStack.h
LinkStack.c
スタックリニアテーブル
main.c
#include <stdio.h>
#include "LinkStack.h"
/*
该程序将 正常的算式 转换成按照运算符优先分布的算式
比如:9+(3-1)*5+8/2 转换成 931-5*+82/+
注意:正常算式 只能是一位数
*/
int isNumber(char c)//定义检测是否数字函数
{
return ('0' <= c) && (c <= '9');
}
int isOperator(char c)//定义检测是否加减乘除运算符
{
return (c == '+') || (c == '-') || (c == '*') || (c == '/');
}
int isLeft(char c)//定义检测是否左边括号函数
{
return (c == '(');
}
int isRight(char c)//定义检测是否右边括号函数
{
return (c == ')');
}
int priority(char c)//定义检测运算符的优先级函数
{
int ret = 0;
if( (c == '+') || (c == '-') )
{
ret = 1;
}
if( (c == '*') || (c == '/') )
{
ret = 2;
}
return ret;
}
void output(char c)//定义输出字符函数
{
if( c != '\0' )
{
printf("%c", c);
}
}
void transform(const char* exp)
{
LinkStack* stack = LinkStack_Create();//创建栈
int i = 0;
while( exp[i] != '\0' )
{
if( isNumber(exp[i]) )//如果是数字
{
output(exp[i]);//输出该字符
}
else if( isOperator(exp[i]) )//如果是加减乘除运算符
{
//如果这个运算符比之前的运算符优先级小或相等
//输出这些运算符,相当运算之前的运算符先,因为从左到右运算的,字符串检测也是从左到右每个字符检测
while( priority(exp[i]) <= priority((char)(int)LinkStack_Top(stack)) )
{
output((char)(int)LinkStack_Pop(stack));//将上一个运算符出栈,然后将其输出
}
LinkStack_Push(stack, (void*)(int)exp[i]);//将该运算符进栈
}
else if( isLeft(exp[i]) )//如果是左边括号
{
LinkStack_Push(stack, (void*)(int)exp[i]);//将该符号进栈
}
else if( isRight(exp[i]) )//如果是右边括号
{
//下面就相当将括号里面的运算符先运算
char c = '\0';//定义结束符 没有使用
while( !isLeft((char)(int)LinkStack_Top(stack)) )//如果不是左边括号
{
output((char)(int)LinkStack_Pop(stack));//一直执行数据出栈
}
LinkStack_Pop(stack);//再执行数据出栈一次,将左边括号出栈了
printf("size=%d ", LinkStack_Size(stack));
}
else
{
printf("Invalid expression!");
break;
}
i++;
}
while( (LinkStack_Size(stack) > 0) && (exp[i] == '\0') )//如果每个字符执行完。栈内还有数据
{
output((char)(int)LinkStack_Pop(stack));//一直执行出栈。清空了栈
}
LinkStack_Destroy(stack);//销毁栈
}
int main()
{
transform("9+(3-1)*5+8/2");
printf("\n");
getchar();
return 0;
}
分析:
コンパイル: