admin管理员组

文章数量:1406149

I'm trying to write a function that takes in two string parameters and check if the second parameter is a rotated version of the first string.

So the following would be the results:

checkRotationStrings('waterbottle', 'lewaterbott'); // true checkRotationStrings('waterbottle', 'bottlewater'); // true checkRotationStrings('waterbottle', 'erbottlewat'); // true checkRotationStrings('waterbottle', 'lewaterbottx'); // false

I wrote the following code, but there are some edge cases that I can't seem to figure out:

function checkRotationStrings(string, rotatedString) {
  let result;
  let rotationCheck
  let stringArr = string.split('');
  let rotatedStringArr = rotatedString.split('')

  for (let i = 0; i < string.length - 1; i++) {
    if (rotatedString[0] === stringArr[i]) {
       result = stringArr.slice(i);
       rotationCheck = stringArr.slice(0, i).concat(result).join('');
    }
  }
  console.log(rotationCheck)
  if (rotationCheck === string){
    return true;
  } else {
    return false;
  }
}

Any help would be appreciated.

I'm trying to write a function that takes in two string parameters and check if the second parameter is a rotated version of the first string.

So the following would be the results:

checkRotationStrings('waterbottle', 'lewaterbott'); // true checkRotationStrings('waterbottle', 'bottlewater'); // true checkRotationStrings('waterbottle', 'erbottlewat'); // true checkRotationStrings('waterbottle', 'lewaterbottx'); // false

I wrote the following code, but there are some edge cases that I can't seem to figure out:

function checkRotationStrings(string, rotatedString) {
  let result;
  let rotationCheck
  let stringArr = string.split('');
  let rotatedStringArr = rotatedString.split('')

  for (let i = 0; i < string.length - 1; i++) {
    if (rotatedString[0] === stringArr[i]) {
       result = stringArr.slice(i);
       rotationCheck = stringArr.slice(0, i).concat(result).join('');
    }
  }
  console.log(rotationCheck)
  if (rotationCheck === string){
    return true;
  } else {
    return false;
  }
}

Any help would be appreciated.

Share Improve this question edited Apr 26, 2018 at 10:03 גלעד ברקן 24k3 gold badges29 silver badges63 bronze badges asked Apr 25, 2018 at 19:41 user7496931user7496931 6
  • 4 Which edge cases? – chevybow Commented Apr 25, 2018 at 19:42
  • 1 For example, I'm breaking the strings where the first letter in the rotatedString is found in the original string. Let's say it's waterbottle and ttlewaterb. The letter t will be found in index 2 first instead of index 7 which is where I want to slice. – user7496931 Commented Apr 25, 2018 at 19:43
  • 1 checkRotationStrings('waterbottle', 'erbottllewat'); // true should be false – Nina Scholz Commented Apr 25, 2018 at 19:48
  • 2 I would remend avoiding using string as a variable name, as it is very close to the String object. – Herohtar Commented Apr 25, 2018 at 19:53
  • 2 Here you have it stackoverflow./questions/2553522/… – algrid Commented Apr 25, 2018 at 21:52
 |  Show 1 more ment

7 Answers 7

Reset to default 5

You could use String#repeat with rotated and two as parameter and check with String#includes.

function checkRotationStrings(string, rotated) {
    return string.length === rotated.length && rotated.repeat(2).includes(string);
}

console.log(checkRotationStrings('waterbottle', 'lewaterbott'));  //  true
console.log(checkRotationStrings('waterbottle', 'bottlewater'));  //  true
console.log(checkRotationStrings('waterbottle', 'erbottllewat')); // false
console.log(checkRotationStrings('waterbottle', 'lewaterbottx')); // false
console.log(checkRotationStrings('waterbottle', 'ttlewaterb'));   // false

You could use substring and rotate until you find a match. Like this:

