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

📅  最后修改于: 2021-04-29 12:02:31             🧑  作者: Mango

给定两个字符串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;
}


Java
// Java program to check if a string is
// substring of other.
class GFG {
 
    // Returns true if s1 is substring of s2
    static 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.charAt(i + j)
                    != s1.charAt(j))
                    break;
 
            if (j == M)
                return i;
        }
 
        return -1;
    }
 
    /* Driver code */
    public static void main(String args[])
    {
        String s1 = "for";
        String s2 = "geeksforgeeks";
 
        int res = isSubstring(s1, s2);
 
        if (res == -1)
            System.out.println("Not present");
        else
            System.out.println(
                "Present at index "
                + res);
    }
}
 
// This code is contributed by JaideepPyne.


Python3
# Python3 program to check if
# a string is substring of other.
 
# Returns true if s1 is substring of s2
def isSubstring(s1, s2):
    M = len(s1)
    N = len(s2)
 
    # A loop to slide pat[] one by one
    for i in range(N - M + 1):
 
        # For current index i,
        # check for pattern match
        for j in range(M):
            if (s2[i + j] != s1[j]):
                break
             
        if j + 1 == M :
            return i
 
    return -1
 
# Driver Code
if __name__ == "__main__":
    s1 = "for"
    s2 = "geeksforgeeks"
    res = isSubstring(s1, s2)
    if res == -1 :
        print("Not present")
    else:
        print("Present at index " + str(res))
 
# This code is contributed by ChitraNayal


C#
// C# program to check if a string is
// substring of other.
using System;
class GFG {
 
    // Returns true if s1 is substring of s2
    static 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 */
    public static void Main()
    {
        string s1 = "for";
        string s2 = "geeksforgeeks";
 
        int res = isSubstring(s1, s2);
 
        if (res == -1)
            Console.Write("Not present");
        else
            Console.Write("Present at index "
                          + res);
    }
}
 
// This code is contributed by nitin mittal.


PHP


Java
// Java program for the above approach
class GFG {
 
    public int strstr(String str, String target)
    {
 
        int t = 0;
        int len = str.length();
        int i;
 
        // Iterate from 0 to len - 1
        for (i = 0; i < len; i++) {
            if (t == target.length())
                break;
            if (str.charAt(i) == target.charAt(t))
                t++;
            else
                t = 0;
        }
 
        return t < target.length() ? -1 : i - t;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        GFG pos = new GFG();
        System.out.println(
            pos.strstr("GeeksForGeeks", "Fr"));
        System.out.println(
            pos.strstr("GeeksForGeeks", "For"));
    }
}


Python3
# Python program for the above approach
def strstr(Str, target):
     
    t = 0
    Len = len(Str)
    i = 0
     
    # Iterate from 0 to Len - 1
    for i in range(Len):
        if (t == len(target)):
            break
        if (Str[i] == target[t]):
            t += 1
        else:
            t = 0
             
    if (t < len(target)):
        return -1
    else:
        return (i - t)
 
# Driver code
print(strstr("GeeksForGeeks", "Fr"))
print(strstr("GeeksForGeeks", "For"))
 
# This code is contributed by avanitrachhadiya2155


输出
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的长度,如果为true,则中断并返回该值(字符串s1的指针–字符串s2的指针)

Java

// Java program for the above approach
class GFG {
 
    public int strstr(String str, String target)
    {
 
        int t = 0;
        int len = str.length();
        int i;
 
        // Iterate from 0 to len - 1
        for (i = 0; i < len; i++) {
            if (t == target.length())
                break;
            if (str.charAt(i) == target.charAt(t))
                t++;
            else
                t = 0;
        }
 
        return t < target.length() ? -1 : i - t;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        GFG pos = new GFG();
        System.out.println(
            pos.strstr("GeeksForGeeks", "Fr"));
        System.out.println(
            pos.strstr("GeeksForGeeks", "For"));
    }
}

Python3

# Python program for the above approach
def strstr(Str, target):
     
    t = 0
    Len = len(Str)
    i = 0
     
    # Iterate from 0 to Len - 1
    for i in range(Len):
        if (t == len(target)):
            break
        if (Str[i] == target[t]):
            t += 1
        else:
            t = 0
             
    if (t < len(target)):
        return -1
    else:
        return (i - t)
 
# Driver code
print(strstr("GeeksForGeeks", "Fr"))
print(strstr("GeeksForGeeks", "For"))
 
# This code is contributed by avanitrachhadiya2155
输出
-1
5

复杂度分析:

由于我们遍历第一个字符串1次,因此顺序为O(n),并且没有为空间复杂度分配额外的空间将为O(1)