假设我有一个字符串"abcdpqrs",
现在,由于这些字符是在一起的,"dcb"可以被计算为上述字符串的子字符串。
同样地,“pdq”是该字符串的一部分。但是“bcpq”不是。我希望你能理解我的需求。
有没有更有效的方法来做到这一点呢?
我所想到的只有借助哈希来实现这一点。但是即使在O(n)程序中需要在许多情况下进行回溯,它也要花费很长时间。任何帮助将不胜感激。
str
中搜索长度为k的字符串s
。因此,从str
中取出每个连续的k个字符,并检查这些字符中是否有任何一个出现在s
中。#include <iostream>
/* pos position where to extract probable string from str
* s string set with possible repetitions being searched in str
* str original string
*/
bool find_in_string( int pos, std::string s, std::string str)
{
std::string str_s = str.substr( pos, s.length());
int s_pos = 0;
while( !s.empty())
{
std::size_t found = str_s.find( s[0]);
if ( found!=std::string::npos)
{
s.erase( 0, 1);
str_s.erase( found, 1);
} else return 0;
}
return 1;
}
bool find_in_string( std::string s, std::string str)
{
bool found = false;
int pos = 0;
while( !found && pos < str.length() - s.length() + 1)
{
found = find_in_string( pos++, s, str);
}
return found;
}
使用方法:
int main() {
std::string s1 = "abcdpqrs";
std::string s2 = "adcbpqrs";
std::string searched = "dcb";
std::string searched2 = "pdq";
std::string searched3 = "bcpq";
std::cout << find_in_string( searched, s1);
std::cout << find_in_string( searched, s2);
std::cout << find_in_string( searched2, s1);
std::cout << find_in_string( searched3, s1);
return 0;
}
打印:1110
bool compare (string s1, string s2)
{
// sort both here
// return if they are equal when sorted;
}
对于这个例子,您需要使用大小为4的以下子字符串调用此函数(与“opde”长度相同):
“axcd” “xcdl” “cdle” “dlef”
bool exist = false;
for (/*every split that has the same size as the search */)
exist = exist || compare(currentsplit, search);
a(ded)em
。 - Ben Voigtbool compare(string s1, string s2)
{
int v1[SIZE_OF_ALFABECT];
int v2[SIZE_OF_ALFABECT];
int count = 0;
map<char, int> mymap;
// here is just pseudocode
foreach letter in s1:
if map doesnt contain this letter already:
mymap[letter] = count++;
// repeat the same foreach in s2
/* You can break and return false here if you try to add new char into map,
that means that the second string has a different character already... */
// count will now have the number of distinct chars that you have in both strs
// you will need to check only 'count' positions in the vectors
for(int i = 0; i < count; i++)
v1[i] = v2[i] = 0;
//another pseudocode
foreach letter in s1:
v1[mymap[leter]]++;
foreach letter in s1:
v2[mymap[leter]]++;
for(int i = 0; i < count; i++)
if(v1[i] != v2[i])
return false;
return true;
}
这里有一个O(m)的最佳情况,O(m!)的最坏情况解决方案 - 其中m是您搜索字符串的长度:
使用后缀树,例如Ukkonnen Trie(有一些漂浮在周围,但我目前没有链接),并搜索子字符串的任何排列。请注意,任何查找仅需要每个要搜索的字符串字符的O(1),而不管n的大小。
然而,虽然n的大小无关紧要,但对于大m来说,这变得不切实际。
如果n足够小且愿意为索引大小牺牲查找性能,则后缀树可以存储包含原始字符串所有排列的字符串。
然后查找将始终为O(m)。
我建议在一般情况下选择接受的答案。但是,在这里,您有一个可以在小子字符串和大字符串上执行(更)好的建议。
boost::regex
。 - aruisdante