给定两个长度分别为N和M 的字符串S和T ,任务是计算S中包含字符串T作为子字符串的子字符串的数量。
例子:
Input: S = “dabc”, T = “ab”
Output: 4
Explanation:
Substrings of S containing T as a substring are:
- S[0, 2] = “dab”
- S[1, 2] = “ab”
- S[1, 3] = “abc”
- S[0, 3] = “dabc”
Input: S = “hshshshs” T = “hs”
Output: 25
朴素的方法:解决问题的最简单方法,请参考本文的前一篇文章。
时间复杂度: O(N 2 )
辅助空间: O(N 2 )
高效方法:为了优化上述方法,其思想是找出S 中所有出现的T 。每当在S中找到T 时,添加包含此T出现的所有子字符串,不包括在先前出现时已计算的子字符串。请按照以下步骤解决问题:
- 初始化一个变量,比如answer ,以存储子字符串的数量。
- 初始化一个变量,比如last ,以存储S 中最后一次出现T的起始索引。
- 使用变量迭代范围[0, N – M] ,比如i 。
- 检查子串S[i, i + M]是否等于T。如果发现为真,则加上(i + 1 – last) * (N – (i + M – 1))来回答并更新last为(i + 1)。
- 否则,继续下一次迭代。
- 完成上述步骤后,打印答案的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count the substrings of
// string containing another given
// string as a substring
void findOccurrences(string S, string T)
{
// Store length of string S
int n1 = S.size();
// Store length of string T
int n2 = T.size();
// Store the required count of
// substrings
int ans = 0;
// Store the starting index of
// last occurence of T in S
int last = 0;
// Iterate in range [0, n1-n2]
for (int i = 0; i <= n1 - n2; i++) {
// Check if substring from i
// to i + n2 is equal to T
bool chk = true;
// Check if substring from i
// to i + n2 is equal to T
for (int j = 0; j < n2; j++) {
// Mark chk as false and
// break the loop
if (T[j] != S[i + j]) {
chk = false;
break;
}
}
// If chk is true
if (chk) {
// Add (i + 1 - last) *
// (n1 - (i + n2 - 1))
// to answer
ans += (i + 1 - last)
* (n1 - (i + n2 - 1));
// Update the last to i + 1
last = i + 1;
}
}
// Print the answer
cout << ans;
}
// Driver code
int main()
{
string S = "dabc", T = "ab";
// Function Call
findOccurrences(S, T);
}
Java
// Java program for the above approach
class GFG{
// Function to count the substrings of
// string containing another given
// string as a substring
static void findOccurrences(String S, String T)
{
// Store length of string S
int n1 = S.length();
// Store length of string T
int n2 = T.length();
// Store the required count of
// substrings
int ans = 0;
// Store the starting index of
// last occurence of T in S
int last = 0;
// Iterate in range [0, n1-n2]
for (int i = 0; i <= n1 - n2; i++)
{
// Check if substring from i
// to i + n2 is equal to T
boolean chk = true;
// Check if substring from i
// to i + n2 is equal to T
for (int j = 0; j < n2; j++)
{
// Mark chk as false and
// break the loop
if (T.charAt(j) != S.charAt(i + j))
{
chk = false;
break;
}
}
// If chk is true
if (chk)
{
// Add (i + 1 - last) *
// (n1 - (i + n2 - 1))
// to answer
ans += (i + 1 - last)
* (n1 - (i + n2 - 1));
// Update the last to i + 1
last = i + 1;
}
}
// Print the answer
System.out.println(ans);
}
// Driver code
public static void main (String[] args)
{
String S = "dabc", T = "ab";
// Function Call
findOccurrences(S, T);
}
}
// This code is contributed by AnkThon
Python3
# Python3 program for the above approach
# Function to count the substrings of
# containing another given
# as a sub
def findOccurrences(S, T):
# Store length of S
n1 = len(S)
# Store length of T
n2 = len(T)
# Store the required count of
# substrings
ans = 0
# Store the starting index of
# last occurence of T in S
last = 0
# Iterate in range [0, n1-n2]
for i in range(n1 - n2 + 1):
# Check if subfrom i
# to i + n2 is equal to T
chk = True
# Check if subfrom i
# to i + n2 is equal to T
for j in range(n2):
# Mark chk as false and
# break the loop
if (T[j] != S[i + j]):
chk = False
break
# If chk is true
if (chk):
# Add (i + 1 - last) *
# (n1 - (i + n2 - 1))
# to answer
ans += (i + 1 - last) * (n1 - (i + n2 - 1))
# Update the last to i + 1
last = i + 1
# Prthe answer
print(ans)
# Driver code
if __name__ == '__main__':
S,T = "dabc","ab"
# Function Call
findOccurrences(S, T)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG
{
// Function to count the substrings of
// string containing another given
// string as a substring
static void findOccurrences(String S, String T)
{
// Store length of string S
int n1 = S.Length;
// Store length of string T
int n2 = T.Length;
// Store the required count of
// substrings
int ans = 0;
// Store the starting index of
// last occurence of T in S
int last = 0;
// Iterate in range [0, n1-n2]
for (int i = 0; i <= n1 - n2; i++)
{
// Check if substring from i
// to i + n2 is equal to T
bool chk = true;
// Check if substring from i
// to i + n2 is equal to T
for (int j = 0; j < n2; j++)
{
// Mark chk as false and
// break the loop
if (T[j] != S[i + j])
{
chk = false;
break;
}
}
// If chk is true
if (chk)
{
// Add (i + 1 - last) *
// (n1 - (i + n2 - 1))
// to answer
ans += (i + 1 - last)
* (n1 - (i + n2 - 1));
// Update the last to i + 1
last = i + 1;
}
}
// Print the answer
Console.WriteLine(ans);
}
// Driver code
public static void Main(String[] args)
{
String S = "dabc", T = "ab";
// Function Call
findOccurrences(S, T);
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
4
时间复杂度: O(N*M)
辅助空间: O(1)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live