如何通过一个string数组并为不同的string应用函数?

好吧,这可能是一个真正的问题,但我希望有一些我还不知道的东西。

我通过一个文件,并检查每一行有哪些string,根据string值我执行不同的function(或function)。

这是我现在这样做的:

编辑:我需要使用if-else-if范围内的variables,更新代码:

string s1 = "used"; string s2 = "in"; string s3 = "functions"; if(str == "something"){ something = process(s1, s2); }else if(str == "something else"){ something = process(s2, s3); }else if(str == "something more"){ something = process(s1, s3); something = process(s1, s2); }else if(str == "something again"){ // do more stuff }else if(str == "something different"){ // do more stuff }else if(str == "something really different"){ // do more stuff } 

我恐怕这将成为“慢”后,我不得不重复这些如果线很多… …

我试图使用switch()语句,但显然它不工作在这里,是否有类似switch()在这里使用?

如果你只是想执行不同的函数,你可以使用字符串映射函数指针或函数,如boost::function / tr1::function

 void f1() { /* ... */ } void f2() { /* ... */ } // ... creating the map: typedef void (*FuncPtr)(); typedef std::map<std::string, FuncPtr> FuncMap; FuncMap fnMap; fnMap["something"] = &f1; fnMap["something else"] = &f2; // ... using the map: FuncMap::const_iterator it = fnMap.find(str); if (it != fnMap.end()) { // is there an entry for str? it->second(); // call the function } 

至于传递参数,到目前为止我给出的细节可能会去传递未分析的行剩余部分或字符串标记列表的功能,让他们处理,因为他们认为合适:

 void f1(const std::vector<std::string>& tokens) { /* ... */ } // ... typedef void (*FuncPtr)(const std::vector<std::string>&); typedef std::map<std::string, FuncPtr> FuncMap; // ... std::vector<std::string> tokens = /* ...? */; FuncMap::const_iterator it = fnMap.find(str); if (it != fnMap.end()) { it->second(tokens); } 

你也可以看看来自Boost.FunctionTypes( header , source file )的解释器例子,它与你的场景类似。

首先,Georg的地图版本比较长的级联比较优雅和可扩展。 然而,如果你关心的是性能,而你的级联是“缓慢的”,那么测量它的速度有多快。

对于您给出的示例字符串,我构建了一个函数的三个变体,它根据传递给它的字符串在数组中增加一个值。 第一个是基于你的代码,第二个是Georg的,第三个是下面的代码,和你的代码一样,但是使用常量字符串,而不是每次调用字符串时都要构造字符串。

 void foo (const std::string& str, int (&count)[6]) { static const std::string s0 = "something"; static const std::string s1 = "something else"; static const std::string s2 = "something more"; static const std::string s3 = "something again"; static const std::string s4 = "something different"; static const std::string s5 = "something really different"; if(str == s0) { ++count[0]; }else if(str == s1) { ++count[1]; }else if(str == s2) { ++count[2]; }else if(str == s3) { ++count[3]; }else if(str == s4) { ++count[4]; }else if(str == s5) { ++count[5]; } } 

使用VS 2008 Express的默认版本设置,这些出现为:

 operator== with constant strings (the code above) time 7.015 seconds 0.116917 microseconds per call std::map lookup (Georg's code) time 9.687 seconds 0.16145 microseconds per call operator== with literal strings (original code) time 10.437 seconds 0.17395 microseconds per call 

所以,除非你打电话的代码很多,那么你不会注意到你的原始版本174纳秒。 假设地图和if级联的行为如预期(O(N)和O(log 2 N)),那么地图在13个字符串处应该更快。 但是,如果它对你来说很重要,那么就要对其进行描述或基准测试。

我会尝试一个简单的数据结构,但也许C ++的大师和STL爱好者可以更好地思考。 我的想法是

 struct smap { string s; int i; } str_int_map[] = { { string("strng"), 1 }, /*...*/ }; 

接着

  j = 0; //default if no match found for(i=0; i < 2; i++) { if ( str_int_map[i].s == a ) { j = str_int_map[i].i; break; } } switch( j ) { case 1: cout << "oooo"; break; case 2: cout << "nnnn"; break; } 

如果它适合您的需要,您可以“映射”到一个函数地址并直接调用它,而不是“映射”到整数。 而不是循环匹配的方法,你可以使用一个真正的地图/字典,无论是从STL调用的字符串到数字,然后切换到上面的例子。

这应该是最有效的。 但是,也许switch-case语句会更优雅?