C++ 中的前缀表达式求值 [CodeEval]
Posted
技术标签:
【中文标题】C++ 中的前缀表达式求值 [CodeEval]【英文标题】:Prefix Expression Evaluation in C++ [CodeEval] 【发布时间】:2015-10-27 09:56:40 【问题描述】:Here 是挑战的链接。 这是为了您的方便:
前缀表达式 描述: 给你一个前缀表达式。编写一个程序来评估它。 输入样本: 第一个参数将是一个输入文件,每行有一个前缀表达式。例如 * + 2 3 4 您的程序必须读取此内容并将其插入您喜欢的任何数据结构中。 遍历该数据结构并评估前缀表达式。每个令牌都是 由空格分隔。您可以假设出现的唯一有效运算符 在测试数据中是 '+'、'*' 和 '/' 输出样本: 打印到标准输出,前缀表达式的输出,每行一个。例如 20"
我的代码有时会被 CodeEval 拒绝,因为编译时间超过 10 秒。当它编译时,我得到了 85/100 的分数,因为我认为在 40 个测试用例中,我得到了一些不正确的。我相信我的算法是正确的,问题仅在于检查边界/极端情况。谁能帮我优化这段代码以在 CodeEval 中工作?
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
using namespace std;
void tokenize(string& str, vector<string>& tokens)
int pos;
string token;
while ((pos = str.find(" ")) != std::string::npos )
token = str.substr(0,pos);
tokens.push_back(token);
str.erase(0, pos + 1);
tokens.push_back(str.c_str());
bool isOperator(string str)
if((str == "+") || (str == "-") || (str == "*") || (str == "/") )
return true;
else
return false;
int compute(string oper, int val1, int val2)
if(oper == "+")
return (val1 + val2);
else if(oper == "*")
return (val1 * val2);
else if(oper == "/")
return (val1 / val2);
else if(oper == "-")
return (val1 - val2);
void evalPrefix(vector<string>& expression)
vector<int> numStack;
int num1;
int num2;
for (int i = (expression.size() - 1); i >=0; i--)
if(isOperator(expression[i]))
num1 = numStack.back();
numStack.pop_back();
num2 = numStack.back();
numStack.pop_back();
numStack.push_back(compute(expression[i], num1, num2));
else
numStack.push_back(atoi(expression[i].c_str()));
cout << numStack[0] << endl;
int main(int argc, char *argv[])
ifstream file(argv[1]);
string line;
string token;
vector<string> tokens;
while (!file.eof()) //processing the file
getline(file, line);
if(line.length() == 0)
continue;
else
tokens.clear();
tokenize(line, tokens); //tokenizing the file
if(tokens.size())
evalPrefix(tokens);
return 0;
这里是最新的代码(97.5分能够编译一次):
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
using namespace std;
void tokenize(string& str, vector<string>& tokens)
int pos;
string token;
while ((pos = str.find(" ")) != std::string::npos )
token = str.substr(0,pos);
tokens.push_back(token);
str.erase(0, pos + 1);
tokens.push_back(str.c_str());
bool isOperator(string str)
if((str == "+") || (str == "*") || (str == "/") )
return true;
else
return false;
int compute(string oper, int val1, int val2)
if(oper == "+")
return (val1 + val2);
else if(oper == "*")
return (val1 * val2);
else if(oper == "/")
return (val1 / val2);
else
return 0;
void evalPrefix(vector<string>& expression)
vector<int> numStack;
int num1;
int num2;
for (int i = (expression.size() - 1); i >=0; i--)
if(isOperator(expression[i]))
num1 = numStack.back();
numStack.pop_back();
num2 = numStack.back();
numStack.pop_back();
numStack.push_back(compute(expression[i], num1, num2));
else
numStack.push_back(atoi(expression[i].c_str()));
cout << numStack[0] << endl;
int main(int argc, char *argv[])
ifstream file(argv[1]);
string line;
string token;
vector<string> tokens;
while (getline(file, line)) //processing the file
if(line.length() == 0)
continue;
else
tokens.clear();
tokenize(line, tokens); //tokenizing the file
if(tokens.size())
evalPrefix(tokens);
return 0;
【问题讨论】:
作为参考。 C# 中的此解决方案有效。他们是否在检查一些我没有的边界? github.com/rogerchang1/codeeval/blob/master/PrefixExpression.cs 一个问题是你不应该使用while (!file.eof())
,见"Why is “while ( !feof (file) )” always wrong?"。
此外,如果您只想在空格上分隔标记,std::ostringstream
和普通输出运算符 >>
也应该可以工作。或者只是将std::copy
与std::ostream_iterator
和std::back_inserter
一起使用。
@JoachimPileborg 已修复。将其更改为 while(getline(file, line))
通过更改 while 循环(访问文件),我能够将我的分数提高到 97.5。
【参考方案1】:
完成了。他们想要浮动值。谢谢。
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
using namespace std;
void tokenize(string& str, vector<string>& tokens)
int pos;
string token;
while ((pos = str.find(" ")) != std::string::npos )
token = str.substr(0,pos);
tokens.push_back(token);
str.erase(0, pos + 1);
tokens.push_back(str.c_str());
bool isOperator(string str)
if((str == "+") || (str == "*") || (str == "/") )
return true;
else
return false;
float compute(string oper, float val1, float val2)
if(oper == "+")
return (val1 + val2);
else if(oper == "*")
return (val1 * val2);
else if(oper == "/")
return (val1 / val2);
else
return 0;
void evalPrefix(vector<string>& expression)
vector<float> numStack;
float num1;
float num2;
for (int i = (expression.size() - 1); i >=0; i--)
if(isOperator(expression[i]))
num1 = numStack.back();
numStack.pop_back();
num2 = numStack.back();
numStack.pop_back();
numStack.push_back(compute(expression[i], num1, num2));
else
numStack.push_back(atoi(expression[i].c_str()));
int i = int (numStack[0] + 0.5);
cout << i << endl;
int main(int argc, char *argv[])
ifstream file(argv[1]);
string line;
string token;
vector<string> tokens;
while (getline(file, line)) //processing the file
if(line.length() == 0)
continue;
else
tokens.clear();
tokenize(line, tokens); //tokenizing the file
if(tokens.size())
evalPrefix(tokens);
return 0;
【讨论】:
以上是关于C++ 中的前缀表达式求值 [CodeEval]的主要内容,如果未能解决你的问题,请参考以下文章