我查看了网站,但没有直接回答以下问题。
在C ++中查找字符串中第n个子字符串的最有效方法是什么?
此处的示例显示了如何查找第二个匹配项: http://www.cplusplus.com/reference/string/string/find/
但是首先找到第一个匹配似乎效率很低,然后使用该位置搜索以下匹配等以找到第n个匹配。如果你想要第25场比赛的位置,有更快的方法吗?
编辑:在更大的上下文中,我逐行读取文件,对项目的每个响应都有一个分数,有些缺失,获得NA
字符串。所有项目都以空格分隔。
我希望可以选择排除某些项目,因此只需搜索项目35至80,90至120和150-200。 所以我现在所做的就是:
string blockedLine(string line)
{
int b_start[] = {35, 90, 150};
int b_end[] = {80, 120, 200};
std::vector<int> space_matches = KMP(line, " ");
string cuttedLine = "";
for (int i = 0; i < 3; i++)
{
cuttedLine.append(line.substr(space_matches[b_start[i]],
space_matches[b_end[i]]));
}
return(cuttedLine);
}
其中KMP
是其中一条评论中提到的函数,它会获取空间出现的位置,并将它们存储在space_matches
中。
然后我计算此附加字符串中NA
的出现次数。
问题在于,如果没有这个附加功能,只需读取整条线就需要大约20万行的1秒钟。当我使用这个附加方法来获取子串时,它需要14秒,这太慢了。
有什么可以改善这一点?
答案 0 :(得分:2)
/// Returns the position of the 'Nth' occurrence of 'find' within 'str'.
/// Note that 1==find_Nth( "aaa", 2, "aa" ) [2nd "aa"]
/// - http://stackoverflow.com/questions/17023302/
size_t find_Nth(
const std::string & str , // where to work
unsigned N , // N'th ocurrence
const std::string & find // what to 'find'
) {
if ( 0==N ) { return std::string::npos; }
size_t pos,from=0;
unsigned i=0;
while ( i<N ) {
pos=str.find(find,from);
if ( std::string::npos == pos ) { break; }
from = pos + 1; // from = pos + find.size();
++i;
}
return pos;
/**
It would be more efficient to use a variation of KMP to
benefit from the failure function.
- Algorithm inspired by James Kanze.
- http://stackoverflow.com/questions/20406744/
*/
}
int main() {
{
// 0123456789.123456789.123
assert( 3 == find_Nth( "My gorila ate the banana", 1 , "gorila") );
assert( 18 == find_Nth( "My gorila ate the banana", 1 , "banana") );
// 0123456789.123456789.123
assert( 3 == find_Nth( "My banana ate the banana", 1 , "banana") );
assert( 18 == find_Nth( "My banana ate the banana", 2 , "banana") );
assert( std::string::npos == find_Nth( "My banana ate the banana", 3 , "banana") );
assert( std::string::npos == find_Nth( "My banana ate the banana", 3 , "gorila") );
}
assert( 1==find_Nth( "aaa", 2, "aa" ) );
assert( 0==find_Nth( "aaa", 1, "aa" ) );
{
std::string str;
// 01234567
str = "aaaaaaaa"; assert( 8==str.size() );
assert( find_Nth( str, 0 , "aa") == std::string::npos );
assert( find_Nth( str, 1 , "aa") == 0 );
assert( find_Nth( str, 2 , "aa") == 1 );
assert( find_Nth( str, 3 , "aa") == 2 );
assert( find_Nth( str, 4 , "aa") == 3 );
assert( find_Nth( str, 5 , "aa") == 4 );
assert( find_Nth( str, 6 , "aa") == 5 );
assert( find_Nth( str, 7 , "aa") == 6 );
assert( find_Nth( str, 8 , "aa") == std::string::npos );
assert( find_Nth( str, 9 , "aa") == std::string::npos );
}
}