Search code examples
c++algorithmparsingpattern-matchinglongest-substring

Longest common substring constrained by pattern


Problem:

I have 3 strings s1, s2, s3. Each contain garbage text on either side, with a defining pattern in its centre: text1+number1. number1 increases by 2 in each string. I want to extract text1+number1.

I have already written code to find number1

How would I extend an LCS function to get 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;
}

Example:

From "hello 5", "bolo 7", "lo 9sdf" I would like to get "lo 5"

Code:

I have been able to write a simple LCS function(test-case) but I am having trouble writing this modified one.


Solution

  • Wrote my own solution:

    #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;
    }