栈
结构体创建
typedef struct CharStack{
int top;
int data[STACK_MAX_SIZE];
}*CharStackPtr;
初始化
CharStackPtr initcharStack(){
CharStackPtr resultPtr=(CharStackPtr)malloc(sizeof(struct CharStack));
resultPtr->top=-1;
return resultPtr;
}
打印栈
void outputStack(CharStackPtr s){
int i;
for(i=0;i<=s->top;i++){
printf("%c",s->data[i]);
}
printf("\r\n");
}
入栈
void push(CharStackPtr s,int e){
if(s->top>=STACK_MAX_SIZE-1){
printf("栈满\r\n");
return;
}
s->top++;
s->data[s->top]=e;
}
出栈
void pop(CharStackPtr s){
if(s->top=-1){
printf("空栈不能删除\r\n");
return;
}
s->top--;
}
取栈顶元素
char Gettop(CharStackPtr s){
if(s->top<0){
printf("空栈不能取值\r\n");
return;
}
s->top--;
return s->data[s->top+1];
}
应用之括号匹配
void bracketMatching(char* paraString,int paraLength){
CharStackPtr tempStack=initcharStack();
push(tempStack,'#');
char tempChar;
char tempPopedChar;
int i;
for(i=0;i<paraLength;i++){
tempChar=paraString[i];
switch(tempChar){
case'(':
case'[':
case'{':
push(tempStack,tempChar);
outputStack(tempStack);
break;
case')':
tempPopedChar=Gettop(tempStack);
if(tempPopedChar!='('){
printf("错误\r\n");
return;
}
outputStack(tempStack);
break;
case']':
tempPopedChar=Gettop(tempStack);
if(tempPopedChar!='['){
printf("错误\r\n");
return;
}
outputStack(tempStack);
break;
case'}':
tempPopedChar=Gettop(tempStack);
if(tempPopedChar!='{'){
printf("错误\r\n");
return;
}
outputStack(tempStack);
break;
}
}
tempPopedChar=Gettop(tempStack);
if(tempPopedChar!='#'){
printf("错误\r\n");
return;
}
printf("匹配\r\n");
}
int main(){
char ch[1000000];
scanf("%s",ch);
int length=strlen(ch);
bracketMatching(ch,length);
}
*判断读入字符,若为”(“、”【“、”{“,将其压入栈
*若为“)”、“】”、“}”,则判断栈顶元素,若栈顶元素为其对应的左括号,则正确匹配,否则,匹配错误
*若最后栈只有“#”,则匹配成功
我在老师代码的基础上改进了一些,不用自己数字符串长度,而用strlen函数计算,并在每一步栈中元素改变时将其打印出来,更便于观察。
完整代码
#include <stdio.h>
#include <malloc.h>
#include<string.h>
#define STACK_MAX_SIZE 10
//结构体创建
typedef struct CharStack{
int top;
int data[STACK_MAX_SIZE];
}*CharStackPtr;
//初始化
CharStackPtr initcharStack(){
CharStackPtr resultPtr=(CharStackPtr)malloc(sizeof(struct CharStack));
resultPtr->top=-1;
return resultPtr;
}
//打印栈
void outputStack(CharStackPtr s){
int i;
for(i=0;i<=s->top;i++){
printf("%c",s->data[i]);
}
printf("\r\n");
}
//入栈
void push(CharStackPtr s,int e){
if(s->top>=STACK_MAX_SIZE-1){
printf("栈满\r\n");
return;
}
s->top++;
s->data[s->top]=e;
}
//出栈
void pop(CharStackPtr s){
if(s->top=-1){
printf("空栈不能删除\r\n");
return;
}
s->top--;
}
//取栈顶元素
char Gettop(CharStackPtr s){
if(s->top<0){
printf("空栈不能取值\r\n");
return;
}
s->top--;
return s->data[s->top+1];
}
//应用之括号匹配
void bracketMatching(char* paraString,int paraLength){
CharStackPtr tempStack=initcharStack();
push(tempStack,'#');
char tempChar;
char tempPopedChar;
int i;
for(i=0;i<paraLength;i++){
tempChar=paraString[i];
switch(tempChar){
case'(':
case'[':
case'{':
push(tempStack,tempChar);
outputStack(tempStack);
break;
case')':
tempPopedChar=Gettop(tempStack);
if(tempPopedChar!='('){
printf("错误\r\n");
return;
}
outputStack(tempStack);
break;
case']':
tempPopedChar=Gettop(tempStack);
if(tempPopedChar!='['){
printf("错误\r\n");
return;
}
outputStack(tempStack);
break;
case'}':
tempPopedChar=Gettop(tempStack);
if(tempPopedChar!='{'){
printf("错误\r\n");
return;
}
outputStack(tempStack);
break;
}
}
tempPopedChar=Gettop(tempStack);
if(tempPopedChar!='#'){
printf("错误\r\n");
return;
}
printf("匹配\r\n");
}
//test
int main(){
char ch[1000000];
scanf("%s",ch);
int length=strlen(ch);
bracketMatching(ch,length);
}
运行结果
({}[])
#(
#({
#(
#([
#(
#
匹配
---------------------------------------------------
)(
错误
---------------------------------------------------
({])
#(
#({
错误
表达式求值
表达式求值是个比较复杂的应用,我模仿了别人的算法并改进了一些。整体思路是创建两个栈一个存放数字一个存放符号,通过比较运算符的优先级进行计算
优先级比较
char priority(char ch1,char ch2){
//用二维数组实现
char pri[7][7]={
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','\0'},
{'>','>','>','>','\0','>','>'},
{'<','<','<','<','<','\0','='},
};
int i,j;
switch (ch1)
{
case '+':
i = 0;
break;
case '-':
i = 1;
break;
case '*':
i = 2;
break;
case '/':
i = 3;
break;
case '(':
i = 4;
break;
case ')':
i = 5;
break;
case '=':
i = 6;
break;
}
switch (ch2)
{
case '+':
i = 0;
break;
case '-':
i = 1;
break;
case '*':
i = 2;
break;
case '/':
i = 3;
break;
case '(':
i = 4;
break;
case ')':
i = 5;
break;
case '=':
i = 6;
break;
}
return pri[i][j];
}
数字符号判断
int isDigit(char ch)
{
if(ch >= '0' && ch <= '9')
{
return 1;
}
return 0;
}
int isOperator(char ch)
{
switch (ch)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '=':
return 1;
default :
return 0;
}
}
int evaluate(int x,char ch ,int y)
{
switch (ch)
{
case '+':
return x+y;
case '-':
return x-y;
case '*':
return x*y;
case '/':
if(y == 0)
{
printf("除数为0,无效的表达式\n");
return -1;
}
else
{
return x/y;
}
}
}
核心代码求值
int evaluateExpression(char *paraExpression)
{
charStackPtr stack1 = stackInit();//存放数
charStackPtr stack2 = stackInit();//存放运算符
int i,a,b,x,x1,x2;
char tempch1,tempch2;
push(stack2,'=');
i = 0;
tempch1 = paraExpression[i++];
while(tempch1 != '=' || getTop(stack2) != '=')
{
if(isOperator(tempch1))//判断是否为运算符
{
switch(priority(getTop(stack2),tempch1))
{
case'<':
push(stack2,tempch1);
tempch1 = paraExpression[i++];
break;
case'>':
tempch2 = pop(stack2);
b = pop(stack1);
a = pop(stack1);
push(stack1,evaluate(a,tempch2,b));
break;
case'=':
x = pop(stack2);
tempch1 = paraExpression[i++];
break;
}
}
else if(isdigit(tempch1))
{
x1 = tempch1-'0';
push(stack1,x1);
x2 = x1;
tempch1 = paraExpression[i++];
while(isDigit(tempch1))
{
x1 = tempch1 - '0';
x2 = 10*x2 + x1;
x = pop(stack1);
push(stack1,x2);
tempch1 = paraExpression[i++];
}
}
else if(tempch1 == ' ')
{
while(tempch1 == ' ')
{
tempch1 == paraExpression[i++];
}
}
else
{
printf("多项式错误\n");
}
}
return getTop(stack1);
}