计算第一个字符串中的子序列,这些子字符串的字谜
给定两个长度分别为n1和n2的字符串str1和str2 。问题是计算str1的所有子序列,它们是str2的字谜。
例子:
Input : str1 = "abacd", str2 = "abc"
Output : 2
Index of characters in the 2 subsequences are:
{0, 1, 3} = {a, b, c} = abc and
{1, 2, 3} = {b, a, c} = bac
The above two subsequences of str1
are anagrams of str2.
Input : str1 = "geeksforgeeks", str2 = "geeks"
Output : 48
方法:创建两个数组freq1[]和freq2[] ,每个大小为'26',实现为哈希表,分别存储str1和str2每个字符的频率。令n1和n2分别为str1和str2的长度。现在实现以下算法:
countSubsequences(str1, str2)
for i = 0 to n1-1
freq1[str1[i] - 'a']++
for i = 0 n2-1
freq2[str2[i] - 'a']++
Initialize count = 1
for i = 0 to 25
if freq2[i] != 0 then
if freq2[i] <= freq1[i] then
count = count * binomialCoeff(freq1[i], freq2[i])
else
return 0
return count
让 freq1[i] 表示为n , freq2[i] 表示为r 。现在,上面算法中提到的binomialCoeff(n, r)只不过是二项式系数n C r 。参考这篇文章的实现。
解释:
让某个字符的频率在'str2'中说ch是'x',在'str1'中是'y'。如果 y < x,则不存在“str1”的子序列,它可能是“str2”的字谜。否则, y C x给出所选ch的出现次数,这将有助于所需子序列的总数。
C++
// C++ implementation to
// count subsequences in
// first string which are
// anagrams of the second
// string
#include
using namespace std;
#define SIZE 26
// Returns value of Binomial
// Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
int res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for (int i = 0; i < k; ++i) {
res *= (n - i);
res /= (i + 1);
}
return res;
}
// function to count subsequences
// in first string which are
// anagrams of the second string
int countSubsequences(string str1, string str2)
{
// hash tables to store frequencies
// of each character
int freq1[SIZE], freq2[SIZE];
int n1 = str1.size();
int n2 = str2.size();
// Initialize
memset(freq1, 0, sizeof(freq1));
memset(freq2, 0, sizeof(freq2));
// store frequency of each
// character of 'str1'
for (int i = 0; i < n1; i++)
freq1[str1[i] - 'a']++;
// store frequency of each
// character of 'str2'
for (int i = 0; i < n2; i++)
freq2[str2[i] - 'a']++;
// to store the total count
// of subsequences
int count = 1;
for (int i = 0; i < SIZE; i++)
// if character (i + 'a')
// exists in 'str2'
if (freq2[i] != 0) {
// if this character's frequency
// in 'str2' in less than or
// equal to its frequency in
// 'str1' then accumulate its
// contribution to the count
// of subsequences. If its
// frequency in 'str1' is 'n'
// and in 'str2' is 'r', then
// its contribution will be nCr,
// where C is the binomial
// coefficient.
if (freq2[i] <= freq1[i])
count = count * binomialCoeff(freq1[i], freq2[i]);
// else return 0 as there could
// be no subsequence which is an
// anagram of 'str2'
else
return 0;
}
// required count of subsequences
return count;
}
// Driver program to test above
int main()
{
string str1 = "abacd";
string str2 = "abc";
cout << "Count = "
<< countSubsequences(str1, str2);
return 0;
}
Java
// Java implementation to
// count subsequences in
// first string which are
// anagrams of the second
// string
import java.util.*;
import java.lang.*;
public class GfG{
public final static int SIZE = 26;
// Returns value of Binomial
// Coefficient C(n, k)
public static int binomialCoeff(int n,
int k)
{
int res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for (int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
// function to count subsequences
// in first string which are
// anagrams of the second string
public static int countSubsequences(String str,
String str3)
{
// hash tables to store frequencies
// of each character
int[] freq1 = new int [SIZE];
int[] freq2 = new int [SIZE];
char[] str1 = str.toCharArray();
char[] str2 = str3.toCharArray();
int n1 = str.length();
int n2 = str3.length();
// store frequency of each
// character of 'str1'
for (int i = 0; i < n1; i++)
freq1[str1[i] - 'a']++;
// store frequency of each
// character of 'str2'
for (int i = 0; i < n2; i++)
freq2[str2[i] - 'a']++;
// to store the total count
// of subsequences
int count = 1;
for (int i = 0; i < SIZE; i++)
// if character (i + 'a')
// exists in 'str2'
if (freq2[i] != 0) {
// if this character's frequency
// in 'str2' in less than or
// equal to its frequency in
// 'str1' then accumulate its
// contribution to the count
// of subsequences. If its
// frequency in 'str1' is 'n'
// and in 'str2' is 'r', then
// its contribution will be nCr,
// where C is the binomial
// coefficient.
if (freq2[i] <= freq1[i])
count = count * binomialCoeff(freq1[i], freq2[i]);
// else return 0 as there could
// be no subsequence which is an
// anagram of 'str2'
else
return 0;
}
// required count of subsequences
return count;
}
// Driver function
public static void main(String argc[])
{
String str1 = "abacd";
String str2 = "abc";
System.out.println("Count = " +
countSubsequences(str1, str2));
}
}
/* This code is contributed by Sagar Shukla */
Python
# Python3 implementation to count
# subsequences in first which are
# anagrams of the second
# import library
import numpy as np
SIZE = 26
# Returns value of Binomial
# Coefficient C(n, k)
def binomialCoeff(n, k):
res = 1
# Since C(n, k) = C(n, n-k)
if (k > n - k):
k = n - k
# Calculate value of
# [n * (n-1) *---* (n-k+1)] /
# [k * (k-1) *----* 1]
for i in range(0, k):
res = res * (n - i)
res = int(res / (i + 1))
return res
# Function to count subsequences
# in first which are anagrams
# of the second
def countSubsequences(str1, str2):
# Hash tables to store frequencies
# of each character
freq1 = np.zeros(26, dtype = np.int)
freq2 = np.zeros(26, dtype = np.int)
n1 = len(str1)
n2 = len(str2)
# Store frequency of each
# character of 'str1'
for i in range(0, n1):
freq1[ord(str1[i]) - ord('a') ] += 1
# Store frequency of each
# character of 'str2'
for i in range(0, n2):
freq2[ord(str2[i]) - ord('a')] += 1
# To store the total count
# of subsequences
count = 1
for i in range(0, SIZE):
# if character (i + 'a')
# exists in 'str2'
if (freq2[i] != 0):
# if this character's frequency
# in 'str2' in less than or
# equal to its frequency in
# 'str1' then accumulate its
# contribution to the count
# of subsequences. If its
# frequency in 'str1' is 'n'
# and in 'str2' is 'r', then
# its contribution will be nCr,
# where C is the binomial
# coefficient.
if (freq2[i] <= freq1[i]):
count = count * binomialCoeff(freq1[i], freq2[i])
# else return 0 as there could
# be no subsequence which is an
# anagram of 'str2'
else:
return 0
# required count of subsequences
return count
# Driver code
str1 = "abacd"
str2 = "abc"
ans = countSubsequences(str1, str2)
print ("Count = ", ans)
# This code contributed by saloni1297
C#
// C# implementation to
// count subsequences in
// first string which are
// anagrams of the second
// string
using System;
class GfG {
public static int SIZE = 26;
// Returns value of Binomial
// Coefficient C(n, k)
public static int binomialCoeff(int n,
int k)
{
int res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for (int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
// function to count subsequences
// in first string which are
// anagrams of the second string
public static int countSubsequences(String str,
String str3)
{
// hash tables to store frequencies
// of each character
int[] freq1 = new int [SIZE];
int[] freq2 = new int [SIZE];
char[] str1 = str.ToCharArray();
char[] str2 = str3.ToCharArray();
int n1 = str.Length;
int n2 = str3.Length;
// store frequency of each
// character of 'str1'
for (int i = 0; i < n1; i++)
freq1[str1[i] - 'a']++;
// store frequency of each
// character of 'str2'
for (int i = 0; i < n2; i++)
freq2[str2[i] - 'a']++;
// to store the total count
// of subsequences
int count = 1;
for (int i = 0; i < SIZE; i++)
// if character (i + 'a')
// exists in 'str2'
if (freq2[i] != 0) {
// if this character's frequency
// in 'str2' in less than or
// equal to its frequency in
// 'str1' then accumulate its
// contribution to the count
// of subsequences. If its
// frequency in 'str1' is 'n'
// and in 'str2' is 'r', then
// its contribution will be nCr,
// where C is the binomial
// coefficient.
if (freq2[i] <= freq1[i])
count = count * binomialCoeff(freq1[i],
freq2[i]);
// else return 0 as there could
// be no subsequence which is an
// anagram of 'str2'
else
return 0;
}
// required count of subsequences
return count;
}
// Driver code
public static void Main(String[] argc)
{
String str1 = "abacd";
String str2 = "abc";
Console.Write("Count = " +
countSubsequences(str1, str2));
}
}
// This code is contributed by parashar
PHP
$n - $k)
$k = $n - $k;
// Calculate value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for ($i = 0; $i < $k; ++$i)
{
$res *= ($n - $i);
$res /= ($i + 1);
}
return $res;
}
// function to count
// subsequences in
// first string which
// are anagrams of the
// second string
function countSubsequences($str1,
$str2)
{
global $SIZE;
// hash tables to
// store frequencies
// of each character
$freq1 = array();
$freq2 = array();
// Initialize
for ($i = 0;
$i < $SIZE; $i++)
{
$freq1[$i] = 0;
$freq2[$i] = 0;
}
$n1 = strlen($str1);
$n2 = strlen($str2);
// store frequency of each
// character of 'str1'
for ($i = 0; $i < $n1; $i++)
$freq1[ord($str1[$i]) -
ord('a')]++;
// store frequency of each
// character of 'str2'
for ($i = 0; $i < $n2; $i++)
$freq2[ord($str2[$i]) -
ord('a')]++;
// to store the total count
// of subsequences
$count = 1;
for ($i = 0; $i < $SIZE; $i++)
// if character (i + 'a')
// exists in 'str2'
if ($freq2[$i] != 0)
{
// if this character's frequency
// in 'str2' in less than or
// equal to its frequency in
// 'str1' then accumulate its
// contribution to the count
// of subsequences. If its
// frequency in 'str1' is 'n'
// and in 'str2' is 'r', then
// its contribution will be nCr,
// where C is the binomial
// coefficient.
if ($freq2[$i] <= $freq1[$i])
$count = $count *
binomialCoeff($freq1[$i],
$freq2[$i]);
// else return 0 as there
// could be no subsequence
// which is an anagram of
// 'str2'
else
return 0;
}
// required count
// of subsequences
return $count;
}
// Driver Code
$str1 = "abacd";
$str2 = "abc";
echo ("Count = ".
countSubsequences($str1,
$str2));
// This code is contributed by
// Manish Shaw(manishshaw1)
?>
Javascript
输出:
Count = 2
时间复杂度: O(n1 + n2) + O(max),其中max是最大频率。