Home > Enterprise >  frequentVowelCounter(word, count = {}) using recursion
frequentVowelCounter(word, count = {}) using recursion

Time:11-12

I can do this problem using a for loop, but I'm having trouble using the recursive method.

I want to count how many times each vowel is called and return the most frequent vowel in an array.

If the array does not have a vowel to return is a string.

const vowel = ['a', 'e', 'i', 'o', 'u'];
frequentVowelCounter(word, count = {})
frequentVowelCounter(['cat', 'rain', 'dorm', 'apple', 'sun'])); // 'a'

I tried writing a base case:

if (word.length != vowel)
   return ''

I don't think it's right, I'm just stuck.

CodePudding user response:

Why would you want to make this recursive? An iterative approach works well.

  1. You will need to loop over each word, and for each word, its letters. As you loop over each letter, you check to see if it is a vowel. If it is a vowel, you increment the frequency map i.e byLetter.
  2. After you build the letter frequency map, you will need to invert the map into a count map i.e. byCount.
  3. Finally, you can get the keys of the byCount map to find the max count and return the value for the corresponding entry in the map.

Note: You may have more than one letter share the same max occurrence count. This is why the result of the function in an array.

const maxFrequency = (words, letters) => {
  const
    letterSet = new Set(letters),
    byLetter = new Map(),
    byCount = new Map();
  for (let word of words) {
    for (let letter of word.toLowerCase().split('')) {
      if (letterSet.has(letter)) {
        byLetter.set(letter, (byLetter.get(letter) ?? 0)   1);
      }
    }
  }
  for (let [letter, count] of byLetter) {
    const letters = byCount.get(count) ?? new Set();
    byCount.set(count, letters.add(letter));
  }
  return [...byCount.get(Math.max(...byCount.keys()))];
};

const
  vowels = ['a', 'e', 'i', 'o', 'u'],
  words = ['cat', 'rain', 'dorm', 'apple', 'sun'],
  mostFrequent = maxFrequency(words, vowels);

console.log(...mostFrequent); // ['a']

If you want to do this recursively, just join all the words together and iterate through the string starting at index 0. The helper function i.e. __helperFn should never be called directly.

Note: You will need a helper function to set up and perform the recursion.

const __helperFn = (str, letterSet, frequency) => {
  if (str.length === 0) {
    const max = Math.max(...Object.values(frequency));
    return Object.entries(frequency)
      .filter(([letter, count]) => count === max)
      .map(([letter]) => letter);
  }
  const letter = str.charAt(0);
  if (letterSet.has(letter)) {
    frequency[letter] = (frequency[letter] ?? 0)   1;
  } 
  return __helperFn(str.slice(1), letterSet, frequency);
}

const maxFrequency = (words, letters) =>
  __helperFn(words.join('').toLowerCase(), new Set(letters), {});

const
  vowels = ['a', 'e', 'i', 'o', 'u'],
  words = ['cat', 'rain', 'dorm', 'apple', 'sun'],
  mostFrequent = maxFrequency(words, vowels);

console.log(...mostFrequent); // ['a']

CodePudding user response:

This should work:

let w = ["cat", "rain", "dorm", "apple", "sun"];

const vowelCounter = (words) => {
    let vowels = {
        a: 0,
        e: 0,
        i: 0,
        o: 0,
        u: 0,
    };

    const count = (char) => {
        if (vowels.hasOwnProperty(char)) {
            vowels[char]  ;
        }
    };

    const rekursive = (words, index = 0) => {
        if (index === words.length) {
            return;
        }
        let i = 0;
        while (true) {
            if (i >= words[index].length) {
                break;
            }
            try {
                count(words[index].charAt(i));
            } catch (error) {}
            i  ;
        }
        rekursive(words,   index);
    };

    rekursive(words);
    console.log(vowels);
};

vowelCounter(w);

  • Related