Count subsequences 01 in string generated by concatenation of given numeric string K times


The analysis and manipulation of strings are fundamental operations in many applications of computer programming. Counting subsequences with the pattern "01" in a string formed by repetitively concatenating a given numeric string poses an interesting challenge. The primary question is determining the total count of such subsequences in the resulting string. This article discusses a useful C++ approach to solve this issue successfully and offers a solid answer to deal with this particular work.

Concept of Subsequence

A subsequence is a sequence of characters that is derived from some other sequence by eliminating zero or more characters without altering the relative order of the characters that are remaining, in the context of string manipulation and sequence analysis. In other terms, a subsequence is said to be a subset of the given sequence in which the elements' order has to be maintained.

The following are important facts about subsequences −

  • Maintaining Order − The relative order of the elements from the initial sequence is maintained by a subsequence. For instance, if the original sequence is "19023," a subsequence could be "923," in which the elements "9," "2," and "3" are chosen from the original sequence while still being arranged in the same way.

  • Element Removal − Subsequences are produced by removing certain elements from the starting sequence one at a time. Any specific element may be included or excluded in the subsequence. Potential subsequences, for instance, from the first grouping "190," include "1," "9," "0," "19," "90," "10," and "190."

  • Length of subsequence − A subsequence's length can range from zero (an empty subsequence) to the length of the main sequence. This suggests that a subsequence may be shorter or of the same length as the original sequence.

  • Non-Contiguous Selection − Unlike substrings, sequences do not need that the components selected be adjacent in the original sequence. The elements may be chosen, provided that their relative order is preserved. An example of a subsequence from the original sequence "1902" is "12," which has elements "1" and "2" that are not adjacent but are still in the same order as the original sequence.

Input

S = "101"
K = 2

Output

4

Here, the given string is repeated k=2 times, so by concatenating the original string 2 times, we get a new string = "101101".

Below are 4 occurrences of "01":

First possible subsequence: 101101

Second possible subsequence:101101

Third possible subsequence:101101

Fourth possible subsequence:101101

Brute Force Approach

The simplest way to solve the following problem is to concatenate original string str, k times to produce the resultant string. From there, locate all feasible pairings (i, j) from the string such that (i j) and str[i] = 0 and str[j] = 1.

Example

Following is the implementation of the above approach in different programming languages: C, C++, Java, and Python −

#include <stdio.h>
#include <string.h>
int count_subseq(char s[], int k) {
   int s_len = strlen(s);
   char s2[1000] = "";

   for (int z = 0; z < k; z++) {
      strcat(s2, s);
   }
   int s2_len = strlen(s2);
   int count = 0;

   for (int i = 0; i < s2_len; i++) {
      if (s2[i] == '0') {
         for (int j = i + 1; j < s2_len; j++) {
            if (s2[j] == '1' && i < j) {
               count = count + 1;
            }
         }
      }
   }
   return count;
}
int main() {
   char str[] = "1091";
   int k = 2;
   int ans = count_subseq(str, k);
   printf("%d\n", ans);
   return 0;
}

Output

4
#include <iostream>
#include <string>
using namespace std;
int count_subseq(string s, int k){
   int s_len=s.length();
   string s2="";
   for (int z = 0; z < k; z++){
      s2+=s;
   }
   int s2_len=s2.length();
   int count=0;
   int ans;
   for(int i=0; i<s2_len;i++){
      if(s2[i]=='0'){
         for (int j = i+1; j < s2_len; j++){
            if(s2[j]=='1' && i<j){
               count=count+1;
            }
         }
      }
   }
   return count;
}
int main(){
   string str="1091";
   int k=2;
   int ans=count_subseq(str, k);
   cout<<ans<<endl;
   return 0;
}	  

Output

4
public class SubsequenceCount {
   static int countSubseq(String s, int k) {
      StringBuilder s2 = new StringBuilder();
      for (int z = 0; z < k; z++) {
         s2.append(s);
      }

      int s2Len = s2.length();
      int count = 0;

      for (int i = 0; i < s2Len; i++) {
         if (s2.charAt(i) == '0') {
            for (int j = i + 1; j < s2Len; j++) {
               if (s2.charAt(j) == '1' && i < j) {
                  count++;
               }
            }
         }
      }
      return count;
   }
   public static void main(String[] args) {
      String str = "1091";
      int k = 2;
      int ans = countSubseq(str, k);
      System.out.println(ans);
   }
}

