【问题标题】:How to check if two strings have any common part?如何检查两个字符串是否有任何共同部分?
【发布时间】:2019-02-04 10:32:41
【问题描述】:

如何在 c++ 中检查两个字符串是否有任何公共部分(子字符串)。

我想对字符串进行排序,然后在两个字符串上使用循环来检查它们是否有共同的部分。但我不确定。而且我还认为这不是该问题的最佳策略

考虑字符串 - 'batman' 和 'catman' 他们有一个共同的部分“atman”。

附:我不检查多个字符。例如 - 'apple' 和 'batman' 有一个共同点,但我对子字符串感兴趣(最少两个常见的连续字符)。

【问题讨论】:

标签: c++ string


【解决方案1】:

这可能不是最有效的代码,但您可以了解它在 batman 和 catman 案例中的工作原理:

注意:这确实解决了其他情况,例如“batmanuc”和“catmanic”,即“atman”。

它不是完美的也不是最有效的,但它可以帮助您了解一种方法以及如何管理数组的位置。从这里开始,以您自己的方式实现它并添加细节取决于您!

like if max>2then 打印数组,如果不是,则不要打印它,例如。

   #include <iostream>

    using namespace std;

    int main()
    {
        char arr1[10]="batmanuc";
        char arr2[10]="catmanic";
        char common[10];
        int cont=0;
        int max=0;
        for (int i=0;i<10;i++){
            if(arr1[i]==arr2[i]){
                if(cont==max){
                common[cont]=arr1[i];
                cont++;
                max++;
                }
            }
            else cont=0;

        }

        printf("%s",common);
        return 0;
}

【讨论】:

    【解决方案2】:

    一个愚蠢的算法 - 对于从最大窗口(等于字符串长度的最大值)到最小窗口大小(等于 2,问题中所述)的每个窗口大小,对于两个字符串中的每个位置,将每个位置与每个位置进行比较每个 window_size 在两个字符串中的位置。

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cassert>
    #include <cstdio>
    
    std::string find_common_part(std::string one, std::string two) {
        const auto onesize = one.size();
        const auto twosize = two.size();
        const auto onebegin = one.begin();
        const auto twobegin = two.begin();
        // min. two common consecutive characters
        for (std::size_t window_size = std::max(onesize, twosize);
                window_size >= 2;
                --window_size) {
            for (auto onepos = onebegin, 
                    oneposmax = onebegin + (onesize - window_size);
                    onepos <= oneposmax;
                    ++onepos) {
                for (auto twopos = twobegin, 
                        twoposmax = twobegin + (twosize - window_size);
                        twopos <= twoposmax; 
                        ++twopos) {
                    if (std::equal(onepos, onepos + window_size, twopos)) {
                        return std::string(onepos, onepos +  window_size);
                    }
                }
            }
        }
        return std::string();
    }
    
    int main()
    {
        std::cout << find_common_part("catman", "batman") << std::endl;
        assert(find_common_part("catman", "batman") == "atman");
        assert(find_common_part("batman", "manbat") == "man" || 
            find_common_part("batman", "manbat") == "bat");
        return 0;
    }
    

    【讨论】:

    • 谢谢,我也在想这样的算法。
    【解决方案3】:

    这个函数会给你两个字符串中最长的公共子字符串:(可能不是你会做的最快的方法)

    std::string GetLongestCommonSubstring(std::string const& a, std::string const& b) {
        std::vector<std::string> substrings;
        for (auto beg = a.begin(); beg != std::prev(a.end()); ++beg)
            for (auto end = beg; end != a.end(); ++end)
                if (b.find(std::string(beg, std::next(end))) != std::string::npos)
                    substrings.emplace_back(beg, std::next(end));
        return *std::max_element(substrings.begin(), substrings.end(), 
               [](auto& elem1, auto& elem2) { return elem1.length() < elem2.length(); });
    }
    

    示例:

    int main() {
        std::cout << GetLongestCommonSubstring("batman", "catman") << std::endl;
    }
    

    输出:

    阿特曼

    【讨论】:

    • 我实际上需要他们是否有共同的子序列的正确或错误的答案。不过谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-09-20
    • 2012-05-03
    • 1970-01-01
    • 2021-01-11
    • 2016-04-10
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    相关资源
    最近更新 更多