3

Here is the problem:

Given two strings, find the number of common characters between them.

For s1 = "aabcc" and s2 = "adcaa", the output should be 3.

I have written this code :

function commonCharacterCount(s1, s2) {
  var count = 0;
  var str = "";
  for (var i = 0; i < s1.length; i++) {
    if (s2.indexOf(s1[i]) > -1 && str.indexOf(s1[i]) == -1) {
      count++;
      str.concat(s1[i])
    }
  }

  return count;
}

console.log(commonCharacterCount("aabcc", "adcaa"));

It doesn't give the right answer, I wanna know where I am wrong?

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Nasim
  • 161
  • 1
  • 3
  • 12
  • are you trying to find common or different characters in the string? – A l w a y s S u n n y Mar 09 '19 at 17:07
  • This is not the same question, but the answers may help you streamline your approach and solve one issue you are having which is you are only finding the first instance of character in the string with `indexOf`: [Count the number of occurrences of a character in a string](https://stackoverflow.com/questions/881085/count-the-number-of-occurrences-of-a-character-in-a-string-in-javascript) – benvc Mar 09 '19 at 17:18

8 Answers8

3

You can do that in following steps:

  1. Create a function that return an object. With keys as letters and count as values
  2. Get that count object of your both strings in the main function
  3. Iterate through any of the object using for..in
  4. Check other object have the key of first object.
  5. If it have add the least one to count using Math.min()

let s1 = "aabcc"
let s2 = "adcaa"

function countChars(arr){
  let obj = {};
  arr.forEach(i => obj[i] ? obj[i]++ : obj[i] = 1);
  return obj;
}


function common([...s1],[...s2]){
  s1 = countChars(s1);
  s2 = countChars(s2);
  let count = 0;
  for(let key in s1){
    if(s2[key]) count += Math.min(s1[key],s2[key]);
  }
  return count
}
console.log(common(s1,s2))
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
3

There are other more efficient answers, but this answer is easier to understand. This loops through the first string, and checks if the second string contains that value. If it does, count increases and that element from s2 is removed to prevent duplicates.

function commonCharacterCount(s1, s2) {
    var count = 0;
    s1 = Array.from(s1);
    s2 = Array.from(s2);
    
    s1.forEach(e => {
      if (s2.includes(e)) {
        count++;
        s2.splice(s2.indexOf(e), 1);
      }
    });
        
    return count;
}

console.log(commonCharacterCount("aabcc", "adcaa"));
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Aniket G
  • 3,471
  • 1
  • 13
  • 39
2

After posting the question, i found that i havent looked the example well. i thought it wants unique common characters .. and i changed it and now its right

function commonCharacterCount(s1, s2) {
    var count = 0;
    var str="";
    for(var i=0; i<s1.length ; i++){
        if(s2.indexOf(s1[i])>-1){  
            count++;
            s2=s2.replace(s1[i],'');
        }
    }                   
        
    return count;
}
Nasim
  • 161
  • 1
  • 3
  • 12
2
  • Create 2 objects containing characters and their count for strings s1 and s2

  • Count the common keys in 2 objects and return count - Sum the common keys with minimum count in two strings

  • O(n) - time and O(n) - space complexities

    function commonCharacterCount(s1, s2) {

        let obj1 = {}
        let obj2 = {}

        for(let char of s1){

            if(!obj1[char]) {

                obj1[char] = 1

            } else

                obj1[char]++

        }

        for(let char of s2){

            if(!obj2[char]) {

                obj2[char] = 1

            } else

                obj2[char]++

        }

        console.log(obj1,obj2)

        let count = 0

        for(let key in obj1 ){

            if(obj2[key])

                count += Math.min(obj1[key],obj2[key])
        }

        return count


    }
Jayanth Kumar T
  • 308
  • 4
  • 9
1

I think it would be a easier way to understand. :)

function commonCharacterCount(s1: string, s2: string): number {
    
    let vs1 = [];
    let vs2 = [];
    let counter = 0;
    
    vs1 = Array.from(s1);
    vs2 = Array.from(s2);
    
    vs1.sort();
    vs2.sort();
    
    let match_char = [];
    
    for(let i = 0; i < vs1.length; i++){
        
        for(let j = 0; j < vs2.length; j++){
            
            if(vs1[i] == vs2[j]){
                match_char.push(vs1[i]);
                vs2.splice(j, 1);
                break;
            }
        }
    }    
    
    return match_char.length;
}
1

JavaScript ES6 clean solution. Use for...of loop and includes method.

var commonCharacterCount = (s1, s2) => {
  const result = [];
  const reference = [...s1];
  let str = s2;

  for (const letter of reference) {
    if (str.includes(letter)) {
      result.push(letter);
      str = str.replace(letter, '');
    }
  }

  // ['a', 'a', 'c'];
  return result.length;
};

// Test:
console.log(commonCharacterCount('aabcc', 'adcaa'));
console.log(commonCharacterCount('abcd', 'aad'));
console.log(commonCharacterCount('geeksforgeeks', 'platformforgeeks'));
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
0

Cause .concat does not mutate the string called on, but it returns a new one, do:

str = str.concat(s1[i]);

or just

str += s1[i];
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • Sorry to downvote ya but this does not have anything to do with the question. concating two strings may be a step for you, but it does not answer the question at all. Could you provide a full example with your suggestion? – rimraf Apr 07 '20 at 00:57
0

You can store the frequencies of each of the characters and go over this map (char->frequency) and find the common ones.

function common(a, b) {
    const m1 = {};
    const m2 = {};
    let count = 0;
    for (const c of a) m1[c] = m1[c] ? m1[c]+1 : 1;
    for (const c of b) m2[c] = m2[c] ? m2[c]+1 : 1;
    for (const c of Object.keys(m1)) if (m2[c]) count += Math.min(m1[c], m2[c]);
    return count;
}
Boopathi Rajaa
  • 4,659
  • 2
  • 31
  • 53