📌  相关文章
📜  计算由相同数量的 a、b、c 和 d 组成的子串

📅  最后修改于: 2021-10-27 16:55:55             🧑  作者: Mango

给定一个字符串str ,任务是计算具有相同数量‘a’‘b’‘c’‘d’ 的非空子字符串。

例子:

方法:可以使用Hashing解决问题。这个想法是基于以下观察:

请按照以下步骤解决问题:

  • 初始化一个变量,比如cntSub ,以存储具有相同数量的‘a’‘b’‘c’‘d’的子串的计数。
  • 初始化一个 Map,比如mp ,以存储字符{ ‘a’ , ‘b’ , ‘c’ , ‘d’ } 的相对频率。
  • 遍历字符串的字符并存储字符“a”,“B”,“C”的相对频率,和“d”。
  • 使用地图的键值作为i遍历地图,对于每个键值,将cntSub的值增加{mp[i] \choose 2}   .
  • 最后,打印cntSub的值。

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to count the substring with
// equal number of a, b, c and d
int countSubstrings(string str)
{
 
    // Stores relative frequency of
    // the characters {'a', 'b', 'c', 'd'}
    map,
             pair >,
        int>
        mp;
 
    // Initially, frequencies of
    // 'a', 'b', 'c' and 'd' are 0.
    mp[{ { 0, 0 }, { 0, 0 } }]++;
 
    // Stores relative
    // frequency of 'a'
    int p = 0;
 
    // Stores relative
    // frequency of 'b'
    int q = 0;
 
    // Stores relative
    // frequency of 'c'
    int r = 0;
 
    // Stores relative
    // frequency of 'd'
    int s = 0;
 
    // Stores count of substring with equal
    // number of 'a', 'b', 'c' and 'd'
    int cntSub = 0;
 
    // Iterate over the characters
    // of the string
    for (int i = 0; i < str.length(); i++) {
 
        // If current character
        // is 'a'
        if (str[i] == 'a') {
 
            // Update p
            p++;
 
            // Stores minimum
            // of { p, q, r, s}
            int Y = min(min(s, r),
                        min(p, q));
 
            // Update p
            p -= Y;
 
            // Update q
            q -= Y;
 
            // Update r
            r -= Y;
 
            // Update s
            s -= Y;
        }
 
        // If current character is b
        else if (str[i] == 'b') {
 
            // Update q
            q++;
 
            // Stores minimum
            // of { p, q, r, s}
            int Y = min(min(p, q),
                        min(r, s));
 
            // Update p
            p -= Y;
 
            // Update q
            q -= Y;
 
            // Update r
            r -= Y;
 
            // Update s
            s -= Y;
        }
        else if (str[i] == 'c') {
 
            // Update r
            r++;
 
            // Stores minimum
            // of { p, q, r, s}
            int Y = min(min(p, q),
                        min(r, s));
 
            // Update p
            p -= Y;
 
            // Update q
            q -= Y;
 
            // Update r
            r -= Y;
 
            // Update s
            s -= Y;
        }
        else if (str[i] == 'd') {
 
            // Update s
            s++;
 
            // Stores minimum
            // of { p, q, r, s}
            int Y = min(min(p, q),
                        min(r, s));
 
            // Update p
            p -= Y;
 
            // Update q
            q -= Y;
 
            // Update r
            r -= Y;
 
            // Update s
            s -= Y;
        }
 
        // Update relative frequency
        // of {p, q, r, s}
        mp[{ { p, q }, { r, s } }]++;
    }
 
    // Traverse the map
    for (auto& e : mp) {
 
        // Stores count of
        // relative frequency
        int freq = e.second;
 
        // Update cntSub
        cntSub += (freq) * (freq - 1) / 2;
    }
    return cntSub;
}
 
// Driver Code
int main()
{
 
    string str = "abcdefg";
 
    // Function Call
    cout << countSubstrings(str);
    return 0;
}


Python3
# Python3 program to implement
# the above approach
 
# Function to count the substring with
# equal number of a, b, c and d
def countSubstrings(Str) :
     
    # Stores relative frequency of
    # the characters {'a', 'b', 'c', 'd'}
    mp = {}
     
    # Initially, frequencies of
    # 'a', 'b', 'c' and 'd' are 0.
    if ((0, 0), (0, 0)) in mp :
        mp[(0, 0), (0, 0)] += 1
    else :
        mp[(0, 0), (0, 0)] = 1
         
    # Stores relative
    # frequency of 'a'
    p = 0
     
    # Stores relative
    # frequency of 'b'
    q = 0
     
    # Stores relative
    # frequency of 'c'
    r = 0
     
    # Stores relative
    # frequency of 'd'
    s = 0
     
    # Stores count of substring with equal
    # number of 'a', 'b', 'c' and 'd'
    cntSub = 0
     
    # Iterate over the characters
    # of the string
    for i in range(len(Str)) :
         
        # If current character
        # is 'a'
        if (Str[i] == 'a') :
            # Update p
            p += 1
             
            # Stores minimum
            # of { p, q, r, s}
            Y = min(min(s, r), min(p, q))
             
            # Update p
            p -= Y
             
            # Update q
            q -= Y
             
            # Update r
            r -= Y
             
            # Update s
            s -= Y
             
        # If current character is b
        elif (Str[i] == 'b') :
             
            # Update q
            q += 1
             
            # Stores minimum
            # of { p, q, r, s}
            Y = min(min(p, q), min(r, s))
             
            # Update p
            p -= Y
             
            # Update q
            q -= Y
             
            # Update r
            r -= Y
             
            # Update s
            s -= Y
             
        elif (Str[i] == 'c') :
             
            # Update r
            r += 1
             
            # Stores minimum
            # of { p, q, r, s}
            Y = min(min(p, q),min(r, s))
             
            # Update p
            p -= Y
             
            # Update q
            q -= Y
             
            # Update r
            r -= Y
             
            # Update s
            s -= Y
             
        elif (Str[i] == 'd') :
             
            # Update s
            s += 1
             
            # Stores minimum
            # of { p, q, r, s}
            Y = min(min(p, q),min(r, s))
             
            # Update p
            p -= Y
             
            # Update q
            q -= Y
             
            # Update r
            r -= Y
             
            # Update s
            s -= Y
             
        # Update relative frequency
        # of {p, q, r, s}
        if ((p, q), (r, s)) in mp :
            mp[(p, q), (r, s)] += 1
        else :
            mp[(p, q), (r, s)] = 1
             
    # Traverse the map
    for e in mp :
         
        # Stores count of
        # relative frequency
         
        freq = mp[e]
         
        # Update cntSub
        cntSub += (freq) * (freq - 1) // 2
         
    return cntSub
 
  # Driver code
