我需要从 C++ 中的一组文件名中计算最长的公共子字符串。
准确地说,我有一个 std::list 的 std::strings (或 QT 等价物,也可以)
char const *x[] = {"FirstFileWord.xls", "SecondFileBlue.xls", "ThirdFileWhite.xls", "ForthFileGreen.xls"};
std::list<std::string> files(x, x + sizeof(x) / sizeof(*x));
我需要计算所有字符串的 n 个不同的最长公共子字符串,在这种情况下,例如对于 n=2
"File" and ".xls"
如果我能计算出最长的公共子序列,我可以把它剪掉并再次运行算法以获得第二长的,所以基本上这归结为:
是否有(参考?)实现来计算 std::strings 的 std::list 的 LCS?
这不是一个好的答案,而是我拥有的一个肮脏的解决方案 - 对 QUrls 的 QList 进行暴力破解,其中仅获取最后一个“/”之后的部分。我很想用“正确的”代码替换它。
(我发现了http://www.icir.org/christian/libstree/ - 这会很有帮助,但我无法在我的机器上编译它。也许有人用过这个?)
QString SubstringMatching::getMatchPattern(QList<QUrl> urls)
{
QString a;
int foundPosition = -1;
int foundLength = -1;
for (int i=urls.first().toString().lastIndexOf("/")+1; i<urls.first().toString().length(); i++)
{
bool hit=true;
int xj;
for (int j=0; j<urls.first().toString().length()-i+1; j++ ) // try to match from position i up to the end of the string :: test character at pos. (i+j)
{
if (!hit) break;
QString firstString = urls.first().toString().right( urls.first().toString().length()-i ).left( j ); // this needs to match all k strings
//qDebug() << "SEARCH " << firstString;
for (int k=1; k<urls.length(); k++) // test all other strings, k = test string number
{
if (!hit) break;
//qDebug() << " IN " << urls.at(k).toString().right(urls.at(k).toString().length() - urls.at(k).toString().lastIndexOf("/")+1);
//qDebug() << " RES " << urls.at(k).toString().indexOf(firstString, urls.at(k).toString().lastIndexOf("/")+1);
if (urls.at(k).toString().indexOf(firstString, urls.at(k).toString().lastIndexOf("/")+1)<0) {
xj = j;
//qDebug() << "HIT LENGTH " << xj-1 << " : " << firstString;
hit = false;
}
}
}
if (hit) xj = urls.first().toString().length()-i+1; // hit up to the end of the string
if ((xj-2)>foundLength) // have longer match than existing, j=1 is match length
{
foundPosition = i; // at the current position
foundLength = xj-1;
//qDebug() << "Found at " << i << " length " << foundLength;
}
}
a = urls.first().toString().right( urls.first().toString().length()-foundPosition ).left( foundLength );
//qDebug() << a;
return a;
}