- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要阅读开头带有特定关键字的多行。我有一个基本问题,需要帮助。
这里是输入的种类:
keyword1 0.0 0.0
keyword1 1.0 5.0
keyword2 10.0
keyword3 0.5
keyword4 6.0
规则是:
包含 keyword1 和 keyword2 的行应该按此顺序排列并位于任何其他行之前。
包含 keyword3 和 keyword4 的行可以任意顺序
keyword1 必须后跟 2 double
关键字 2、3 和 4 必须后跟 1 个双数
在包含所有四个关键字及其 double 的行的末尾,“循环”中断并触发计算。
这是我的来源:
using namespace std;
int main (int argc, const char * argv[]) {
vector<double> arrayInputs;
string line;
double keyword1_first, keyword1_second, keyword4,
keyword3, keyword2;
bool inside_keyword1=false, after_keyword2=false,
keyword4_defined=false, keyword3_defined=false ;
//cin.ignore();
while (getline(cin, line)) {
if (inside_keyword1 && after_keyword2 && keyword3 && keyword4) {
break;
}
else
{
std::istringstream split(line);
std::vector<std::string> tokens;
char split_char = ' ';
for (std::string each; std::getline(split, each, split_char); tokens.push_back(each));
if (tokens.size() > 2)
{
if (tokens[0] != "keyword1") return EXIT_FAILURE; // input format error
else
{
keyword1_first = atof(tokens[1].c_str());
keyword1_second = atof(tokens[2].c_str());
inside_keyword1 = true;
}
}
else
{
if (tokens[0] == "keyword2")
{
if (inside_keyword1)
{
keyword2 = atof(tokens[1].c_str());
after_keyword2 = true;
}
else return EXIT_FAILURE; // cannot define anything else keyword2 after keyword1 definition
}
else if (tokens[0] == "keyword3")
{
if (inside_keyword1 && after_keyword2)
{
keyword3 = atof(tokens[1].c_str());
keyword3_defined = true;
}
else return EXIT_FAILURE; // cannot define keyword3 outside a keyword1
}
else if (tokens[0] == "keyword4")
{
if (inside_keyword1 && after_keyword2)
{
keyword4 = atof(tokens[1].c_str());
keyword4_defined = true;
}
else return EXIT_FAILURE; // cannot define keyword4 outside a keyword1
}
}
}
}
// Calculation
// output
return EXIT_SUCCESS;
}
我的问题是:除了在读取/解析循环中使用 bool 值之外,还有更有效的方法吗?
最佳答案
您问的是“更高效”的东西,但您似乎没有特定的性能目标。所以你在这里想要的可能更像是代码审查。有一个网站,特别是:
https://codereview.stackexchange.com/
但是无论如何...
您的直觉是正确的,这里并不是真正需要四个 bool 值。那是 2^4 = 16 种不同的“状态”,其中许多是您永远无法到达的。 (例如,您的规范明确禁止在 keyword3_defined == true
时使用 after_keyword1 == false
)。
当然,程序状态可以保存在枚举和 bool 值中。这使得“健忘”循环有可能在不同情况下重新访问一行代码,但仍然记得它处于处理的哪个阶段。它在许多情况下都很有用,包括在复杂的解析器中。但是,如果您的任务是线性且简单的,则最好隐式地“了解”基于已到达特定代码行的状态。
作为展示我正在谈论的对比的教育示例,这是一个愚蠢的状态机,可以在一封信中阅读 A
后跟任意数量的字母 B
小号:
enum State {
beforeReadingAnA,
haveReadAnA,
readingSomeBs,
doneReadingSomeBs
};
State s = beforeReadingAnA;
char c;
while(true) {
switch (s) {
case beforeReadingAnA:
cin >> c;
if (cin.good() && c == 'A') {
// good! accept and state transition to start reading Bs...
s = haveReadAnA;
} else {
// ERROR: expected an A
return EXIT_CODE_FAILURE;
};
break;
case haveReadAnA:
// We've read an A, so state transition into reading Bs
s = readingSomeBs;
break;
case readingSomeBs:
cin >> c;
if (cin.good() && c == 'B') {
// good! stay in the readingSomeBs state
} else if (cin.eof()) {
// reached the end of the input after 0 or more Bs
s = doneReadingSomeBs;
} else {
// ERROR: expected a B or the EOF
return EXIT_CODE_FAILURE;
}
break;
case doneReadingSomeBs:
// all done!
return EXIT_CODE_SUCCESS;
}
}
如前所述,这是一种非常非常有用的风格编码。然而,对于这种情况,这是荒谬的。与执行相同操作的简单线性代码进行比较:
// beforeReadingAnA is IMPLICIT
char c;
cin >> c;
if (cin.fail() || c != 'A')
return EXIT_CODE_FAILURE;
// haveReadAnA is IMPLICIT
do {
// readingSomeBs is IMPLICIT
cin >> c;
if (cin.eof())
return EXIT_CODE_SUCCESS;
if (cin.fail() || c != 'B')
return EXIT_CODE_FAILURE;
}
// doneReadingSomeBs is IMPLICIT
所有的状态变量都消失了。它们是不必要的,因为程序只是“知道它在哪里”。如果您重新考虑您的示例,那么您可能也可以这样做。您不需要四个 bool 值,因为您可以将光标放在一行代码上,然后自信地说出如果该行代码恰好在运行,这四个 bool 值必须是。 p>
就效率而言,<iostream>
类可以让生活比你在这里更轻松,并且更符合 C++ 的习惯,而无需调用像 atof
这样的 C 主义。或者不得不使用 c_str()
.让我们看一下您的代码的简化摘录,它只读取与“keyword1”关联的 double 值。
string line;
getline(cin, line);
istringstream split(line);
vector<string> tokens;
char split_char = ' ';
string each;
while (getline(split, each, split_char)) {
tokens.push_back(each);
}
double keyword1_first, keyword1_second;
if (tokens.size() > 2) {
if (tokens[0] != "keyword1") {
return EXIT_FAILURE; // input format error
} else {
keyword1_first = atof(tokens[1].c_str());
keyword1_second = atof(tokens[2].c_str());
}
}
对比一下:
string keyword;
cin >> keyword;
if (keyword != "keyword1") {
return EXIT_FAILURE;
}
double keyword1_first, keyword1_second;
cin >> keyword1_first >> keyword1_second;
魔法。 Iostreams 可以检测您尝试读取或写入的类型。如果它在按照您要求的方式解释输入时遇到问题,那么它会将输入保留在缓冲区中,以便您可以尝试以另一种方式读取它。 (在请求字符串的情况下,行为是读取一系列字符直到空格...如果您真的想要整行,您可以像以前那样使用 getline
。)
但是,错误处理是您必须处理的事情。可以告诉 iostreams 使用异常处理方法,以便遇到问题(例如在预期为 double 的地方的随机词)的标准响应将是使您的程序崩溃。但是默认是设置一个你需要测试的失败标志:
iostream 有细微差别,所以您可能想做一些问答调查...我最近在此处回答/提问时自己也学到了一些东西:
关于c++ - 阅读多行,但特别是......有效地解析它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7784200/
我已经可以在其中输入一些附加文本了mydomain/wiki/Special:UserLogin。我添加了一句话: In order to apply for an account send an m
有人可以解释以下脚本输出背后的逻辑吗? import numpy if(numpy.dtype(numpy.float64) == None): print "Surprise!!!!" 谢谢
是我还是 gmail bulls**t?在 outlook/浏览器上,我的电子邮件是完美的,但在 gmail 上,2 个表之间有一个空间,为什么?!?图片:http://i.imgur.com/srJ
我是一名优秀的程序员,十分优秀!