受模式约束的最长公共子字符串
Longest common substring constrained by pattern
问题:
我有3个字符串s1,s2,s3。每一个都包含两侧的垃圾文本,其中心有一个定义模式:text1+number1
。CCD_ 2在每个串中增加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函数(测试用例(,但我在编写这个修改后的函数时遇到了问题。
假设您正在寻找模式*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,2(,(3,6(,(5,6(],[(1,19(,(3,4(
第二部分将确定:["hello 1"、"hello 3"、"hello 5"]作为与模式匹配的最长子字符串。
该算法可以通过组合这两部分并丢弃与模式匹配但次优的早期序列来进一步优化,但为了更好地清晰起见,我更喜欢将其分为两部分。
--编辑固定代码块
如果您已经知道number1
,并且您知道这些数字在相应的字符串中只出现一次,那么以下方法应该有效:
我将把你的字符串称为s[0]
、s[1]
等。设置longest = INT_MAX
。对于每个字符串s[i]
(i>=0(,仅:
- 查找
number1 + 2 * i
在s[i]
中的位置。假设它发生在位置CCD_ 16 - 如果(i==0(j0=j;其他的
- 对于(k=1;k+lt;=j&&k<=最长的&s[i][j-k]=s[0][j0-k];++k({}
- 最长=k
最后,longest
将是所有字符串共有的最长子字符串的长度。
基本上,我们只是从找到数字的点向后扫描,寻找与s1
(我的s[0]
(中相应字符的不匹配,并跟踪number1
0中迄今为止最长匹配的子字符串是什么——这只能随着我们看到的每个新字符串而保持不变或减少
与其试图修改LCS算法的内部结构,不如获取其输出并在s1中找到它。从那里,您的数字将位于输出长度加1的偏移处。
编写了我自己的解决方案:
#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;
}
- 小字符串优化(调试与发布模式)
- C++ 中用于搜索字符串模式的正则表达式
- C 搜索模式在2个字符串中,而无需串联
- 如何提取由特定模式分开的JSON对象字符串
- AES/CFB密码模式从字符串失败中解密
- 正则表达式:从模式字符串 1.string2'string3 中提取字符串,其中字符串 1 可以包含 '." 字符
- 在匹配另一个模式的字符串中找到最短子字符串的开始和结尾索引
- 如何将正则表达式模式存储为正则表达式对象或字符串
- 用于多个级联字符串的同步模式匹配算法
- 如何在C++中有效地提取字符串模式
- 使用后缀数组和 LCP(-LR) 实现字符串模式匹配
- 基于匹配字符串模式来简化函数
- 与缓冲区数据匹配的 C++ 字符串模式
- 在给定字符串中查找字符串模式的重复
- 如何使用标准库(包括boost)实现简单的字符串模式匹配
- QRegExp找不到预期的字符串模式
- 字符串模式匹配和插入
- 寻找字符串模式的更好解决方案
- 如果字符位于引号之间,则不匹配(AKA具有编程字符串模式)
- 在没有正则表达式的情况下拾取特定的字符串模式