给定两个字符串,求第二个字符串在第一个字符串出现的次数,无论是连续的还是不连续的。
例子:
Input:
string a = "GeeksforGeeks"
string b = "Gks"
Output: 4
Explanation:
The four strings are - (Check characters marked in bold)
GeeksforGeeks
GeeksforGeeks
GeeksforGeeks
GeeksforGeeks
如果我们仔细分析给定的问题,我们可以看到它可以很容易地划分为子问题。这个想法是从左侧或右侧一个一个地处理两个字符串的所有字符。让我们从右角开始遍历,每对被遍历的字符都有两种可能性。
m: Length of str1 (first string)
n: Length of str2 (second string)
If last characters of two strings are same,
1. We consider last characters and get count for remaining
strings. So we recur for lengths m-1 and n-1.
2. We can ignore last character of first string and
recurse for lengths m-1 and n.
else
If last characters are not same,
We ignore last character of first string and
recurse for lengths m-1 and n.
以下是上述朴素递归解决方案的实现 –
C++
// A Naive recursive C++ program to find the number of
// times the second string occurs in the first string,
// whether continuous or discontinuous
#include
using namespace std;
// Recursive function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
int count(string a, string b, int m, int n)
{
// If both first and second string is empty,
// or if second string is empty, return 1
if ((m == 0 && n == 0) || n == 0)
return 1;
// If only first string is empty and second
// string is not empty, return 0
if (m == 0)
return 0;
// If last characters are same
// Recur for remaining strings by
// 1. considering last characters of both strings
// 2. ignoring last character of first string
if (a[m - 1] == b[n - 1])
return count(a, b, m - 1, n - 1) +
count(a, b, m - 1, n);
else
// If last characters are different, ignore
// last char of first string and recur for
// remaining string
return count(a, b, m - 1, n);
}
// Driver code
int main()
{
string a = "GeeksforGeeks";
string b = "Gks";
cout << count(a, b, a.size(), b.size()) << endl;
return 0;
}
Java
// A Naive recursive java program to find the number of
// times the second string occurs in the first string,
// whether continuous or discontinuous
import java.io.*;
class GFG
{
// Recursive function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
static int count(String a, String b, int m, int n)
{
// If both first and second string is empty,
// or if second string is empty, return 1
if ((m == 0 && n == 0) || n == 0)
return 1;
// If only first string is empty and
// second string is not empty, return 0
if (m == 0)
return 0;
// If last characters are same
// Recur for remaining strings by
// 1. considering last characters of
// both strings
// 2. ignoring last character of
// first string
if (a.charAt(m - 1) == b.charAt(n - 1))
return count(a, b, m - 1, n - 1) +
count(a, b, m - 1, n);
else
// If last characters are different,
// ignore last char of first string
// and recur for remaining string
return count(a, b, m - 1, n);
}
// Driver code
public static void main (String[] args)
{
String a = "GeeksforGeeks";
String b = "Gks";
System.out.println( count(a, b, a.length(), b.length())) ;
}
}
// This code is contributed by vt_m
Python 3
# A Naive recursive Python program
# to find the number of times the
# second string occurs in the first
# string, whether continuous or
# discontinuous
# Recursive function to find the
# number of times the second string
# occurs in the first string,
# whether continuous or discontinuous
def count(a, b, m, n):
# If both first and second string
# is empty, or if second string
# is empty, return 1
if ((m == 0 and n == 0) or n == 0):
return 1
# If only first string is empty
# and second string is not empty,
# return 0
if (m == 0):
return 0
# If last characters are same
# Recur for remaining strings by
# 1. considering last characters
# of both strings
# 2. ignoring last character
# of first string
if (a[m - 1] == b[n - 1]):
return (count(a, b, m - 1, n - 1) +
count(a, b, m - 1, n))
else:
# If last characters are different,
# ignore last char of first string
# and recur for remaining string
return count(a, b, m - 1, n)
# Driver code
a = "GeeksforGeeks"
b = "Gks"
print(count(a, b, len(a),len(b)))
# This code is contributed by ash264
C#
// A Naive recursive C# program to find the number of
// times the second string occurs in the first string,
// whether continuous or discontinuous
using System;
class GFG
{
// Recursive function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
static int count(string a, string b, int m, int n)
{
// If both first and second string is empty,
// or if second string is empty, return 1
if ((m == 0 && n == 0) || n == 0)
return 1;
// If only first string is empty and
// second string is not empty, return 0
if (m == 0)
return 0;
// If last characters are same
// Recur for remaining strings by
// 1. considering last characters of
// both strings
// 2. ignoring last character of
// first string
if (a[m - 1] == b[n - 1])
return count(a, b, m - 1, n - 1) +
count(a, b, m - 1, n);
else
// If last characters are different,
// ignore last char of first string
// and recur for remaining string
return count(a, b, m - 1, n);
}
// Driver code
public static void Main ()
{
string a = "GeeksforGeeks";
string b = "Gks";
Console.Write( count(a, b, a.Length, b.Length) );
}
}
// This code is contributed by nitin mittal
PHP
Javascript
C++
// A Dynamic Programming based C++ program to find the
// number of times the second string occurs in the first
// string, whether continuous or discontinuous
#include
using namespace std;
// Iterative DP function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
int count(string a, string b)
{
int m = a.length();
int n = b.length();
// Create a table to store results of sub-problems
int lookup[m + 1][n + 1] = { { 0 } };
// If first string is empty
for (int i = 0; i <= n; ++i)
lookup[0][i] = 0;
// If second string is empty
for (int i = 0; i <= m; ++i)
lookup[i][0] = 1;
// Fill lookup[][] in bottom up manner
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
// If last characters are same, we have two
// options -
// 1. consider last characters of both strings
// in solution
// 2. ignore last character of first string
if (a[i - 1] == b[j - 1])
lookup[i][j] = lookup[i - 1][j - 1] +
lookup[i - 1][j];
else
// If last character are different, ignore
// last character of first string
lookup[i][j] = lookup[i - 1][j];
}
}
return lookup[m][n];
}
// Driver code
int main()
{
string a = "GeeksforGeeks";
string b = "Gks";
cout << count(a, b);
return 0;
}
Java
// A Dynamic Programming based
// Java program to find the
// number of times the second
// string occurs in the first
// string, whether continuous
// or discontinuous
import java.io.*;
class GFG
{
// Iterative DP function to
// find the number of times
// the second string occurs
// in the first string, whether
// continuous or discontinuous
static int count(String a, String b)
{
int m = a.length();
int n = b.length();
// Create a table to store
// results of sub-problems
int lookup[][] = new int[m + 1][n + 1];
// If first string is empty
for (int i = 0; i <= n; ++i)
lookup[0][i] = 0;
// If second string is empty
for (int i = 0; i <= m; ++i)
lookup[i][0] = 1;
// Fill lookup[][] in
// bottom up manner
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
// If last characters are
// same, we have two options -
// 1. consider last characters
// of both strings in solution
// 2. ignore last character
// of first string
if (a.charAt(i - 1) == b.charAt(j - 1))
lookup[i][j] = lookup[i - 1][j - 1] +
lookup[i - 1][j];
else
// If last character are
// different, ignore last
// character of first string
lookup[i][j] = lookup[i - 1][j];
}
}
return lookup[m][n];
}
// Driver Code
public static void main (String[] args)
{
String a = "GeeksforGeeks";
String b = "Gks";
System.out.println(count(a, b));
}
}
// This code is contributed by anuj_67.
Python3
# A Dynamic Programming based Python
# program to find the number of times
# the second string occurs in the first
# string, whether continuous or discontinuous
# Iterative DP function to find the
# number of times the second string
# occurs in the first string,
# whether continuous or discontinuous
def count(a, b):
m = len(a)
n = len(b)
# Create a table to store results of sub-problems
lookup = [[0] * (n + 1) for i in range(m + 1)]
# If first string is empty
for i in range(n+1):
lookup[0][i] = 0
# If second string is empty
for i in range(m + 1):
lookup[i][0] = 1
# Fill lookup[][] in bottom up manner
for i in range(1, m + 1):
for j in range(1, n + 1):
# If last characters are same,
# we have two options -
# 1. consider last characters of
# both strings in solution
# 2. ignore last character of first string
if a[i - 1] == b[j - 1]:
lookup[i][j] = lookup[i - 1][j - 1] + lookup[i - 1][j]
else:
# If last character are different, ignore
# last character of first string
lookup[i][j] = lookup[i - 1][j]
return lookup[m][n]
# Driver code
if __name__ == '__main__':
a = "GeeksforGeeks"
b = "Gks"
print(count(a, b))
# this code is contributed by PranchalK
C#
// A Dynamic Programming based
// C# program to find the
// number of times the second
// string occurs in the first
// string, whether continuous
// or discontinuous
using System;
class GFG
{
// Iterative DP function to
// find the number of times
// the second string occurs
// in the first string, whether
// continuous or discontinuous
static int count(String a, String b)
{
int m = a.Length;
int n = b.Length;
// Create a table to store
// results of sub-problems
int[,] lookup = new int[m + 1, n + 1];
// If first string is empty
for (int i = 0; i <= n; ++i)
lookup[0, i] = 0;
// If second string is empty
for (int i = 0; i <= m; ++i)
lookup[i, 0] = 1;
// Fill lookup[][] in
// bottom up manner
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
// If last characters are
// same, we have two options -
// 1. consider last characters
// of both strings in solution
// 2. ignore last character
// of first string
if (a[i - 1] == b[j - 1])
lookup[i, j] = lookup[i - 1, j - 1] +
lookup[i - 1, j];
else
// If last character are
// different, ignore last
// character of first string
lookup[i, j] = lookup[i - 1, j];
}
}
return lookup[m, n];
}
// Driver Code
public static void Main()
{
String a = "GeeksforGeeks";
String b = "Gks";
Console.WriteLine(count(a, b));
}
}
// This code is contributed
// by Akanksha Rai(Abby_akku)
PHP
Javascript
输出:
4
上述解决方案的时间复杂度是指数级的。如果我们仔细分析,我们可以看到很多子问题被一次又一次地解决了。由于再次调用相同的子问题,因此该问题具有重叠子问题的属性。所以这个问题具有动态规划问题的两个属性(见this和this)。与其他典型的动态规划问题一样,可以通过构造一个存储子问题结果的临时数组来避免对相同子问题的重新计算。
下面是它使用动态规划的实现——
C++
// A Dynamic Programming based C++ program to find the
// number of times the second string occurs in the first
// string, whether continuous or discontinuous
#include
using namespace std;
// Iterative DP function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
int count(string a, string b)
{
int m = a.length();
int n = b.length();
// Create a table to store results of sub-problems
int lookup[m + 1][n + 1] = { { 0 } };
// If first string is empty
for (int i = 0; i <= n; ++i)
lookup[0][i] = 0;
// If second string is empty
for (int i = 0; i <= m; ++i)
lookup[i][0] = 1;
// Fill lookup[][] in bottom up manner
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
// If last characters are same, we have two
// options -
// 1. consider last characters of both strings
// in solution
// 2. ignore last character of first string
if (a[i - 1] == b[j - 1])
lookup[i][j] = lookup[i - 1][j - 1] +
lookup[i - 1][j];
else
// If last character are different, ignore
// last character of first string
lookup[i][j] = lookup[i - 1][j];
}
}
return lookup[m][n];
}
// Driver code
int main()
{
string a = "GeeksforGeeks";
string b = "Gks";
cout << count(a, b);
return 0;
}
Java
// A Dynamic Programming based
// Java program to find the
// number of times the second
// string occurs in the first
// string, whether continuous
// or discontinuous
import java.io.*;
class GFG
{
// Iterative DP function to
// find the number of times
// the second string occurs
// in the first string, whether
// continuous or discontinuous
static int count(String a, String b)
{
int m = a.length();
int n = b.length();
// Create a table to store
// results of sub-problems
int lookup[][] = new int[m + 1][n + 1];
// If first string is empty
for (int i = 0; i <= n; ++i)
lookup[0][i] = 0;
// If second string is empty
for (int i = 0; i <= m; ++i)
lookup[i][0] = 1;
// Fill lookup[][] in
// bottom up manner
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
// If last characters are
// same, we have two options -
// 1. consider last characters
// of both strings in solution
// 2. ignore last character
// of first string
if (a.charAt(i - 1) == b.charAt(j - 1))
lookup[i][j] = lookup[i - 1][j - 1] +
lookup[i - 1][j];
else
// If last character are
// different, ignore last
// character of first string
lookup[i][j] = lookup[i - 1][j];
}
}
return lookup[m][n];
}
// Driver Code
public static void main (String[] args)
{
String a = "GeeksforGeeks";
String b = "Gks";
System.out.println(count(a, b));
}
}
// This code is contributed by anuj_67.
蟒蛇3
# A Dynamic Programming based Python
# program to find the number of times
# the second string occurs in the first
# string, whether continuous or discontinuous
# Iterative DP function to find the
# number of times the second string
# occurs in the first string,
# whether continuous or discontinuous
def count(a, b):
m = len(a)
n = len(b)
# Create a table to store results of sub-problems
lookup = [[0] * (n + 1) for i in range(m + 1)]
# If first string is empty
for i in range(n+1):
lookup[0][i] = 0
# If second string is empty
for i in range(m + 1):
lookup[i][0] = 1
# Fill lookup[][] in bottom up manner
for i in range(1, m + 1):
for j in range(1, n + 1):
# If last characters are same,
# we have two options -
# 1. consider last characters of
# both strings in solution
# 2. ignore last character of first string
if a[i - 1] == b[j - 1]:
lookup[i][j] = lookup[i - 1][j - 1] + lookup[i - 1][j]
else:
# If last character are different, ignore
# last character of first string
lookup[i][j] = lookup[i - 1][j]
return lookup[m][n]
# Driver code
if __name__ == '__main__':
a = "GeeksforGeeks"
b = "Gks"
print(count(a, b))
# this code is contributed by PranchalK
C#
// A Dynamic Programming based
// C# program to find the
// number of times the second
// string occurs in the first
// string, whether continuous
// or discontinuous
using System;
class GFG
{
// Iterative DP function to
// find the number of times
// the second string occurs
// in the first string, whether
// continuous or discontinuous
static int count(String a, String b)
{
int m = a.Length;
int n = b.Length;
// Create a table to store
// results of sub-problems
int[,] lookup = new int[m + 1, n + 1];
// If first string is empty
for (int i = 0; i <= n; ++i)
lookup[0, i] = 0;
// If second string is empty
for (int i = 0; i <= m; ++i)
lookup[i, 0] = 1;
// Fill lookup[][] in
// bottom up manner
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
// If last characters are
// same, we have two options -
// 1. consider last characters
// of both strings in solution
// 2. ignore last character
// of first string
if (a[i - 1] == b[j - 1])
lookup[i, j] = lookup[i - 1, j - 1] +
lookup[i - 1, j];
else
// If last character are
// different, ignore last
// character of first string
lookup[i, j] = lookup[i - 1, j];
}
}
return lookup[m, n];
}
// Driver Code
public static void Main()
{
String a = "GeeksforGeeks";
String b = "Gks";
Console.WriteLine(count(a, b));
}
}
// This code is contributed
// by Akanksha Rai(Abby_akku)
PHP
Javascript
输出:
4
上述解决方案的时间复杂度为 O(MN)。
程序使用的辅助空间为O(MN)。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。