基于栈运算的算术表达式(纠错判错)

#define ISNUM -30
#define NOTNUM -50

double atof(const char *);

double gd[100]={0};
char gc[100]={0};

int id = 0,ic = 0 ;

void pushD(double data)
{
	gd[id++] = data;
}

int popD(double * data)
{
	if( id < 1)	return 0;
	* data = gd[--id] ;
	return 1;
}

int GetTopD(double * data)
{
		if( id < 1)	return 0;
	* data = gd[id - 1] ;
	return 1;
}

/**************/
void pushC(char data)
{
	gc[ic++] = data;
}

int popC(char * data)
{
	if( ic < 1)	return 0;
	* data = gc[--ic] ;
	return 1;
}

int GetTopC(char * data)
{
	if( ic < 1)	return 0;
	* data = gc[ic - 1] ;
	return 1;
}
/**************/

int IsNum(char c)
{
	if(( c >= '0'  && c<= '9') || c == '.')
			return 1;
	return 0;
}

char precede(char a,char b)
{
	int p1 =0,p2 = 0;
	char table[7][7]={
	'>','>','<','<','<','>','>',
	'>','>','<','<','<','>','>',	
	'>','>','>','>','<','>','>',
	'>','>','>','>','<','>','>',	
	'<','<','<','<','<','=','E',
	'>','>','>','>','E','>','>',
	'<','<','<','<','<','E','=',
	};

	if( a == '+' ) p1 = 0;
	if( a == '-' ) p1 = 1;
	if( a == '*' ) p1 = 2;
	if( a == '/' ) p1 = 3;
	if( a == '(' ) p1 = 4;
	if( a == ')' ) p1 = 5;
	if( a == '#' ) p1 = 6;

	if( b == '+' ) p2 = 0;
	if( b == '-' ) p2 = 1;
	if( b == '*' ) p2 = 2;
	if( b == '/' ) p2 = 3;
	if( b == '(' ) p2 = 4;
	if( b == ')' ) p2 = 5;
	if( b == '#' ) p2 = 6;
	
	return table[p1][p2];
}

double oprate(double a ,double b,char ch)
{
	if( ch == '+' ) return a+b;
	if( ch == '-' ) return a-b;
	if( ch == '*' ) return a*b;
	if( ch == '/' ) return a/b;
	return 0;
}

/*向字符串str在pos的位置插入一个字符c*/
int InsertStr(char * str,char c,int pos)
{
	int i =0 , len ;
	if(!str) return 0;

	len = strlen(str);

	for(i = len;i>pos;i--)
	{
		str[i] = str[i-1];
	}
	str[pos] = c;

	return 1;
}

int DeleteStr(char * str , char c,int pos)
{
	int i =0 ,len;
	if(!str) return 0;

	len = strlen(str);
	for(i = pos; i <= len; i++)
	{
		str[i] = str[i+1];
	}
	return 1;
}

int LegalExp(char * str)
{
	int n = 0 , c = 0;
	if( ! str)	return 0;
	
	while(str[n])
	{
		if( IsNum(str[n]) )
		{
			if(str[n] == '.' && ++c > 1)	return n;
		}
		else if( str[n] == '+' ||  str[n] == '-' ||  str[n] == '*' ||  str[n] == '/' || str[n] == '(' || str[n] == ')' )
		{
			/* 运算符后面是运算符或者( 都为错误 */
			if( ( str[n] == '+' ||  str[n] == '-' ||  str[n] == '*' ||  str[n] == '/' ) &&
				 (str[n+1] == '+' ||  str[n+1] == '-' ||  str[n+1] == '*' ||  str[n+1] == '/'   || str[n+1] == ')' || str[n+1] == 0))
				 return n;

			/* +  - 前面是( 或者为第一个就插入一个0 */
			if( ( str[n] == '+' ||  str[n] == '-' )  && ( n==0 || str[n-1]=='(' ) )
				InsertStr(str,'0',n);
 
			/*(前面是')'或者是数字则插入一个‘*’*/
			if( str[n] == '(' &&  n > 0  && ( IsNum(str[n-1]) || str[n-1] == ')' ) )
				InsertStr(str,'*',n);

			/*(是最后一个,错误*/
			if( str[n] == '('  &&  str[n+1] == '\0'  )
				return n;
			
			/*)是第一个,错误*/
			if( str[n] == ')' && n==0   )
				return n;

			if( str[n] == ')'  && IsNum(str[n+1]) )
				InsertStr(str,'*',n+1);
			/* )后面接着一个数字要插入一个‘*’*/
			c = 0;
		}
		else
			return n;
		n++;
	}

	return -1;
}

int GetNext(char * str,char * host,int * pos)
{
	int ret = 0 , n = 0 ;

	if(!(str&& pos && host)	)	return 0;

	n = * pos;

	ret = IsNum(str[n]);

	while(str[n] && ret == IsNum(str[n]))
	{
		if(str[n] == '(' || str[n] == ')')
		{
			n = *pos + 1;
			break;
		}
		n++;
	}

	memcpy(host,& str[*pos] , n - (*pos));

	ret = *pos ; 
	*pos  = n;
	n = ret;
	if( str[n] == '+' ||  str[n] == '-' ||  str[n] == '*' ||  str[n] == '/' 
		|| str[n] == '(' || str[n] == ')' || str[n] == '#' )
		return NOTNUM;

	return ISNUM;

}

int EvaluateExp(char* str,double * answer)
{
	int pos = 0,ret = 0;
	char theta = 0,ch;
	double a,b;
	char host[20] = {0} ;
	if(!(str&& answer))	return 0;
	ic = 0;
	id = 0;
	pushC('#');
	ch = '#';

	ret = GetNext(str,&host,&pos);

	while(ch != '#' || host[0] != '#')
	{
		if( ret == ISNUM)
		{
			pushD(atof(host));
			memset(host,0,20);
			ret = GetNext(str,&host,&pos);
		}
		else
		{	
			GetTopC(&ch);
			
			switch(precede(ch,host[0]))
			{
			case '<':	pushC(host[0]);
						memset(host,0,20);
						ret = GetNext(str,&host,&pos);

				break;

			case '=': if(! popC(&ch))	return 0;
						memset(host,0,20);
						ret = GetNext(str,&host,&pos);
				break;

			case '>':	if(! popC(&ch))	return 0;
						if(! popD(&a))	return 0;
						if(! popD(&b))	return 0;
 
						pushD(oprate(b,a,ch));
				break;

			case 'E':	return 0;
				break;
			}

		}
		GetTopC(&ch);

	}

	if(!GetTopD(answer))  return 0;
	return 1;

}

main()
{
	char str[100]={0};
	double answer = 0.0;
	int Error = 0 , i = 0;
	gets(str);
	while(str[0] != 'q')
	{
			Error = LegalExp(str);
			if(0 <= Error)
			{
				for(  i = 0 ; i<  Error ;  printf(" "),i++);
				printf("^  error expression! \n",Error);
				memset(str,0,100);
				gets(str);
				continue;
			}
			str[strlen(str)]= '#';
				printf("%s \n",str);
			if(!EvaluateExp(&str,&answer))
				printf("Error Occured When Caculate!\n");
			else
			printf("The answer is %g \n",answer);

			memset(str,0,100);
			gets(str);
	}

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值