function checkRotationStrings(string, rotatedString) {

  let match = false;
  for (let i = 0;
    (i < string.length - 1) & !match; i++) {

    match = rotatedString.substring(i, rotatedString.length) + rotatedString.substring(0, i) === string;

  }
  return match

}


console.log(checkRotationStrings('waterbottle', 'lewaterbott')); // true
console.log(checkRotationStrings('waterbottle', 'bottlewater')); // true 
console.log(checkRotationStrings('waterbottle', 'erbottlewat')); // true 
console.log(checkRotationStrings('waterbottle', 'lewaterbottx')); // false

This is a somewhat strange solution, as it uses some only for the index parameter. But each iteration in some simply pares two strings, one which is a rotation of the first, and the other is the second one.

const checkRotationStrings = (str, rot) => 
    str.split('').some((s, i) => str.slice(i) + str.slice(0, i) == rot);

[
  ['waterbottle', 'lewaterbott'],   // true 
  ['waterbottle', 'bottlewater'],   // true 
  ['waterbottle', 'erbottllewat'],  // false  -- ORIGINAL
  ['waterbottle', 'erbottlewat'],   // true   -- CORRECTED
  ['waterbottle', 'lewaterbottx']   // false
].forEach(([s, r]) => console.log(`'${s}', '${r}': ${checkRotationStrings(s, r)}`))

You can do the following:

    checkRotationStrings(str1: string, str2: string) {

    if (str1.length !== str2.length) {

      return false;
    } else {

      for (var i = 0; i < str2.length; i++) {

        if (str2[i] === str1[0]) {

          var substring1 = str2.substring(0,i);
          var substring2 = str2.substring(i,str2.length);
          var concatWord = substring2.concat(substring1);

          if(str1 === concatWord){

            console.log(str1 + " matches " + concatWord)
            return true;

          }else{
            console.log(str1 + " not matches " + concatWord)

          }


        }

      }

      return false;

    }


  }

Stack Overflow questions often receive answers in the form of pletely new code (and/or ideas) on how to achieve the desired result. Usually, there's at least an attempt to help the questioner with their actual question, which in this case seemed to ask for some help with your code (one issue at least had to do with "slicing," as you mented).

I also love to offer new code or ideas if I particularly like it so I'm only partly critical here, but the answers so far have suffered from a plete lack of relating to the question.

There's nothing wrong with how you have conceived of checking for string rotation. You just have a couple of bugs:

First, since rotationCheck is meant to rotate string in order to pare it with rotatedString, you got the string-building reversed. It should be:

rotationCheck = result.concat(stringArr.slice(0, i)).join('');

Secondly, once you've built the rotation-check, you need to pare it with rotatedString, not string. So:

if (rotationCheck === rotatedString){

I might be late for this, but here is my solution and it include all edge cases.

function checkRotation(str1,str2){
  const char0 = str1[0];
  let ind = str2.indexOf(char0);
  while(ind>-1){
    const start = str2.substring(0,ind);
    const end = str2.substring(ind,str2.length);
    if(end+start === str1){
      return true;
    }
    ind = str2.indexOf(char0,ind+1)
  }
  return false
}
console.log(checkRotation("assads","adsass"))

Instead of trying to break it in random pieces and do different checks, you could instead do a count of the letters. This would be much simpler:

const countLetters = a => Array.prototype.reduce.call(a, (r, l) => Object.assign(r, { [l]: (r[l] || 0) + 1 }), {});

function checkRotatedString(a, b) {
  const countA = countLetters(a);
  const countB = countLetters(b);
  
  return Object.keys(countA).length === Object.keys(countB).length 
    && Object.entries(countA).every(([key, value]) => value === countB[key]);
}

// Tests
[['waterbottle', 'lewaterbott'], ['waterbottle', 'bottlewater'], ['waterbottle', 'erbottlewat'], ['waterbottle', 'lewaterbottx']]
  .forEach(a => console.log(a, checkRotatedString.apply(null, a)));

本文标签: javascriptCheck if second string is rotation of another stringStack Overflow