华为机试-2014

题目大意:有字符串表示的一个四则运算表达式,要求计算出该表达式的正确数值。四则运算即:加减乘除"+-*/",另外该表达式中的数字只能是1位(数值范围0~9)。另若有不能整除的情况,按向下取整处理,eg: 8/3得出值为2。
  若有字符串"8+7*2-9/3",计算出其值为19。


本人使用的是《渐降解析法》---》由于使用c语言,没有直接的栈可以使用,所以个人感觉机试的话还是有一定难度!


思路是:由于乘除运算级高,把乘除运算整体当做一个项,数也算一项,那么加减的话只需对项处理。


__表达式___
 |            |             
 |___+__|
 |___-___|


____项___
 |            |
 |___*__|
 |___/___|

比较容易理解的逆波兰式解法见: 字符串的四则运算

//一些其他错误还未考虑,但考虑了除数为0!


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>


int eval_term(char * string,int *pos)
{
int value_1 = 0;
int value_2 = 0;
int result = 0;
char cmd='0';


if (*string == '\0')
{
printf("error:empty\n");
return -1;
}


if (!isdigit(*string))
{
return -1;
}
value_1=atoi(string);
result = value_1;


while (1)
{
value_1 = result;
string++;
(*pos)++;


if (*string == '*'||*string == '/')
{
value_1 = result;
cmd = *string;
}
else
{
(*pos)--;
break;

}


string++;
if (!isdigit(*string))return -1;
(*pos)++;
value_2=atoi(string);


if (cmd == '*')
{
result =  value_1*value_2;
}
else
{
if(value_2 == 0)
{
printf("除数不能为0!\n");
return -1;
}
result =  value_1/value_2;
}
}

return result;
}


int main()
{

int value_1 = 0;
int value_2 = 0;
int result = 0;
char cmd='0';
char *string_temp=NULL;
int pos=0;
//char *string ="2+1*2*4/2+6*3/3+2";
char string[255] ="";

printf("请输入表达式:");
fgets(string,255,stdin);//-->会带上换行符!


if ((value_1 = eval_term(string+pos,&pos))==-1)//起始下面这一段封转为一个函数,感觉会更直观,专门处理加减运算!
{
return 0;
}
result = value_1;


while (1)//可改为判断长度
{
value_1 = result;
pos++;
string_temp = string+pos;


if (*string_temp == '\n')//先出现换行符!
{
break;
}


if (*string_temp == '-'||*string_temp == '+')
{
cmd = *string_temp;
}
else
{
printf("标准表达式不对!\n");
return 0;
}


pos++;
if ((value_2 = eval_term(string+pos,&pos))==-1)
{
printf("标准表达式不对!\n");
return 0;
}


if (cmd == '+')
{
result =  value_1+value_2;
}
else
{
result =  value_1-value_2;
}
}

printf("the result:%d\n",result);


return 1;
}

上述如有不妥,欢迎大家指正,谢谢!


更改于2013、9、18中秋前一天!


//把上面的代码重新写了以下,下面的情况只处理前半部分正确的表达式!


#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

int term(char *string ,int *pos);
int ceil(char *string ,int *pos);
int expression(char *string ,int *pos);

int ceil(char *string ,int *pos)//处理元素
{
	int value_data = -1;
	
	if (isdigit(*(string+*pos)))
	{
		value_data = atoi((char*)(string+*pos));
		(*pos)++;
	}
	
	return value_data;

}

int term(char *string ,int *pos)//处理项
{
	int value_data1 = -1;
	int value_data2 = -1;
	int result = -1 ;
	char opt = ' ';
	value_data1 = ceil(string ,pos);
	if (value_data1 == -1)
	{
		(*pos)--;
		return value_data1;
	}
	result = value_data1;
	while (value_data1 != -1)
	{
		if (*(string+*pos)=='*' || *(string+*pos)=='/')
		{  
			opt = *(string+*pos);
			(*pos)++;

			value_data2 = ceil(string ,pos);//判断是否是项
		

			if (value_data2 == -1)
			{
				(*pos)--;
				return result;
			}
		}
		else
		{
			return result;
		}
		if (opt == '*')
		{
			result = value_data1 * value_data2;
		}
		else
		{
			result = value_data1 / value_data2;
		}
		value_data1 = result ;
	
	}
	
	return result;

}



int expression(char *string ,int *pos)//处理表达式
{
	int value_data1 = -1;
	int value_data2 = -1;
	int result = -1 ;
	char opt = ' ';

	value_data1 = term(string ,pos);//判断是否是项
	result=value_data1;
	while (value_data1 != -1)
	{
		
		if (*(string+*pos)=='+'||*(string+*pos)=='-')
		{
			opt = *(string+*pos);
			(*pos)++;
			value_data2 = term(string ,pos);//判断是否是项

			if (value_data2 == -1)
			{
				(*pos)--;
				return result;
			}

		}
		else
		{
			return result;
		}
		if (opt == '+')
		{
			result = value_data1 + value_data2;
		}
		else
		{
			result = value_data1 - value_data2;
		}
			value_data1 = result ;
	}
	
	return result;

}

int main()
{
	char string[255];
	int pos = 0;
	int value = 0;

	fgets(string,255-1,stdin);
	printf("%s",string);
	value = expression(string,&pos);
	printf("value:%d \n",value);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值