Str = "abcdefg"
 
# Function Call
print(countSubstrings(Str))
 
# This code is contributed by divyeshrabadiya07


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic; 
class GFG {
     
    // Function to count the substring with
    // equal number of a, b, c and d
    static int countSubstrings(string str)
    {
       
        // Stores relative frequency of
        // the characters {'a', 'b', 'c', 'd'}
        Dictionary,
      Tuple>, int> mp =
        new Dictionary,
      Tuple>, int>(); 
       
        // Initially, frequencies of
        // 'a', 'b', 'c' and 'd' are 0.
        if(mp.ContainsKey(new Tuple,
                          Tuple>(new Tuple(0, 0),
                                           new Tuple(0, 0))))
        {
            mp[new Tuple,
               Tuple>(new Tuple(0, 0),
                                new Tuple(0, 0))]++;
        }
        else{
            mp[new Tuple,
               Tuple>(new Tuple(0, 0),
                                new Tuple(0, 0))] = 1;
        }
       
        // Stores relative
        // frequency of 'a'
        int p = 0;
       
        // Stores relative
        // frequency of 'b'
        int q = 0;
       
        // Stores relative
        // frequency of 'c'
        int r = 0;
       
        // Stores relative
        // frequency of 'd'
        int s = 0;
       
        // Stores count of substring with equal
        // number of 'a', 'b', 'c' and 'd'
        int cntSub = 0;
       
        // Iterate over the characters
        // of the string
        for (int i = 0; i < str.Length; i++) {
       
            // If current character
            // is 'a'
            if (str[i] == 'a') {
       
                // Update p
                p++;
       
                // Stores minimum
                // of { p, q, r, s}
                int Y = Math.Min(Math.Min(s, r),
                            Math.Min(p, q));
       
                // Update p
                p -= Y;
       
                // Update q
                q -= Y;
       
                // Update r
                r -= Y;
       
                // Update s
                s -= Y;
            }
       
            // If current character is b
            else if (str[i] == 'b') {
       
                // Update q
                q++;
       
                // Stores minimum
                // of { p, q, r, s}
                int Y = Math.Min(Math.Min(p, q),
                            Math.Min(r, s));
       
                // Update p
                p -= Y;
       
                // Update q
                q -= Y;
       
                // Update r
                r -= Y;
       
                // Update s
                s -= Y;
            }
            else if (str[i] == 'c') {
       
                // Update r
                r++;
       
                // Stores minimum
                // of { p, q, r, s}
                int Y = Math.Min(Math.Min(p, q),
                            Math.Min(r, s));
       
                // Update p
                p -= Y;
       
                // Update q
                q -= Y;
       
                // Update r
                r -= Y;
       
                // Update s
                s -= Y;
            }
            else if (str[i] == 'd') {
       
                // Update s
                s++;
       
                // Stores minimum
                // of { p, q, r, s}
                int Y = Math.Min(Math.Min(p, q),
                            Math.Min(r, s));
       
                // Update p
                p -= Y;
       
                // Update q
                q -= Y;
       
                // Update r
                r -= Y;
       
                // Update s
                s -= Y;
            }
       
            // Update relative frequency
            // of {p, q, r, s}
            if(mp.ContainsKey(new Tuple,
                              Tuple>(new Tuple(p, q),
                                               new Tuple(r, s))))
            {
                mp[new Tuple,
                   Tuple>(new Tuple(p, q),
                                    new Tuple(r, s))]++;
            }
            else{
                mp[new Tuple,
                   Tuple>(new Tuple(p, q),
                                    new Tuple(r, s))] = 1;
            }
        }
       
        // Traverse the map
        foreach(KeyValuePair,
                Tuple>, int> e in mp)
        {
       
            // Stores count of
            // relative frequency
            int freq = e.Value;
       
            // Update cntSub
            cntSub += (freq) * (freq - 1) / 2;
        }
        return cntSub;
    }
 
  // Driver code
  static void Main()
  {
       
    string str = "abcdefg";
   
    // Function Call
    Console.WriteLine(countSubstrings(str));
  }
}
 
// This code is contributed by divyesh072019


输出:
10

时间复杂度: O(N * Log(N))
辅助空间: O(N)