Output

4
def count_subseq(s, k):
   s2 = ""
   for z in range(k):
      s2 += s

   s2_len = len(s2)
   count = 0

   for i in range(s2_len):
      if s2[i] == '0':
         for j in range(i + 1, s2_len):
            if s2[j] == '1' and i < j:
               count += 1
   return count
if __name__ == "__main__":
   str_val = "1091"
   k_val = 2
   ans_val = count_subseq(str_val, k_val)
   print(ans_val)

Output

4

Optimized Approach

Let S be the concatenated string and s be the original string.

If the subsequence "01" lies completely within a single occurrence of the string s in S, then the number of occurrences of "01" in S can be obtained by counting the occurrences of "01" in that particular occurrence of s. Let this count be denoted as s_cnt. In this case, the total number of occurrences of "01" in S will be s_cnt*k. This is because we can simply replicate the same occurrence of "01" k times to form S.

Otherwise if the letter '0' lies strictly inside one occurrence of s(let's say si), and the letter '1' lies inside some other occurrence of s(let's say sj) such that i < j, we need to consider the occurrences of both '0' and '1' in their respective positions within S.

Therefore, in this scenario, to find the number of occurrences of "01" in S, we first choose two occurrences of the string s out of the total k occurrences (kC2 or (k * (k − 1)) / 2). This accounts for selecting one occurrence of '0' which is in si and one occurrence of '1' which is in sj.

Next, we multiply this count by the number of occurrences of '0' within si and the number of occurrences of '1' within sj.

Example

Following is the implementation of the above approach in different programming languages: C, C++, Java, and Python −

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int subseq_cnt(char s[], int len, int k){
   // storing the count of 0's and 1's present in the original string
   int oneString_subseq_cnt = 0, ones_cnt = 0, zeros_cnt = 0;
   // calculating the number of 1s and 0s present in the original string
   for (int i = 0; i < len; i++){
      if (s[i] == '1')
         ones_cnt++;
      else if (s[i] == '0')
         zeros_cnt++;
   }
   // Count of subsequences present without doing concatenation
   int occured_ones = 0;
   for (int i = 0; i < len; i++){
      if (s[i] == '1')
         occured_ones++;
      else if (s[i] == '0')
         oneString_subseq_cnt += (ones_cnt - occured_ones);
   }
   /* ans1= number of subsequences 01 formed witnin a single string s without concatenating.*/
   int ans1 = oneString_subseq_cnt * k;
   /* ans2= number of subsequences 01 formed by considering 0 in one occurence and 1 in other occurence.*/
   int ans2 = ( zeros_cnt *ones_cnt * (((k) * (k - 1)) / 2));
   // Return the total subsequences present after concatenation
   return ans1 + ans2;
}
int main(){
   char str[] = "1091";
   int k = 2;
   int n = strlen(str);
   printf("%d", subseq_cnt(str, n, k));
   return 0;
}

Output

4
#include <iostream>
#include <string>
using namespace std;

int subseq_cnt(string s, int len, int k){
   // storing the count of 0's and 1's present in the original string
   int oneString_subseq_cnt = 0, ones_cnt = 0, zeros_cnt = 0;
   // calculating the number of 1s and 0s present in the original string
   for (int i = 0; i < len; i++){
      if (s[i] == '1')
         ones_cnt++;
      else if (s[i] == '0')
         zeros_cnt++;
   }
   // Count of subsequences present without doing concatenation
   int occured_ones = 0;
   for (int i = 0; i < len; i++){
      if (s[i] == '1')
         occured_ones++;
      else if (s[i] == '0')
         oneString_subseq_cnt += (ones_cnt - occured_ones);
   }
   /* ans1= number of subsequences 01 formed witnin a single string s without concatenating.*/
   int ans1 = oneString_subseq_cnt * k;
   /* ans2= number of subsequences 01 formed by considering 0 in one occurence and 1 in other occurence.*/
   int ans2 = ( zeros_cnt *ones_cnt * (((k) * (k - 1)) / 2));
   // Return the total subsequences present after concatenation
   return ans1 + ans2;
}
int main(){
   string str = "1091";
   int k = 2;
   int n = str.length();
   cout << subseq_cnt(str, n, k);
   return 0;
}	  

