📌  相关文章
📜  C++ 程序检查一个字符串是否是另一个字符串的子字符串

📅  最后修改于: 2022-05-13 01:56:07.829000             🧑  作者: Mango

C++ 程序检查一个字符串是否是另一个字符串的子字符串

给定两个字符串s1 和 s2,判断 s1 是否是 s2 的子字符串。如果是,则返回第一次出现的索引,否则返回 -1。

例子 :

Input: s1 = "for", s2 = "geeksforgeeks"
Output: 5
Explanation:
String "for" is present as a substring
of s2.

Input: s1 = "practice", s2 = "geeksforgeeks"
Output: -1.
Explanation:
There is no occurrence of "practice" in
"geeksforgeeks"

简单方法:想法是从头到尾运行一个循环,并为给定字符串中的每个索引检查是否可以从该索引形成子字符串。这可以通过运行一个遍历给定字符串的嵌套循环来完成,并在该循环中运行另一个循环检查每个索引中的子字符串。
例如,假设有一个长度为 N 的字符串和一个长度为 M 的子字符串。然后运行一个嵌套循环,其中外循环从 0 到 (NM),内循环从 0 到 M。对于非常索引检查是否内循环遍历的子串是否是给定的子串。

C++
// C++ program to check if a string is
// substring of other.
#include 
using namespace std;
  
// Returns true if s1 is substring 
// of s2
int isSubstring(string s1, string s2)
{
    int M = s1.length();
    int N = s2.length();
  
    /* A loop to slide pat[] one 
       by one */
    for (int i = 0; i <= N - M; i++) 
    {
        int j;
  
        /* For current index i, check for
           pattern match */
        for (j = 0; j < M; j++)
            if (s2[i + j] != s1[j])
                break;
  
        if (j == M)
            return i;
    }
    return -1;
}
  
// Driver code 
int main()
{
    string s1 = "for";
    string s2 = "geeksforgeeks";
    int res = isSubstring(s1, s2);
    if (res == -1)
        cout << "Not present";
    else
        cout << "Present at index " << 
                 res;
    return 0;
}


C++
// C++ program to implement 
// the above approach
#include 
using namespace std;
  
int Substr(string s2, string s1)
{
    // pointing s2
    int counter = 0; 
    int i = 0;
    for(; i < s1.length(); i++)
    {
        if(counter==s2.length())
            break;
        if(s2[counter]==s1[i])
        {
            counter++;
        }
      else
        {
            // Special case where character preceding 
            // the i'th character is duplicate
            if(counter > 0)
            {
                i -= counter;
            }
            counter = 0;
        }
    }
    return (counter < s2.length() ? 
            -1 : i - counter);
}
  
// Driver code
int main() 
{
    string s1 = 
    "geeksfffffoorrfoorforgeeks";
    cout << Substr("for", s1);
    return 0;
}
// This code is contributed by Manu Pathria


输出:

Present at index 5

复杂性分析:

  • 时间复杂度: O(m * n) 其中 m 和 n 分别是 s1 和 s2 的长度。
    使用嵌套循环,外循环从 0 到 NM,内循环从 0 到 M,因此复杂度为 O(m*n)。
  • 空间复杂度: O(1)。
    因为不需要额外的空间。

一个有效的解决方案是使用 O(n) 搜索算法,如KMP 算法Z 算法等。
语言实现:

  • Java子字符串
  • C++ 中的子串
  • Python查找

另一个有效的解决方案:

  • 一个有效的解决方案将只需要一次遍历,即在较长的字符串s1 上的 O(n)。在这里,我们将开始遍历字符串s1 并从第 0 个索引处维护字符串s2 的指针。
  • 对于每次迭代,我们比较 s1 中的当前字符并用 s2 处的指针检查它。
  • 如果它们匹配,我们将 s2 上的指针加 1。对于每个不匹配,我们将指针设置回 0。
  • 还要检查 s2 指针值何时等于字符串s2 的长度,如果为真,我们将中断并返回值(字符串s1 的指针 -字符串s2 的指针)
  • 适用于包含重复字符的字符串。

C++

// C++ program to implement 
// the above approach
#include 
using namespace std;
  
int Substr(string s2, string s1)
{
    // pointing s2
    int counter = 0; 
    int i = 0;
    for(; i < s1.length(); i++)
    {
        if(counter==s2.length())
            break;
        if(s2[counter]==s1[i])
        {
            counter++;
        }
      else
        {
            // Special case where character preceding 
            // the i'th character is duplicate
            if(counter > 0)
            {
                i -= counter;
            }
            counter = 0;
        }
    }
    return (counter < s2.length() ? 
            -1 : i - counter);
}
  
// Driver code
int main() 
{
    string s1 = 
    "geeksfffffoorrfoorforgeeks";
    cout << Substr("for", s1);
    return 0;
}
// This code is contributed by Manu Pathria

输出:

18

复杂性分析:

上面代码的复杂度在最坏的情况下仍然是 O(n*m),空间复杂度是 O(1)。

请参阅有关检查字符串是否为另一个字符串的完整文章以获取更多详细信息!