表达式的计算

Posted cjj2503

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了表达式的计算相关的知识,希望对你有一定的参考价值。

数据结构----表达式的计算

说明:
本程序为表达式的计算算法实现
(1)表达式支持整数的+ - * / ( )运算,可以有空格
(2)算法从文件input.txt 中读取表达式,表达式以#结束

算法说明: (1)计算算术表达式的值时,可用两个栈作辅助工具。
(2)对于给出的一个表达式,从左向右扫描它的字符,并将操作数放入栈S1中,运算符放入栈S2中,
但每次扫描到运算符时,要把它同S2的栈顶运算符进行优先级比较,当扫描到的运算符的优先级不高于栈顶运算符的优先级时,
取出栈S1的栈顶和次栈顶的两个元素,以及栈S2的栈顶运算符进行运算将结果放入栈S1中(得到的结果依次用T1、T2等表示)。
(3)为方便比较,假设栈S2的初始栈顶为#(#运算符的优先级低于加、减、乘、除中任何一种运算)。

输入举例: 34 + ((5*8)- 20+6)#

输出: 34 + ((5*8)- 20+6) = 60

测试案例
输入案例

34 + ((5*8)- 20+6)#

输出案例

34 + ((5*8)- 20+6) = 60

代码部分
SeqStack.h

#ifndef SEQSTACK_H
#define SEQSTACK_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MaxStackSize 100
typedef int DataType;

typedef struct
	DataType stack[MaxStackSize];			
	int top;
 SeqStack;


void StackInitiate(SeqStack *S);	

int StackNotEmpty(SeqStack S);

int StackPush(SeqStack *S, DataType x);


int StackPop(SeqStack *S, DataType *d);

int StackTop(SeqStack S, DataType *d);

int StackLength(SeqStack S);
#endif

exp.h

#ifndef EXP_H
#define EXP_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum 

	 PLUS, MINUS, TIMES, OVER, LPAREN, RPAREN, JINHAO
OpType;  //頓炬륜잚謹

typedef enum 

	 NUM, OP,  ERROR   
Type;  //데늦잚謹 꾸鱗鑒 꾸鱗륜 俚륜눔써監륜 페儉댄轎데늦

int scan(int* d);
int compareOp(OpType op1,OpType op2);
int compute(int op1,int op2, OpType ot,int* result);
int expCalculation(int *result);
#endif

SeqStack.c

#include "SeqStack.h"

//初始化   
void StackInitiate(SeqStack *S)	

	S->top = 0;		

//非空否   
int StackNotEmpty(SeqStack S)

	if(S.top <= 0)	return 0;
	else return 1;



//把数据元素值x存入顺序堆栈S中,入栈成功则返回0,否则返-1
int StackPush(SeqStack *S, DataType x)

	if(S->top >= MaxStackSize-1)
		
		printf("堆栈已满无法插入!");	
		return -1;
	
	else
		
	    S->top ++;
		S->stack[S->top] = x;
		
		return 0;
	


//出栈   出栈成功则返回0,否则返-1
int StackPop(SeqStack *S, DataType *d)

	if(S->top <= 0)
		
		printf("堆栈已空无数据元素出栈!");
		return -1;
	
	else
		

		*d = S->stack[S->top];
		S->top --;
		return 0;
	

//取栈顶数据元素 ,成功返回0,失败返回-1
int StackTop(SeqStack S, DataType *d)

	if(S.top <= 0)
		
		printf("堆栈已空无数据元素!");
		return -1;
	
	else
		*d = S.stack[S.top];
		return 0;
	

//栈中元素的个数
int StackLength(SeqStack S)
 	return S.top;





exp.c


