先码下代码,后面跟进分析
运行结果
后缀表达式
Hanoi塔
进制转化
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 100
int step = 0,power=0,powerSFX=0;
char suffixEXP[100];
typedef struct seqStack
{
int data[MAX];
int top;
};
typedef struct seqStackC
{
char data[MAX];
int top;
};
//初始化栈
seqStack* Init_seqStack()
{
seqStack* s;
s = (seqStack*)malloc(sizeof(seqStack));
s->top = -1;
return s;
}
seqStackC* Init_seqStackC()
{
seqStackC* s;
s = (seqStackC*)malloc(sizeof(seqStackC));
s->top = -1;
return s;
}
//判断是否是空栈
int isEmpty(seqStack* s)
{
if (s->top == -1)
return 1;
else
{
return 0;
}
}
//进栈
void push_seqStack(seqStack* s, int x)
{
if (s->top == MAX - 1)
printf("栈满!\n");
else
{
s->top++;
s->data[s->top] = x;
}
}
void push_seqStackC(seqStackC* s, char x)
{
if (s->top == MAX - 1)
printf("栈满!\n");
else
{
s->top++;
s->data[s->top] = x;
}
}
//出栈
void pop_seqStack(seqStack* s, int* x)
{
if (s->top == -1)
printf("栈空!\n");
else
{
*x = s->data[s->top];
s->top--;
}
}
void pop_seqStackC(seqStackC* s, char* x)
{
if (s->top == -1)
printf("栈空!\n");
else
{
*x = s->data[s->top];
s->top--;
}
}
//返回栈顶元素
int top_seqStack(seqStack* s)
{
if (isEmpty(s))
printf("栈空!");
else
{
return (s->data[s->top]);
}
}
char top_seqStackC(seqStackC* s)
{
if (s->top==-1)
printf("栈空!");
else
{
return (s->data[s->top]);
}
}
//依次输出栈内元素
void printSeqStack(seqStack* s)
{
int i = 0;
for (i = 0; i <= s->top; i++)
printf("%d ", s->data[i]);
}
void printSeqStackc(seqStackC* s)
{
int i = 0;
for (i = 0; i <= s->top; i++)
printf("%c ", s->data[i]);
}
//进制转化
void conversionSystem(int N, int r)
{
seqStack* s;
int x;
s = Init_seqStack();
while (N)
{
push_seqStack(s, N % r);
N = N / r;
}
while (s->top != -1)
{
pop_seqStack(s, &x);
printf("%d", x);
}
}
//计算表达式(一个整数型的和一个字符型的栈,不限大小,整数内计算)
char precede(char in, char out) //比较读取运算符和栈顶运算符的优先级,()返回等号
{
if (in == '(' && out == ')')
return '=';
int a, b;
if (in == '(')
a = 0;
if (in == '+' || in == '-')
a = 1;
if (in == '*' || in == '%' || in == '/')
a = 2;
if (in == '^')
a = 3;
if (in == ')')
a = -1;
if (out == '(')
b = 4;
if (out == '+' || out == '-')
b = 1;
if (out == '*' || out == '%' || out == '/')
b = 2;
if (out == '^')
b = 3;
if (out == ')')
b = -1;
if (b <= a)
return '<';
else
return '>';
}
int operate(int a, char opr, int b) //计算a opr b
{
if (opr == '-')
return a - b;
if (opr == '+')
return a+b;
if (opr == '*')
return a * b;
if (opr == '/')
return a / b;
if (opr == '%')
return a % b;
if (opr == '^')
return pow(a,b);
}
int evaluateExpression() //计算表达式,返回整数型计算结果
{
seqStack *OPND; //整数型栈,存数字
seqStackC* OPTR; //字符型栈,存字符
char c, theta,x;
int a, b,debug=0;
OPND = Init_seqStack();
OPTR = Init_seqStackC();
push_seqStackC(OPTR, '(');
c = getchar();
while (c!='#')
{
if (c >= '0' && c <= '9')
{
if (!power) //读取的初个数字直接存入
{
power++;
push_seqStack(OPND, c - 48);
}
else //连续数字下把之前存入的数字取出,合并成新的整数存入
{
int trs;
pop_seqStack(OPND, &trs);
trs = trs*10 + c - 48;
push_seqStack(OPND, trs);
}
c = getchar();
}
else
{
power = 0;
switch (precede(top_seqStackC(OPTR), c)) //比较读取运算符与栈顶运算符的优先级
{
case '>': //高于直接存入字符栈
push_seqStackC(OPTR, c);
c = getchar();
break;
case '=': //()相遇弹出
pop_seqStackC(OPTR, &x);
c = getchar();
break;
case '<': //小于从整数栈取出两个数字,取出运算符栈栈顶,进行运算,结果存入整数栈,之后继续比较
pop_seqStackC(OPTR, &theta);
pop_seqStack(OPND, &b);
pop_seqStack(OPND, &a);
push_seqStack(OPND, operate(a, theta, b));
break;
}
}
debug++;
printf("\n第%d部:OPND:", debug);
printSeqStack(OPND);
//printf("\n");
printf("\nOPTR:");
printSeqStackc(OPTR);
}
while (OPTR->top != 0) //循环结束后运算符栈还有剩余直接依次取出计算直到读到'('
{
pop_seqStackC(OPTR, &theta);
pop_seqStack(OPND, &b);
pop_seqStack(OPND, &a);
push_seqStack(OPND, operate(a, theta, b));
}
return top_seqStack(OPND);
}
//后缀表达式(一个字符型的栈,不限大小整数范围内计算)
void toSuffixExpression()//把中缀表达式转换成后缀表达式,数之间用'|'隔开
{
seqStackC* OPTR;
OPTR = Init_seqStackC();
push_seqStackC(OPTR, '(');
char c,theta,x; //c接受输入字符,theta运算符,x剔除多余字符时中介
int i = 0; //i数组计数
c = getchar();
while (c != '#') //读到终止符结束
{
if (c >= '0' && c <= '9') //如果是数字
{
if (!powerSFX) //第一个数字前加上'|'用来区分不同数字,再输入数组
{
powerSFX++;
suffixEXP[i] = '|';
i++;
suffixEXP[i] = c;
}
else //之后直接输入进数组
suffixEXP[i] = c;
i++;
c = getchar();
}
else
{
if (powerSFX) //把是否输入数字的中介清零
{
powerSFX = 0;
}
switch (precede(top_seqStackC(OPTR), c)) //比较读取运算符的优先级与运算符栈顶优先级高低
{
case '>': //优先级高直接存入运算符的栈
push_seqStackC(OPTR, c);
c = getchar();
break;
case '=': //括号相遇清除
pop_seqStackC(OPTR, &x);
c = getchar();
break;
case '<': //优先级低把运算符的栈顶输入数组,并继续比较
pop_seqStackC(OPTR, &theta);
suffixEXP[i] = theta;
i++;
break;
}
}
}
while (OPTR->top != 0) //出循环后如果运算符栈还有剩余直接依次输入数组
{
pop_seqStackC(OPTR, &theta);
suffixEXP[i] = theta;
i++;
}
}
int calculateSuffixEXP() //计算后缀表达式,并返回整数型计算结果
{
seqStackC* sfx;
int i = 0,a,b,res,pow_=0,mRes; //i用于存后缀表达式的数组的计次,a b存从栈中取出经过转化后的两个整数
powerSFX = 0; //pow_:两整数计算结果的位数 mRes协助把计算结果依次转化后存入字符栈
char rt,a_,b_;
sfx = Init_seqStackC();
while (suffixEXP[i]!=NULL) //数组内为空结束循环
{
if ((suffixEXP[i] >= '0' && suffixEXP[i] <= '9')||suffixEXP[i]=='|') //是数字或者数字区分的符号直接存入栈
{
push_seqStackC(sfx, suffixEXP[i]);
printf("\n栈内现在为:");
printSeqStackc(sfx);
i++;
}
else
{
a = 0;
b = 0; //以下几步用来把存在字符栈中的数字拼接成完整的整数
pop_seqStackC(sfx, &a_); //从栈中读取首个数字
printf("\n%c", a_);
while (a_ != '|') //读到区别的符号结束
{
a = a + (a_-48) * pow(10, powerSFX); //拼接整数
powerSFX++;
pop_seqStackC(sfx, &a_);
printf("\n%c", a_);
}
powerSFX = 0;
pop_seqStackC(sfx, &b_); //同a的转化
printf("\n%c", b_);
while (b_ != '|')
{
b = b + (b_ - 48) * pow(10, powerSFX);
powerSFX++;
pop_seqStackC(sfx, &b_);
printf("\n%c", b_);
}
powerSFX = 0;
printf("\n%c", suffixEXP[i]);
res = operate(b, suffixEXP[i],a); //把取出的两个整数进行计算,结果赋值给res
printf("\n计算后%d", res); //以下几步为把计算的结果转化为字符依次存入栈
push_seqStackC(sfx, '|'); //先存入区别符号
while (res / pow(10, pow_ + 1)>=1) //计算res的位数
pow_++;
printf("\npow_%d", pow_);
for (;pow_>=0; pow_--) //借助res的位数依次把res各个位数字存入栈
{
mRes = res / pow(10, pow_); //res的最高位赋给mRes
res = res - mRes * pow(10, pow_); //res去掉最高位数字
printf("\nmRes:%d", mRes);
push_seqStackC(sfx,mRes+48); //存入
}
pow_ = 0;
printf("\n计算后栈变为:");
printSeqStackc(sfx);
i++;
}
}
b = 0;
pop_seqStackC(sfx, &b_); //把经过计算只存储了一个整数的字符栈转化为整数,同上a的赋值
while (b_ != '|')
{
b = b + (b_ - 48) * pow(10, powerSFX);
powerSFX++;
pop_seqStackC(sfx, &b_);
}
powerSFX = 0;
return b; //返回就计算结果
}
//汉诺塔
void move(int n, char o, char p)
{
step++;
printf("第%d步:将编号为%d的圆盘从%c移动到%c\n", step,n, o, p);
}
void Hanoi(int n, char x, char y, char z)
{
if (n == 1)
move(n, x, z);
else
{
Hanoi(n - 1, x, z, y);
move(n, x, z);
Hanoi(n - 1, y, x, z);
}
}
int main()
{
//进制转换
/*int n, r;
printf("输入十进制数n和r进制\n");
scanf_s("%d %d", &n, &r);
printf("十进制%d转化成为%d进制数为\n", n, r);
conversionSystem(n, r);
getchar();*/
//表达式计算
/*int result;
printf("\n输入表达式,输入#结束\n");
result = evaluateExpression();
printf("结果为%d\n", result);
getchar();*/
//后缀表达式
int j = 0;
printf("\n输入表达式,输入#结束\n");
toSuffixExpression();
while (suffixEXP[j]!=NULL)
{
printf("%c", suffixEXP[j]);
j++;
}
printf("\n结果为%d", calculateSuffixEXP());
getchar();
//Hanoi塔
/*int n2=0;
char x = 'x', y = 'y', z = 'z';
printf("输入圆盘数目:\n");
scanf_s("%d", &n2);
Hanoi(n2, x, y, z);
printf("步骤:%d", step);
getchar();*/
return 0;
}