检查两个字符串是否在旋转方向上彼此相等

Check if two strings are rotationally equal to each other

我需要您在以下方面的帮助:我正在尝试开发一个函数,该函数应该检查两个参数字符串是否在旋转方向上彼此相等。比如,如果我们顺时针旋转两次,'abcd' 会变成 'cdab',所以如果上面的字符串作为参数提供,我的函数应该是 return 'true'。我最初解决这个问题的想法是检查两个字符串中每个字符之间的常量移位是否存在,所以我尝试了

function areRotEq (str1, str2) {
    var shift = null;
    for(char of str1){
        if(!shift) shift = str2.indexOf(char);
        else if (shift != str2.indexOf(char)) return false
    }
    return true;
}

但是,它甚至无法正确评估上面的简单字符串 returns 'false'。如果您能指出正确的方向来弄清楚为什么我的代码不起作用,或者建议一些更有效的方法来解决我的问题,我们将不胜感激。 提前致谢!

这是另一种方法:

首先,进行 "quick" 检查绝对正确或错误。

然后,检查str2 中str1 的第一个字符。此时将其拆分并将第一部分粘贴到最后一部分之后。两者相等则为轮换。

警告:这不适用于多次包含相同字符的字符串。

function areRotEq (str1, str2) {
    if (str1 === str2) return true;
    if (str1.length !== str2.length) return false;
    
    var start2 = str2.indexOf(str1[0]);
    if (start2 === -1) return false;

    return str1 === str2.slice(start2) + str2.slice(0, start2)
}

console.log(
  areRotEq("abcd", "abcd"),
  areRotEq("abcd", "acdb"),
  areRotEq("abcd", "dabc"),
  areRotEq("dcab", "abdc")
);

您可以使用 for-loop 并从 0 开始递增第一个字符串的索引,并从其长度递减第二个字符串的索引。使用这两个索引,您可以比较字符串中的特定字符。

function areRotEq(str1, str2) {
  for (var a = 0; a < str1.length; a++) {
    if (str1.charAt(a) != str2.charAt(str2.length - (a + 1))) {
      return false;
    }
  }
  return true;
}
console.log(areRotEq("abcd", "dcba"));

我就是这样解决这个问题的。我基本上一直在移动 str1 直到它与 str2 匹配,或者直到我尝试了每个移动组合。

function areRotEq (str1, str2) {
    for(let i=0; i<str1.length; ++i) {
        // shift str1
        str1 = str1[str1.length-1] + str1.substring(0, str1.length-1);
        if(str1 === str2) {
            return true;
        }
    }
    return false;
}


console.log(
    areRotEq('12345', '34512'), // true
    areRotEq('12345', '23451'), // true
    areRotEq('12345', '12354') // false
);

我会对出现超过 1 个字母的字符串使用 findIndex 并将它们删除

function areRotEq(str1, str2) {
    const str1Array = str1.split('');
    const str2Array = str2.split('');
    for (let i = str1Array.length - 1; i >= 0 ; i--) {
        const index = str2Array.findIndex(letter => letter === str1Array[i]);
        if (index === -1) {
            return false;
        }
        str2Array.splice(index, 1);
    }
    return str2Array.length === 0;
}
console.log(areRotEq('abcda', 'cdaba'));

你可以将字符串呈现为一副牌组结构,即一副字符牌组(可以将元素放在集合的开头和末尾,就像一副纸牌一样)。非常方便的是,JavaScript 数组提供了开箱即用的功能(通过队列和堆栈的方法 shiftpush。基本上,我们取出字符串中的第一个字符并将其移动在最后一个位置并进行新的相等性检查。我们重复此操作,直到字符串移动(或旋转)到其初始值:

function areRotEq(str1, str2) {
    if (str1.length !== str2.length) {
        return false;
    }

    if (str1 === str2) {
        return true;
    }

    let str1Array = str1.split('');
    let tempEl;

    for (let i = 0; i < str1.length - 1; i++) {
        tempEl = str1Array.shift();
        str1Array.push(tempEl);

        if (str1Array.join('') === str2) {
            return true;
        }
    }

    return false;
}

您的解决方案无效,因为您计算的班次不正确,解决方法如下:

function areRotEq (str1, str2) {
    var shift = null;
    let i = 0;
    for(char of str1){
        if(!shift) shift = str2.indexOf(char);
        else {
            const currentShift = Math.abs(str2.indexOf(char) - i);
            if (shift != currentShift) return false;
        } 
        i++;
    }
    return true;
}

这是连接技巧的解决方案:

function areRotEq (str1, str2) {
    if (str1.length != str2.length) return false;
    return (str1 + str1).indexOf(str2) != -1;
}

如果两个字符串互相旋转,则一个字符串存在于另一个字符串中,并且连续重复两次!这个逻辑的实现很容易:

function rotEq(str1, str2) {
  var str = str1 + str1;
  return str.includes(str2);
}

console.log(rotEq("abcd", "bcda"));
console.log(rotEq("abcde", "cdeab"));
console.log(rotEq("abcd", "acdb"));

此函数将检查两个字符串是否在旋转方向上彼此相等,如果两个字符串在旋转方向上相等,则它将 return 需要旋转的元素数才能使它们相等。

const areRotEq= (first, second) => {
  let result = -1;
  const lengthUnmatch = first.length != second.length
  if (lengthUnmatch)
    return result
  else
   const temp = second.concat(second)
    if (temp.includes(first))
        return temp.indexOf(first) 
    else
        return result 
 }

此函数将检查两个字符串是否彼此旋转相等,如果两个字符串旋转相等则它将 return 为真,否则将为 return 假。

const areRotEq= (first, second) => {
  let result = false;
  const lengthUnmatch = first.length != second.length
  if (lengthUnmatch)
    return result
  else
   const temp = second.concat(second)
    if (temp.includes(first))
        return true 
    else
        return result 
 }