PAT3-07中缀表达式 strtok_r()的使用

23 篇文章 0 订阅

逆波兰式的转换因为题目中浮点数及其带符号的操作数的输入,使得自己忙活以阵子,然后发现只用一个栈来存储操作符号的时候,重新改算法,然后又在输出时必须间隔一个空格处卡住,于是一怒之下不写这道题目,转而攻中缀表达式,结果页是在接受字符串的时候耽搁了半天,终于写出了AC的程序,不过。。各人感觉对给出用例的最后一个有点奇怪,因为明显用本程序是error ,但是没有去特殊判断,然后就AC了,表示奇怪。

#include<iostream>
#include<stack>

#include<string>
#include<iomanip>
#include<vector>
using namespace std;

stack<char> operStack;
stack<float> dataStack;
map<char,int> priority;
char dataSource[35];
//中缀表达式 要从后往前来搞
float operation(float opA,float opB,char opera)
{
	switch (opera)
	{
	case '+':
		return opA + opB;
	case '-':
		return opA -opB;
	case '*':
		return opA * opB;
	case '/':
		if(opB == 0.0f)
			{
				cout<<"ERROR";
				exit(0);
		}
		else
			return opA / opB;
	default:
		cout<<"the wrong operator!"<<endl;
		exit(0);
	}

}
int main()
{
	char *t,*p;
	/*operStack.push('#');*/
	//其实不用优先级的
	vector<char *> value;
// 这里接受字符数组,在用字符串还是字符的问题上纠结了一番
	cin.get(dataSource,31);
//strtok 的用法,参数必须是字符数组,NND,后来又查到此函数线程不安全,下面附上strtok_r()的用法
	p = strtok(dataSource," ");
	value.push_back(p);
	while(p)
	{
		p = strtok(NULL," ");
		value.push_back(p);
	}
	vector<char *>::reverse_iterator iter = value.rbegin();
	iter ++;//这里很重要,最后一个是空的,因为字符数组和字符串一样,最后有一个\0表示符
	for(;iter != value.rend();iter++)
	{
		if((*iter)[0] >= '0' && (*iter)[0] <= '9' || (*iter)[1]!='\0')
		{
			float data = 0.0f;
			data = atof(*iter);
			dataStack.push(data);
		}
		else
		{
			if(dataStack.size() >= 2)
			{
				float dataA = dataStack.top();
				dataStack.pop();
				float dataB = dataStack.top();
				dataStack.pop();
				float midResult = operation(dataA,dataB,(*iter)[0]);
				dataStack.push(midResult);
			}
			else
			{
				cout<<"ERROR";
				exit(0);
			}
		}
	}
		cout<< setiosflags(ios::fixed) << setprecision(1)<<dataStack.top()<<endl;
		dataStack.pop();
		if(!dataStack.empty())
			{
				cout<<"ERROR";
				exit(0);
			}


	return 0;
	
}
strtok_c()
void split(const char * str,const char * deli, vector<string> *list) 
{ 
    char buff[1024]; 
    snprintf(buff,sizeof(buff),str); 
    char * gg; 
    char *p = strtok_r(buff, deli, &gg);

    list->clear(); 
    while(p !=NULL) 
    { 
        list->push_back(p); 
        p = strtok_r(NULL, deli, &gg); 
    }; 
}

如果确定被切分的字符串不是很长,可以适当减小buff的大小,这样应该可以提高一些效率~

这个封装的函数可以实现将一个字符串切分,并且不改变之前的字符串,切分后的字符串通过用户传入的vector<string>参数获得,这个函数木有内存泄露的问题,也是线程安全的,放心使用吧。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值