比较std::string
的最佳方式是什么?显而易见的方法是if
/ else
:
std::string input;
std::cin >> input;
if ( input == "blahblahblah" )
{
// do something.
}
else if ( input == "blahblah" )
{
// do something else.
}
else if ( input == "blah" )
{
// do something else yet.
}
// etc. etc. etc.
另一种可能性是使用std::map
和switch
/ case
。在进行这些比较(例如8,10,12 +)时,最好的方法是什么?
答案 0 :(得分:25)
这是使用std :: map。
的示例#include <map>
#include <string>
#include <iostream>
#include <utility>
void first()
{
std::cout << "first\n";
}
void second()
{
std::cout << "second\n";
}
void third()
{
std::cout << "third\n";
}
int main()
{
typedef void(*StringFunc)();
std::map<std::string, StringFunc> stringToFuncMap;
stringToFuncMap.insert(std::make_pair("blah", &first));
stringToFuncMap.insert(std::make_pair("blahblah", &second));
stringToFuncMap.insert(std::make_pair("blahblahblah", &third));
stringToFuncMap["blahblah"]();
stringToFuncMap["blahblahblah"]();
stringToFuncMap["blah"]();
}
输出是:
second
third
first
这种方法的好处是:
使用boost :: function来使语法更好一些,特别是对于类成员函数。
答案 1 :(得分:3)
使用operator==
非常好,但如果性能非常重要,您可以根据用例进行改进。如果目标是选择一个选项之一并执行特定操作,则可以使用TRIE。此外,如果字符串足够不同,您可以执行以下操作:
switch(s[0]) {
case 'a':
// only compare to strings which start with an 'a'
if(s == "abcd") {
} else if (s == "abcde") {
}
break;
case 'b':
// only compare to strings which start with an 'b'
if(s == "bcd") {
} else if (s == "bcde") {
}
break;
default:
// we know right away it doesn't match any of the above 4 choices...
}
基本上使用字符串中的某个字符,它具有良好的唯一性(如果所有字符串的长度至少为N,则在N之前的任何字符中都不必是第一个!)来执行switch
然后执行对符合该独特特征的字符串子集进行一系列比较
答案 2 :(得分:1)
“12”并不是很多......但无论如何。
您只能使用switch
作为整数类型(char
,int
等),因此对于std::string
来说是不可能的。使用地图可能更具可读性。
然后,这一切都取决于你如何定义“最佳”。
答案 3 :(得分:0)
这个问题的答案完全取决于问题。你已经列举了两个例子。您可以添加诸如哈希表,正则表达式等选项......
答案 4 :(得分:0)
通过8,10甚至12个比较,你仍然可以使用if ... else if ...
方案,没什么不好的。如果你想要100或者其他东西,我建议写一个函数来计算字符串的散列(即使是通过简单的xoring所有字符,但是其他一些好的方法更适合更好的分配),然后将其结果切换为Evan建议。如果函数返回所有可能输入字符串的唯一数字 - 那就更好了,不需要进行额外的比较。
答案 5 :(得分:0)
如果你的意思是“最有效”,那么请提前阅读。
如果有很多话,我建议使用以下方法 Switch中的字符串实际上是Java 7中的字符串。(作为Project Coin的一部分)
根据proposal,这是Java语言实现它的方式
首先,计算每个字符串的哈希值。这个问题是一个“switch int”问题,它以大多数当前语言提供,并且是有效的。在每个case语句中,然后检查这是否真的是字符串(在极少数情况下,不同的字符串可以散列到相同的int)。
我个人有时不会在实践中做最后一步,因为它的必要性取决于你特定程序所处的情况,即字符串是否在程序员的控制之下以及程序需要多么强大。
对应的样本伪代码
String s = ...
switch(s) {
case "quux":
processQuux(s);
// fall-through
case "foo":
case "bar":
processFooOrBar(s);
break;
case "baz":
processBaz(s);
// fall-through
default:
processDefault(s);
break;
}
来自the fore-mentioned proposal以帮助您理解。
// Advanced example
{ // new scope for synthetic variables
boolean $take_default = false;
boolean $fallthrough = false;
$default_label: {
switch(s.hashCode()) { // cause NPE if s is null
case 3482567: // "quux".hashCode()
if (!s.equals("quux")) {
$take_default = true;
break $default_label;
}
processQuux(s);
$fallthrough = true;
case 101574: // "foo".hashCode()
if (!$fallthrough && !s.equals("foo")) {
$take_default = true;
break $default_label;
}
$fallthrough = true;
case 97299: // "bar".hashCode()
if (!$fallthrough && !s.equals("bar")) {
$take_default = true;
break $default_label;
}
processFooOrBar(s);
break;
case 97307: // "baz".hashCode()
if (!s.equals("baz")) {
$take_default = true;
break $default_label;
}
processBaz(s);
$fallthrough = true;
default:
$take_default = true;
break $default_label;
}
}
if($take_default)
processDefault(s);
}