C++ 模式约束的最长公共子串 问题:
我有3个字符串s1,s2,s3。每一面都包含垃圾文本,中间有一个定义模式:C++ 模式约束的最长公共子串 问题:,c++,algorithm,parsing,pattern-matching,longest-substring,C++,Algorithm,Parsing,Pattern Matching,Longest Substring,我有3个字符串s1,s2,s3。每一面都包含垃圾文本,中间有一个定义模式:text1+number1数字1在每个字符串中增加2。我想提取text1+number1 我已经编写了查找number1 如何扩展LCS函数以获取文本1? #include <iostream> const std::string longestCommonSubstring(int, std::string const& s1, std::string const& s2, std::str
text1+number1
<代码>数字1在每个字符串中增加2。我想提取text1+number1
我已经编写了查找number1
如何扩展LCS函数以获取文本1?
#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;
}
#包括
常量std::string longestCommonSubstring(int,std::string const&s1,std::string const&s2,std::string const&s3);
内部主(空){
std::string s1=“hello 5”,s2=“bolo 7”,s3=“lo 9sdf”;
std::cout如果您已经知道number1
,并且您知道这些数字在其相应的字符串中只出现一次,那么下面的方法应该有效:
我将调用您的字符串s[0]
,s[1]
,等等。设置longest=INT\u MAX
。对于每个字符串s[I]
(I>=0),只需:
- 找到
number1+2*i
出现在s[i]
中的位置。假设它出现在位置j
- 如果(i==0)j0=j;else
- 对于(k=1;k如果您已经知道
number1
,并且您知道这些数字在其相应的字符串中只出现一次,那么以下操作应该有效:
我将调用您的字符串s[0]
,s[1]
,等等。设置longest=INT\u MAX
。对于每个字符串s[I]
(I>=0),只需:
- 找到
number1+2*i
出现在s[i]
中的位置。假设它出现在位置j
- 如果(i==0)j0=j;else
- 为了(k=1;k不尝试修改LCS算法的内部,您可以将其输出和它放在s1中。从那里,您的数字将位于输出长度加1的偏移量处。不尝试修改LCS算法的内部,您可以将其输出和它放在s1中。从那里,您的数字将是l位于输出长度加1的偏移量处。假设您正在寻找一个模式*n、*n+2、*n+4等,并且您有以下字符串:
s1=“你好1,再见2,再见1”,s2=“你好3,再见4,再见2”和s3=“你好5,再见6,再见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)]
第二部分将确定:
[“hello 1”、“hello 3”、“hello 5”]作为与模式匹配的最长子字符串
该算法可以通过组合这两部分并丢弃与模式匹配但不太理想的早期序列来进一步优化,但为了更清晰,我更倾向于将其分为两部分
--编辑固定代码块假设您正在查找一个模式*n、*n+2、*n+4等,并且您有以下字符串:
s1=“你好1,再见2,再见1”,s2=“你好3,再见4,再见2”和s3=“你好5,再见6,再见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)]
第二部分将确定:
[“hello 1”、“hello 3”、“hello 5”]作为与模式匹配的最长子字符串
该算法可以通过组合这两部分并丢弃与模式匹配但不太理想的早期序列来进一步优化,但为了更清晰,我更倾向于将其分为两部分
--编辑固定代码块编写了我自己的解决方案:
#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;
}
#包括
#包括
#包括
#包括
typedef std::成对字符串;
typedef std::对字符串对字符串;
stringPairString最长的公共子字符串(const pairStringTrio&);
std::string strFindReplace(const std::string&,const std::string&,const std::string&);
内部主(空){
std::string s1=“6人操作b”,s2=“8人操作d”,s3=“10人操作f”;
pairStringTrio结果=标准::制造对(标准::制造对(s1,“6”)、标准::制造对(标准::制造对(s2,“8”)、标准::制造对(s3,“10”);
stringPairString-answer=longestCommonSubstring(结果);
std::cout编写了我自己的解决方案:
#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;
}
#包括
#包括
#包括
#包括
typedef std::成对字符串;
typedef std::对字符串对字符串;
stringPairString最长的公共子字符串(const pairStringTrio&);
std::string strFindReplace(const std::string&,const std::string&,const std::string&);
内部主(空){
std::string s1=“6人操作b”,s2=“8人操作d”,s3=“10人操作f”;
pairStringTrio结果=标准::制造对(标准::制造对(s1,“6”)、标准::制造对(标准::制造对(s2,“8”)、标准::制造对(s3,“10”);
stringPairString-answer=longestCommonSubstring(结果);
std::cout您到底遇到了什么问题?从明显的LCS算法开始,只需通过+2
和+4
修改相关字符即可。您已经识别了LCS。现在是否要提取下一个字符从每个字符串中,检查它们是否为数字,每次递增2?最简单的方法取决于数据。例如,如果3个字符串为“hello 5”、“hello 7”和“hello 9sdf”,则LCS将为“hel”,但您想要的是“lo”。这类数据可能吗?如果可能,您需要修改LCS以同时解析出数字部分,并对其进行验证。如果不可能,您可以保留LCS算法,在每个字符串中找到LCS,然后从中进行解析。您到底遇到了什么问题?从明显的LCS算法开始,只需通过+2
和+4
。您已经识别了LCS。现在是否要从每个字符串中提取下一个字符,检查它们是否为数字,并且每次递增2?最简单的方法取决于数据。例如,如果这3个字符串是“hello 5”、“hello 7”和“hello 9sdf”,LCS将是“Hell”,但你想要的是“lo”。这种数据可能吗