0

There are two strings called str1 and str2 and I'm trying to check if str1 can be re-arranged as str2.

FOR EXAMPLE: lets say str1 = "aabbcamaomsccdd" and str2="commas". Is it possible to write the word "commas" out of "str1"

function scramble(str1, str2) {

  let arr=[]; 
  let str1arr =  str1.split("");
  let str2arr =  str2.split("");
  let j=0;
  
  for(let i=0; i<str1.length; i++){
    if(str1arr[i]==str2arr[j]){
      arr.push(str1arr[i]);
      str1arr=str1arr.splice(i,1);
      j++;
      i=0;
      
    }
    
  }if(arr.toString()===str2arr.toString()){
    return true;
  }else{
    return false;
  }
    }

What I tried basically if str1arr[i]==str2arr[j] it will put the str1arr[i] value on a new array called arr and at the end it will compare str2 and the arr and return True or False.

The reason why I used str1arr=str1arr.splice(i,1); to delete the i after the match is because the for loop is reseting it self to check from the "i=0" each time i and j matches and that i would match with other duplicate letters (I hope thats what it does atleast :D).

It is an internet question and im not passing the tests. I only pass if the result is FALSE.

I want to know what I'm doing and thinking wrong here. Its not performance efficent too so any comment on that would be great too.

  • 4
    Does sorting both strings and comparing work? – Som Shekhar Mukherjee Jun 06 '21 at 07:45
  • You should say that only portion of the string1 is tested, not the whole string, because it changes the task: https://stackoverflow.com/questions/40823054/how-to-write-a-function-that-returns-true-if-a-portion-of-str1-can-be-rearranged – sinisake Jun 06 '21 at 07:48
  • I dont understand what it means by the portion of str1. Str1 is basically scrambled letters like str1="aabbcamaomsccdd" and str2 is = "commas" lets say. Question is can make out the word commas out of the letters inside the str1. – Ömer Faruk Çalışkan Jun 06 '21 at 07:54

3 Answers3

2

You could take arrays and sort them and check each character of the second string/array against the first one.

function compare([...a], [...b]) {
    a.sort();
    return b.sort().every((i => v => {
        while (i < a.length && a[i] !== v) i++;
        return a[i++] === v;
    })(0));
}

console.log(compare("aabbcamaomsccdd", "commas")); //  true
console.log(compare("aabbcamaomccdd", "commas"));  // false
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

You should just check that both strings contain the same chars like so:

function scramble(str1, str2) {
    var s1 = str1.split('');
    var s2 = str2.split('');
    var i;
    for (i = 0; i < s2.length; i++) {
      const idx = s1.indexOf(s2[i]);
      if (idx === -1) {
        return false;
      }
      s1.splice(idx, 1);
    }
    return s1.length === 0;
}

console.log(scramble('xcab1c', 'abxcc1'));
Alon Yampolski
  • 851
  • 7
  • 15
  • 1
    This doesnt work if st1 and st2 doenst have the same length. – Ömer Faruk Çalışkan Jun 06 '21 at 08:19
  • of course it does! if s2 is longer then, at some point, you'll get -1 in `indexOf()`. If s1 is longer then you'll get false at `return s1.length === 0` – Alon Yampolski Jun 06 '21 at 08:24
  • I actually dont know why your code fails the test it looks fine to me. But I changed the if to `if(idx>1){ s1.splice(idx,1)` and put an `else` that returns false after the `if`. Now it passes the tests but still fails from the performance test and times out long stirngs. – Ömer Faruk Çalışkan Jun 06 '21 at 09:09
0

You could count the frequency of each character in your first string. Below I have used .reduce() to build an object with key-value pairs, where the key represents a character from your s1 string and the value is how many times it appears. You can then loop through the characters in s2 and check that every character appears in the frequency map. When you see a character you can subtract one from the value from the frequency object to signify that the character has been "used". If the .every() callback returns a falsy value (such as 0 for the value), then the result will be false, as your string can't be re-arranged:

const scramble = (s1, s2) => {
  const s1Freq = [...s1].reduce((o, c) => ({...o, [c]: (o[c] || 0) +1}), {});
  return [...s2].every(char => s1Freq[char]--); 
}

console.log(scramble("aabbcamaomsccdd", "commas")); // true
console.log(scramble("abc321", "123")); // true
console.log(scramble("a3b2c11", "1231")); // true
console.log(scramble("a", "a")); // true
console.log(scramble("xyz", "xyt")); // false
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64