📄 05061040-3-0.txt
字号:
#include"stdio.h" /* 头文件 */
#include"stdlib.h"
#include"math.h"
#define ERROR 0 /* 宏定义 */
#define TURE 1
#define FALSE 0
#define OK 1
#define arraySize 100 /* 空间基大小 */
#define Increment 10 /* 每次空间扩展长度 */
struct Lstack
{
char *base;
char *top;
int length;
int stacksize;
}stack,stack2;
struct lstack
{
double t[30];
int top;
};
struct Lstack *InitStack(struct Lstack *S); /* 函数声明 */
char Gettop(struct Lstack *S);
int Push(struct Lstack *S,char t);
char Pop(struct Lstack *S);
int StackEmpty(struct Lstack *S);
void ClearStack(struct Lstack *S);
int StrLength(char s[]);
char *read(char *a,int size);
void prit_opr(char *a,int size);
int Precedence(char op);
char *change(char *S1,char *S2);
double Calculate(char *str);
void menu();
void chiose(struct Lstack *ptr,char choose);
int main()
{
char yes_no,choose; /*yes_no,choose 表示循环和分支控制变量*/
double s=0;
struct Lstack *S1=&stack,*S2=&stack2; /* 定义结构体指针 */
InitStack(S1);InitStack(S2);
do
{
clrscr(); /*清屏函数*/
menu();
printf("\n ");
choose=getch(); /* 输入选择变量 */
switch(choose)
{ case 'a':printf("\n 你的选择是: %c\n\n",choose); /* 栈初始化 */
read(S1->base,S1->stacksize);
S1->length=StrLength(S1->base);
change(S1->base,S2->base);
s=Calculate(S2->base);
S2->length=StrLength(S2->base);
printf("\n 表达式 ");
prit_opr(S2->base,S2->length);
printf(" = %f\n ",s);
break;
case '0':break; /* 退出 */
default: printf("\n %c 是非法选择!\n\n",choose);
}
if(choose=='0') break; /*退出分支结构*/
printf("\n 是否继续运行该程序(Y/N)?\n");
do /* 退出外循环 */
{ yes_no=getch();
}while(yes_no!='Y'&&yes_no!='y'&&yes_no!='N'&&yes_no!='n');
}while(yes_no=='Y'||yes_no=='y');
getch();
return 0;
}
void menu() /* 菜单函数 */
{
printf("\n\n\n\n\n"); /*显示主菜单*/
printf(" |-------------------------------------------------------|\n");
printf(" | 表达式求值 |\n");
printf(" |-------------------------------------------------------|\n");
printf(" | |\n");
printf(" | 1、 程序解释: |\n");
printf(" | |\n");
printf(" | 可操作数: 整型、字符型 |\n");
printf(" | 可操作运算符: + - * / ( ) |\n");
printf(" | 计算方法: 后缀表达式求值 |\n");
printf(" | 输入方式: 中缀表达式输入 |\n");
printf(" | 转换过程: 中缀转化为后缀 |\n");
printf(" | 过程思想: 栈操作运算思想 |\n");
printf(" | |\n");
printf(" | 2、程序选择: |\n");
printf(" | |\n");
printf(" | a-----进入运算程序 |\n");
printf(" | 0-----退出运算程序 |\n");
printf(" |-------------------------------------------------------|\n");
printf(" 请输入您的选择从 0 或 a: ");
}
void prit_opr(char *a,int size) /* 输出后缀表达式 */
{ int i;
for(i=0;i<size&&*a!='#';i++)
{ printf("%c",*a);a++;}
}
char *read(char *a,int size) /* 输入后缀式 */
{ char ch;
int i=0;
printf("\n 请输入计算表达式(以'#'结束):");
do
{
ch=getch();
*a=ch;
printf("%c",ch);
a++;i++;
}while(ch!='#'&&i<=size);
return a;
}
struct Lstack *InitStack(struct Lstack *S) /* 字符栈初始化 */
{ S->base=(char *)malloc(arraySize*sizeof(char));
if(!(S->base)) exit(ERROR);
S->top=S->base;
S->stacksize=arraySize;
S->length=0;
return S;
}
struct stack *InitStack1(struct lstack *S) /* 浮点数栈初始化 */
{ S->top=-1;
S->t[0]=0;
}
char Gettop(struct Lstack *S) /* 取字符栈栈顶元素 */
{
char t;
if(S->base==S->top) return ERROR;
t=*(S->top-1);
return t;
}
int Push(struct Lstack *S,char t) /* 字符入栈操作 */
{
if(S->top-S->base>=S->stacksize)
{ S->base=(char *)realloc(S->base,(S->stacksize+Increment)*sizeof(char));
if(!S->base) exit(ERROR);
S->top=S->base+S->stacksize;
S->stacksize+=Increment;
}
*(S->top++)=t;
return OK;
}
double Push1(struct lstack *S,double t) /* 浮点数入栈操作 */
{ ++(S->top);
S->t[S->top]=t;
return t;
}
char Pop(struct Lstack *S) /* 字符出栈 */
{
char t;
if(S->top==S->base) return ERROR;
t=*(--S->top);
return t;
}
double Pop1(struct lstack *S) /* 浮点数出栈 */
{ double t;
t=S->t[S->top];
--(S->top);
return t;
}
int StrLength(char s[]) /* 求栈长 */
{int flag=0;
while(s[flag]!='\0')
flag++;
return(flag);
}
int StackEmpty(struct Lstack *S) /* 判断字符栈是否为空 */
{
if(S->top==S->base) return TURE;
else return FALSE;
}
int StackEmpty1(struct lstack *S) /* 判断浮点数栈是否为空 */
{
if(S->top==-1) return TURE;
else return FALSE;
}
void ClearStack(struct Lstack *S) /* 清空栈 */
{
if(S->top!=S->base) free(S->base);
S->base=NULL;
S->top=S->base;
S->stacksize=0;
S->length=0;
}
char *change(char *S1,char *S2) /* 中缀转换为后缀 */
{
struct Lstack *R; /* 设置一暂时栈存放符号 */
int i=0,j=0;
char w,ch=S1[i];
InitStack(R); /* 符号栈初始化 */
Push(R,'#');
while(ch!='#') /* 中缀表达式以 # 结束 */
{ if(ch==' ') ch=S1[++i];
else if(ch=='(') /* 碰到左括弧,入栈取下一个字符 */
{ Push(R,ch);
ch=S1[++i];
}
else if(ch==')') /* 右括弧,符号出栈,直到遇到左括弧 */
{ while(Gettop(R)!='(') S2[j++]=Pop(R);
Pop(R);
ch=S1[++i];
}
else if(ch=='+'||ch=='-'||ch=='*'||ch=='/') /* 计算符号,判断前后优先级 */
{ w=Gettop(R);
while(Precedence(w)>=Precedence(ch))
{ S2[j++]=w;Pop(R); /* 栈中符号优先级高于表达式取的符号优先级,符号出栈 */
w=Gettop(R);
}
Push(R,ch); /* 否则,符号入栈 */
ch=S1[++i];
}
else /* 非合法字符,警示错误! */
{ if((ch<'0'||ch>'9')&&ch!='.')
{ printf("\n 中缀表达式表示错误!");
exit(1);
}
while((ch>='0'&&ch<='9')||ch=='.') /* 遇到数字字符,直接存入另一字符串 */
{ S2[j++]=ch;
ch=S1[++i];
}
S2[j++]=' '; /* 区分数字和符号,以空格隔开 */
}
}
ch=Pop(R);
while(ch!='#') /* 括号不匹配,报告错误! */
{ if(ch=='(')
{ printf("\n 表达错误!");
exit(1);
}
else /* 符号出栈 */
{ S2[j++]=ch;
ch=Pop(R);
}
}
S2[j++]='\0';
return S2;
}
int Precedence(char op) /* 符号优先级比较 */
{
switch(op)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
case '#':
default : return 0;
}
}
double strdou(char a[],int n,int t) /* 字符转换为相应的浮点数 */
{ /* a,n,t,分别表示浮点字符串,数组大小,小数点位置 */
int i=0,j=1,m=0;
double number=0,s=0;
i=0;
while(i<n&&a[i]!='#')
{ m=a[i]-'0';
s=m*pow(10,t-j-1);
number+=s;j++;i++;
if(a[i]=='.')
i++;
}
return number;
}
double Calculate(char *str) /* 计算后缀表达式 */
{ struct lstack *S; /* 设置暂时浮点数栈 */
int i=0,j,k;
char tem[30]; /* 存放浮点字符串 */
double x=0.0;
InitStack1(S);
while(str[i]) /* 字符串不为空时操作 */
{ if(str[i]==' ') /* 遇到空格直接取下一个字符 */
{ i++;continue;}
switch(str[i])
{ case '+': /* 浮点数出栈相加 */
x=Pop1(S)+Pop1(S);
i++;break;
case '-':
x=Pop1(S); /* 浮点数出栈相减 */
x=Pop1(S)-x;
i++;break;
case '*':
x=Pop1(S)*Pop1(S); /* 浮点数出栈相乘 */
i++;break;
case '/': /* 浮点数出栈相除 */
x=Pop1(S);
if(x!=0.0) x=Pop1(S)/x;
else
{ printf("\n 除数为 0 ,行程错误!");exit(1);}
i++;break;
default : /* 遇到浮点字符,把一个表示浮点数的字符串存入tem数组 */
x=0;j=0;k=0;
while(str[i]>=48&&str[i]<=57)
{ tem[j]=str[i];i++;j++;}
if(str[i]=='.')
{ tem[j++]=str[i];i++;k=j;
while(str[i]>=48&&str[i]<=57)
{ tem[j++]=str[i];i++;}
}
if(k==0) { k=++j;tem[--j]='#';} /* K表示记录小数点位置 */
tem[j]='#';
x=strdou(tem,30,k); /* 调用浮点字符串转化为浮点数的函数 */
}
Push1(S,x); /* 转化的浮点数入栈 */
}
if(StackEmpty1(S)) { printf("\n 操作错误,栈为空!");return ERROR;}
x=Pop1(S);
if(StackEmpty1(S)) return x; /* 返回操作结果 */
else { printf("\n 表达错误!");return ERROR;}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -