检查字符串是否与可能的输入之一匹配的最有效方法是什么?

时间:2019-06-27 14:41:31

标签: c++ coding-efficiency

我被要求同时接受数字和单位,其中单位可以是cm,m,in或ft。

为此,我有一个循环

cout << "Please put in a number and its unit.\n";
while (cin >> val >> unit) {
    if (val == '|') { break; }
    cout << "Please put in a number and its unit.\n";
}

我的问题是,在代码效率和可读性方面,检查单位字符串的最佳方法是什么?放置大的if语句更有意义

    if (unit != "cm" && unit != "m" && unit != "in" && unit != "ft") {
        cout << "Unit " << unit << " not accepted.\n";
    }

或者最好有一个我用所有单位初始化的向量,然后检查它是否与任何单位匹配。

    if (find(units.begin(), units.end(), unit) == units.end()) {
        cout << "Unit " << unit << " not accepted.\n";
    }

...其中vector<string> units = {"cm", "m", "in", "ft"};

或者在效率和可读性方面还有另一种更好的方法吗?

我希望这是问这个问题的正确地方。我考虑过代码审查,但似乎不适合这样的小问题。还是??

3 个答案:

答案 0 :(得分:1)

您的“ if”语句不仅效率更高,效率也无关紧要,因为无论您如何执行,IO都会花费大约十亿倍的时间。

它也是最易于维护的,因为如果将“ if”语句的格式设置为每单位字符串一行,那么添加,删除或重命名单位只是一行编辑,您可以轻松地在它们之间注释掉如果您改变主意。

使用向量的时间是直到运行时才知道单位是什么。

答案 1 :(得分:1)

  

放置大的if语句更有意义吗?

只有4个条目,我想说您不需要使用std::vector(并且随之而来的是分配费用)和用于测试案例的算法。如果条件的长度困扰您,请将条件打包到lambda函数中,并使用用户输入进行调用。

与直接在if语句中检查变量相比,正确命名lambda会带来更多的可读性。

const auto isMatchingUnit = [](const std::string& unit) noexcept -> bool {
    return unit == "cm" || unit == "m" || unit == "in" || unit == "ft";
};

if (isMatchingUnit(unit)) {
    // do something
} else {
    // do something else
}

话虽这么说,如果可能的输入的数量很大,您可能想将可能的输入打包到std::arraystd::vector中,并按照选择:

如果要检查的集合已排序且唯一,则可以

  • std::binary_search,如果找到了项目,则返回true
  • std::lower_bound,方法是检查std::lower_bound(container.cbegin(), container.cend(), input) != container.cend()是否为true

如果要检查的集合未未排序

  • std::find,方法是检查std::find(container.cbegin(), container.cend(), input) != container.cend()是否为true
  • std::any_of,带有适当的谓词。

答案 2 :(得分:0)

最有效的方法是对经过排序的字符串数组使用std::lower_bound,因此它不会搜索所有字符串。如果您使用直接比较或std :: find,则将全部搜索。

对于较小的向量,它可能并不重要(它甚至可能比直接比较要慢),但对于较大的集合,它将变得重要。