```c
#include "exp.h"
#include "SeqStack.h"
extern char str[100];
extern int index;


int scan(int* d)
	char temp[100];
	int i=0;
	while(str[index]==' ') //过滤空格
		index++;
	if(str[index]=='+')
		*d=PLUS;
		index++;
		return OP;
	
	if(str[index]=='-')
		*d=MINUS;
		index++;
		return OP;
	
	if(str[index]=='*')
		*d=TIMES;
		index++;
		return OP;
	
	if(str[index]=='/')
		*d=OVER;
		index++;
		return OP;
	
	if(str[index]=='(')
		*d=LPAREN;
		index++;
		return OP;
	
	if(str[index]==')')
		*d=RPAREN;
		index++;
		return OP;
	
	while(str[index]>='0'&&str[index]<='9')
		temp[i]=str[index];
		index++;
		i++;
	
	temp[i]='\\0';
	if(i>0)
		*d=atoi(temp);
		return NUM;
	
	
	if(str[index]=='#')
		*d=JINHAO;
		return OP;
		
	
	
	return ERROR;


//运算符优先表,用函数来表示,比较运算符 op1 和 op2 , op1>op2 返回1; < 返回-1 ; == 返回0; 非法运算符返回-2
int compareOp(OpType op1,OpType op2)
	switch(op1)
		case  PLUS:    if(op2==PLUS||op2==MINUS) return  1; if(op2==TIMES||op2==OVER) return -1; if(op2== LPAREN) return -1;if(op2== RPAREN) return 1;if(op2== JINHAO) return 1;
		case  MINUS:   if(op2==PLUS||op2==MINUS) return  1; if(op2==TIMES||op2==OVER) return -1; if(op2== LPAREN) return -1;if(op2== RPAREN) return 1;if(op2== JINHAO) return 1;
		case  TIMES:   if(op2==PLUS||op2==MINUS) return  1; if(op2==TIMES||op2==OVER) return  1; if(op2== LPAREN) return -1;if(op2== RPAREN) return 1;if(op2== JINHAO) return 1;
		case  OVER:    if(op2==PLUS||op2==MINUS) return  1; if(op2==TIMES||op2==OVER) return  1; if(op2== LPAREN) return -1;if(op2== RPAREN) return 1;if(op2== JINHAO) return 1;
		case  LPAREN:  if(op2==PLUS||op2==MINUS) return -1; if(op2==TIMES||op2==OVER) return -1; if(op2== LPAREN) return -1;if(op2== RPAREN) return 0;if(op2== JINHAO) printf("illegal expression:%s",str);return -2; 
		case  RPAREN:  if(op2==PLUS||op2==MINUS) return  1; if(op2==TIMES||op2==OVER) return  1;  if(op2== LPAREN) printf("illegal expression:%s\\n",str);exit(0); if(op2== RPAREN) return 1;if(op2== JINHAO) return 1;
		case  JINHAO:  if(op2==PLUS||op2==MINUS) return -1; if(op2==TIMES||op2==OVER) return -1; if(op2== LPAREN) return -1;if(op2== RPAREN)printf("illegal expression:%s",str);return -2; if(op2== JINHAO) return 0;
		default: printf("illegal expression!");return -2;
	


//根据不同的运算符类型计算结果,成功返回0,失败返回-1
 int compute(int op1,int op2, OpType ot,int* result)
	switch(ot)
		case  PLUS:   *result = op1+op2; return 0;
		case  MINUS:  *result = op1-op2; return 0;
		case  TIMES:  *result = op1*op2; return 0;
		case  OVER:   *result = op1/op2; return 0;
		default:printf("illegal expression!");return -1;
	

/*表达式求值算法描述:
(1)计算算术表达式的值时,可用两个栈作辅助工具。
(2)对于给出的一个表达式,从左向右扫描它的字符,并将操作数放入栈S1中,运算符放入栈S2中,
     但每次扫描到运算符时,要把它同S2的栈顶运算符进行优先级比较,当扫描到的运算符的优先级不高于栈顶运算符的优先级时,取出栈S1的栈顶和次栈顶的两个元素,
     以及栈S2的栈顶运算符进行运算将结果放入栈S1中(得到的结果依次用T1、T2等表示)。
(3)为方便比较,假设栈S2的初始栈顶为#(#运算符的优先级低于加、减、乘、除中任何一种运算)。
*/

int expCalculation(int *result)
	SeqStack s1;  //装操作数的堆栈
	SeqStack s2;  //装运算符的堆栈
	StackInitiate(&s1);
	StackInitiate(&s2);
	StackPush(&s2, JINHAO);
	int  value=0;
	Type type=-1;
	int isSuccessFinish=0;
	type=scan(&value);  //扫描到到第一个单词类型
	while(1)  
		if(type==NUM)               //如果当前扫描到的单词类型是操作数类型时,操作数进操作数栈
			StackPush(&s1,value);
			type=scan(&value);   //读取下一个单词
		
		else if(type==OP)    //如果当前扫描到的单词类型是操作符类型时,与栈顶操作符比较
			OpType o;
			if(StackNotEmpty(s2)==0) //如果堆栈为空,表达式错误
				isSuccessFinish=0;
				break;
			
			StackTop(s2,&o);
			if(value==JINHAO&&o==JINHAO) //  如果当前扫描到的单词和栈顶操作符都是#,表达式计算正确完成,设置成功标志,退出循环
				isSuccessFinish=1;
				break;
			
			int result=compareOp(o,value); //如果当前操作符号不是#,栈顶符号和当前扫描到的运算符进行优先级比较
			if(result==1)  //栈顶符号 >  当前符号, 运算符出栈并计算
			
				//补充代码
				OpType o;
				DataType a,b;
				int T1;
				StackPop(&s2,&o);
			if(StackNotEmpty(s1)==0)continue;		
			else StackPop(&s1,&b);
			if(StackNotEmpty(s1)==0)continue;	
			else StackPop(&s1,&a);
				compute(a,b,o,&T1);
				StackPush(&s1,T1);
			
			else if(result ==-1) //栈顶符号 < 当前符号, 当前符号进栈
				
				   //补充代码
				   StackPush(&s2,value);
				   type=scan(&value);  
				
				else     //栈顶符号 == 当前符号,匹配
				
				 	 //补充代码
				 	OpType o;
				 	StackPop(&s2,&o);
				 	type=scan(&value);  
				
		
		
		else if(type==ERROR)
		
				printf("illegal expression:%s");
				return -1;
				
		
	
	
	if(isSuccessFinish&&StackLength(s1)==1)
	
  		StackTop(s1,result);
  		return 0;
  	
  	else
  	
  			printf("illegal expression:%s",str);
			return -1;
  	
	
	

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "exp.h"


/*
功能:
	主函数
	
参数:
	argc - argv 数组的长度,大小至少为 1,argc - 1 为命令行参数的数量。
	argv - 字符串指针数组,数组长度为命令行参数个数 + 1。其中 argv[0] 固定指向当前
	       所执行的可执行文件的路径字符串,argv[1] 及其后面的指针指向各个命令行参数。
	       例如通过命令行输入 "C:\\hello.exe -a -b" 后,main 函数的 argc 的值为 3,
	       argv[0] 指向字符串 "C:\\hello.exe",argv[1] 指向字符串 "-a",argv[2] 指向字符串 "-b"。

返回值:
	成功返回 0, 失败返回 1
*/

char str[100];
int index=0;
int main(int argc, char* argv[])

	// 使用第一个参数输入待处理文件的名称,若没有输入此参数就报告错误
	if(argc < 2)
	
		printf("Usage: app.exe filename\\n");
		return 1;
	
	
	// 打开待处理的文件。读取文件中的内容。
	FILE* file= fopen(argv[1], "rt");
	if(NULL == file)
	
		printf("Can not open file \\"%s\\".\\n", argv[1]);
		return 1;
	
	char temp[100];

	if(fgets(temp,100,file)!=NULL)
	    index=0;
		int i=0;
		int flag=0;
		while(temp[i]!='\\0')
			str[i]=temp[i];
			if(temp[i]=='#')
				flag=1;
				break;
			
			i++;
		
		
		if(flag!=1)
	 		printf("表达式要以#结尾!\\n");
	 		exit(0)Linux shell 编程:运算

求一个匹配 以指定字符开头,指定字符结尾,中间内容任意的正则表达式

求一个匹配 以指定字符开头,指定字符结尾,中间内容任意的正则表达式

求一个匹配 以指定字符开头,指定字符结尾,中间内容任意的正则表达式

计算机基础之正则表达式

python--------re 正则表达式(计算器)