如何检查两个字符串是否有共同的部分?

时间:2019-02-04 10:32:42

标签: c++ string

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

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

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

P.S。我没有检查多个字符。例如-“苹果”和“蝙蝠侠”有一个共同点,但我对子字符串(至少两个共同的连续字符)感兴趣。

3 个答案:

答案 0 :(得分:0)

这可能不是最有效的代码,但是您可以大致了解它在batman和catman情况下如何工作:

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

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

if max>2一样,然后打印该数组,例如,不打印该数组。

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

答案 1 :(得分:0)

此函数将为您提供两个字符串中最长的公共子字符串:(( not 可能不是您执行此操作的最快方法)

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

输出:

     
    

atman

  

答案 2 :(得分:0)

一种愚蠢的算法-对于从最大窗口(等于字符串长度的最大值)到最小窗口大小(等于问题中所述的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;
}