我有3个字符串s1,s2,s3。每个都包含两侧的垃圾文本,其中心有一个定义模式:text1+number1
。每个字符串number1
增加2。我想提取text1+number1
。
我已编写代码来查找number1
如何扩展LCS功能以获取text1?
#include <iostream>
const std::string longestCommonSubstring(int, std::string const& s1, std::string const& s2, std::string const& s3);
int main(void) {
std::string s1="hello 5", s2="bolo 7", s3="lo 9sdf";
std::cout << "Trying to get \"lo 5\", actual result: \"" << longestCommonSubstring(5, s1, s2, s3) << '\"';
}
const std::string longestCommonSubstring(int must_include, std::string const& s1, std::string const& s2, std::string const& s3) {
std::string longest;
for(size_t start=0, length=1; start + length <= s1.size();) {
std::string tmp = s1.substr(start, length);
if (std::string::npos != s2.find(tmp) && std::string::npos != s3.find(tmp)) {
tmp.swap(longest);
++length;
} else ++start;
}
return longest;
}
来自"hello 5"
,"bolo 7"
,"lo 9sdf"
我想"lo 5"
我已经能够编写一个简单的LCS函数(test-case)但是我在编写这个修改过的函数时遇到了麻烦。
答案 0 :(得分:1)
假设你正在寻找一个模式* n,* n + 2,* n + 4等等。你有以下字符串: s1 =“hello 1,bye 2,ciao 1”,s2 =“hello 3,bye 4,ciao 2”,s3 =“hello 5,bye 6,ciao 5”。然后以下将做:
//find all pattern sequences
N1 = findAllPatterns(s1, number);
for i = 2 to n:
for item in Ni-1:
for match in findAllPatterns(si, nextPattern(item))
Ni.add([item, (match, indexOf(match))]);
//for all pattern sequences identify the max common substring
maxCommonLength = 0;
for sequence in Nn:
temp = findLCS(sequence);
if(length(temp[0]) > maxCommonLength):
maxCommonLength = length(temp[0]);
result = temp;
return result;
` 算法的第一部分将识别序列: [(1,6),(3,6),(5,6)],[(1,19),(3,6),(5,6)],[(2,12),(4, 12),(6,12)]
第二部分将确定: [“你好1”,“你好3”,“你好5”]作为与模式匹配的最长子串。
通过组合这两个部分并丢弃与模式匹配但不是最理想的早期序列,可以进一步优化算法,但我更倾向于将其分为两部分以便更清晰。
- 编辑固定代码块
答案 1 :(得分:0)
如果您已经知道number1
,并且您知道这些数字在相应的字符串中只显示一次,则以下内容应该有效:
我会调用您的字符串s[0]
,s[1]
等。设置longest = INT_MAX
。对于每个字符串s[i]
(i&gt; = 0),只需:
number1 + 2 * i
中s[i]
出现的位置。假设它发生在j
位置。最后,longest
将是所有字符串共有的最长子字符串的长度。
基本上我们只是从找到号码的位置向后扫描,寻找与s1
(我的s[0]
)中相应字符的不匹配,并跟踪最长的内容到目前为止匹配子字符串在longest
中 - 这只能保持不变或随着我们查看的每个新字符串而减少。
答案 2 :(得分:0)
您可以在s1中获取其输出并find,而不是尝试修改LCS算法的内部。从那里,您的号码将位于输出长度的偏移量加1。
答案 3 :(得分:0)
写了我自己的解决方案:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
typedef std::pair<std::pair<std::string, std::string>, std::pair<std::pair<std::string, std::string>, std::pair<std::string, std::string>>> pairStringTrio;
typedef std::pair<std::string,std::pair<std::string,std::string>> stringPairString;
stringPairString longestCommonSubstring(const pairStringTrio&);
std::string strFindReplace(const std::string&, const std::string&, const std::string&);
int main(void) {
std::string s1= "6 HUMAN ACTIONb", s2="8 HUMAN ACTIONd", s3="10 HUMAN ACTIONf";
pairStringTrio result = std::make_pair(std::make_pair(s1, "6"), std::make_pair(std::make_pair(s2, "8"), std::make_pair(s3, "10")));
stringPairString answer = longestCommonSubstring(result);
std::cout << '\"' << answer.first << "\"\t\"" << answer.second.first << "\"\t\"" << answer.second.second << '\"';
}
stringPairString longestCommonSubstring(const pairStringTrio &foo) {
std::string longest;
for(size_t start=0, length=foo.first.first.size()-1; start + length <= foo.first.first.size();) {
std::string s1_tmp = foo.first.first.substr(start, length);
std::string s2_tmp = strFindReplace(s1_tmp, foo.first.second, foo.second.first.second);
std::string s3_tmp = strFindReplace(s1_tmp, foo.first.second, foo.second.second.second);
if (std::string::npos != foo.second.first.first.find(s2_tmp) && std::string::npos != foo.second.second.first.find(s3_tmp)) {
s1_tmp.swap(longest);
++length;
} else ++start;
}
return std::make_pair(longest, std::make_pair(strFindReplace(longest, foo.first.second, foo.second.first.second), strFindReplace(longest, foo.first.second, foo.second.second.second)));
}
std::string strFindReplace(const std::string &original, const std::string& src, const std::string& dest) {
std::string answer=original;
for(std::size_t pos = 0; (pos = answer.find(src, pos)) != answer.npos;)
answer.replace(pos, src.size(), dest);
return answer;
}