Output

4
public class SubsequenceCount {
   static int subseqCnt(String s, int len, int k) {
      // storing the count of 0's and 1's present in the original string
      int oneStringSubseqCnt = 0, onesCnt = 0, zerosCnt = 0;
      for (int i = 0; i < len; i++) {
         if (s.charAt(i) == '1')
            onesCnt++;
         else if (s.charAt(i) == '0')
            zerosCnt++;
      }
      // Count of subsequences present without doing concatenation
      int occuredOnes = 0;
      for (int i = 0; i < len; i++) {
         if (s.charAt(i) == '1')
            occuredOnes++;
         else if (s.charAt(i) == '0')
            oneStringSubseqCnt += (onesCnt - occuredOnes);
      }
      /* ans1= number of subsequences 01 formed witnin a single string s without concatenating.*/
      int ans1 = oneStringSubseqCnt * k;
      int ans2 = (zerosCnt * onesCnt * (((k) * (k - 1)) / 2));
      // Return the total subsequences present after concatenation
      return ans1 + ans2;
   }

   public static void main(String[] args) {
      String str = "1091";
      int k = 2;
      int n = str.length();
      System.out.println(subseqCnt(str, n, k));
   }
}

Output

4
def subseq_cnt(s, len, k):
   #storing the count of 0's and 1's present in the original string
   one_string_subseq_cnt = 0
   ones_cnt = 0
   zeros_cnt = 0

   for i in range(len):
      if s[i] == '1':
         ones_cnt += 1
      elif s[i] == '0':
         zeros_cnt += 1
   # Count of subsequences present without doing concatenation
   occured_ones = 0
   for i in range(len):
      if s[i] == '1':
         occured_ones += 1
      elif s[i] == '0':
         one_string_subseq_cnt += (ones_cnt - occured_ones)
    
   # ans1= number of subsequences 01 formed witnin a single string s without concatenating.
   ans1 = one_string_subseq_cnt * k
   #ans2= number of subsequences 01 formed by considering 0 in one occurence and 1 in other occurence.
   ans2 = (zeros_cnt * ones_cnt * (((k) * (k - 1)) // 2))
   # Return the total subsequences present after concatenation
   return ans1 + ans2

if __name__ == "__main__":
   str_val = "1091"
   k_val = 2
   n_val = len(str_val)
   print(subseq_cnt(str_val, n_val, k_val))

Output

4

Test Case

Test case → "101"
  • Count of 0's and 1's

For the given sequence "101," there is 1 occurrence of '0' and 2 occurrences of '1'.

ones_cnt= 2 
zeros_cnt= 1 
  • Count of subsequences without concatenation:

Iterate through the sequence and keep track of the counts. Whenever a '0' is encountered, add the difference between the total count of 1's and the current count of 1's to the variable 'oneString_subseq_cnt'.

In the given sequence "101," there is 1 '0' at index 1. At that point, ones_cnt= 1. Hence, 'oneString_subseq_cnt 'is incremented by (ones_cnt − occured_ones) = (1 − 0) = 1.

So, oneString_subseq_cnt= 1

  • ans1 − deals with the count of subsequences considering the concatenation.

ans1 = (oneString_subseq_cnt) * k = 1 * 2 = 2

ans2 = deals with the count of subsequences considering concatenation and combinations.

ans2 = ( zeros_cnt* ones_cnt *(((k) * (k − 1)) / 2))

ans2 = (2 * 1 * (((2) * (2 - 1)) / 2))

ans2 = (2 * 1 * 1)

ans2 = 2

Hence, the final answer is ans1+ ans2 = 4.

Conclusion

This article offers a C++ way to determine how many subsequences with the pattern "01" there are in a string created by joining a given numeric string K times. The number of instances of the required subsequence in the final concatenated string can be effectively determined using the provided code. This solution gives a workable way to deal with the issue and can be used in a variety of programming contexts where counting subsequences in concatenated strings is necessary

Updated on: 09-Feb-2024

47 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements