Counting matching substrings in JavaScript


The ability to accurately count matching substrings within a given string is a pivotal skill in JavaScript programming, as it empowers developers to efficiently analyze and manipulate text data. Delving into the realm of string manipulation, this article explores the intricacies of counting matching substrings in JavaScript, employing a range of lesser-known techniques. By unraveling the underlying logic and employing these unconventional methods, developers can gain a deeper understanding of how to effectively tally occurrences of specific substrings, enabling them to extract meaningful insights from textual data. Join us on this enlightening journey as we unlock the potential of JavaScript's robust functionality and expand our repertoire of rarefied vocabulary to master the art of counting matching substrings.

Problem Statement

We require a JavaScript function that counts subsequences in a given string, taking a string input named "str" and an array of strings input named "arr." The objective is to examine each element in "arr" and determine the number of strings that are subsequences of "str." A subsequence refers to a string that can be formed by removing characters from the original string while maintaining the relative order of the remaining characters. The function should meticulously compare each element in "arr" to "str" and identify if it can be constructed by removing characters from "str." It will then return an integer representing the count of qualifying subsequences found in "str."

Sample Input −

str = 'abracadabra';
arr = ['a', 'bra', 'cad', 'dab'];

Sample Output −

Output =4;

Output Explanation −

In the given input, the string "str" is 'abracadabra' and the array "arr" contains ['a', 'bra', 'cad', 'dab'].

Analyzing each element of "arr," we find that 'a', 'bra', 'cad', and 'dab' are all subsequences of "str." Therefore, the count of subsequences is 4, which is the expected output.

Approach

In this article, we are going to see a number of different ways to solve the above problem statement in JavaScript −

  • Brute-Force Approach

  • Two-Pointer Approach

Method 1: Brute-Force Approach

The brute force approach to count valid subsequences involves generating all possible subsequences of a string and checking their presence in an array. We iterate through each string, generate subsequences recursively or using bit manipulation, and compare them with array elements. A counter increments for each match, giving the total count. This method is computationally expensive for larger inputs, so alternative algorithms like dynamic programming offer more optimized solutions.

Example

The code implements a recursive algorithm to count the number of subsequences of a given string (str) in an array of strings (arr). The countSubsequences function initializes a count variable to track the valid subsequences. The generateSubsequences function generates all possible subsequences by iterating through the input string and checking if each subsequence exists in the array. Recursive calls are made to explore different possibilities for including or excluding characters. The main function call starts generating subsequences from the beginning of the string. The count variable is returned as the final result. An example usage demonstrates the function's usage with a sample string and an array of strings. The result is stored and printed to the console.

function countSubsequences(str, arr) {
   let count = 0;
 
   // Generate all possible subsequences of the input string
   function generateSubsequences(sub, index) {
      if (index === str.length) {
         // Check if the subsequence exists in the array
         if (arr.includes(sub)) {
            count++;
         }
         return;
      }
 
      // Include the current character in the subsequence
      generateSubsequences(sub + str[index], index + 1);
 
      // Exclude the current character from the subsequence
      generateSubsequences(sub, index + 1);
   }
 
   // Start generating subsequences from the beginning of the string
   generateSubsequences("", 0);
 
   return count;
}
 
// Example usage:
const str = "abcde";
const arr = ["a", "ab", "bd", "abc", "acde", "eab"];
const result = countSubsequences(str, arr);
console.log(result);

Output

The following is the console output −

5

Method 2: Two-Pointer Method

The algorithm traverses through every string in an array and employs two pointers, one designated for the given string and another for the present string under examination. These pointers are initially positioned at the inaugural character of their corresponding strings and subsequently propelled forward until they encounter the terminus of either string. On each occasion that a valid subsequence is ascertained, an incrementation is made to a numerical indicator. Ultimately, the algorithm furnishes the numerical value of the indicator as the final outcome.

Example

The function countValidSubsequences takes an array of strings (arr) and a target string (target) as parameters. It iterates over each string in arr and compares its characters with the characters in target using nested loops. If the characters match, the indices are incremented; if they don't match, only the index for target is incremented. If the entire string is a valid subsequence, the count is incremented. After iterating through all strings in arr, the function returns the final count.

function countValidSubsequences(arr, target) {
   let count = 0;
 
   for (let i = 0; i < arr.length; i++) {
      const current = arr[i];
      let j = 0;
      let k = 0;
 
      while (j < current.length && k < target.length) {
         if (current[j] === target[k]) {
            j++;
            k++;
         } else {
            k++;
         }
      }
 
      if (j === current.length) {
         count++;
      }
   }
 
   return count;
}
 
// Example usage: 
const str = "abcde"; 
const arr = ["a", "ab", "bd", "abc", "acde", "eab"]; 
const result = countValidSubsequences(arr, str); 
console.log(result);

Output

The following is the console output −

5

Conclusion

In culmination, the exploration of counting matching substrings in JavaScript has unearthed a plethora of ingenious techniques that can be employed to accomplish this task efficiently. By employing various algorithms and leveraging the rarely utilized capabilities of the language, programmers can devise elegant and resourceful solutions. It is imperative to acknowledge that the intricate nature of substring matching necessitates careful consideration of edge cases and potential performance implications. Nevertheless, armed with these newfound insights, developers can transcend conventional methodologies and harness the full potential of JavaScript to enumerate and manipulate substrings with finesse. In conclusion, the esoteric knowledge shared in this article empowers programmers to elevate their coding prowess and unlock new dimensions of substring counting in JavaScript.

Updated on: 04-Aug-2023

81 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements