【问题标题】:why is my compare evaluating to false为什么我的比较评估为假
【发布时间】:2016-08-10 05:00:20
【问题描述】:

我是 JavaScript 新手。我正在编写一个函数来检查是否可以通过最多一对字符的交换从中获得回文。我遇到的一个问题是我的对象在警报中看起来是正确的,但无论我使用什么运算符,它都被评估为假。我附上了小提琴

http://jsfiddle.net/sQx4H/89/

我做错了什么?

function isOneSwapEnough() {
inputString = 'aabaa'
    var inputStringArray = inputString.split();
    if (isPalandrome(inputStringArray))
    {
        return true;
    }
    //if we made it this far then the string is not a palendrone yet.
    var newCharArray;
    for (var j =0; j<inputStringArray.length; j++)
    {
        newCharArray = inputStringArray; 
        for (var k =0; k<inputStringArray.length; k++)
        {
            var tempChar =  inputStringArray[j];
            newCharArray[j] = newCharArray[k];
            newCharArray[k] = tempChar;

            if (isPalandrome(newCharArray))
            {
                return true;
            }
        }
    }
    return false;
}

function isPalandrome(testString)
{
    var firstcheck = [];
    // already a char array... var testStringArray = testString.split();
    //check if already a palendrone
    for (var i =0; i<testString.length; i++)
    {

        firstcheck[testString.length-(i+1)] = testString[i];
        //console.log(testString[i]);
        //console.log(firstcheck[testString.length-i]);
    }
    //console.log(testString);
    //console.log(firstcheck);
    //alert("1: " + typeof  testString);
    //alert("2: " + typeof  firstcheck);
    alert("condition " + firstcheck.valueOf() === testString.valueOf())
    if ( firstcheck.valueOf() == testString.valueOf())
    {
        return true;
    }
}

【问题讨论】:

  • 只是让你知道,'aabaa'.split() //=&gt; ['aabaa'] 不是['a', 'a', 'b', 'a', 'a'],就像你可能期待的那样。如果是这样的话,你可能想试试.split('')
  • 您的回文是否允许使用空格、逗号或其他特殊字符?
  • alert("condition " + firstcheck.valueOf() === testString.valueOf()) 行将始终返回 false。它将"condition"firstCheck.valueOf() 连接起来,并将其与testString.valueOf() 进行比较,testString.valueOf() 始终为false

标签: javascript arrays string character


【解决方案1】:

代码审查

除了我在您的问题上留下的评论之外,您的isPalindrome 程序还有很多事情要做;我的 cmets 内联……

// `isPalindrome` is a nice function name
// `testString` is a terrible parameter name,
// especially since you're passing in an array
function isPalandrome(testString)
{
    // unclear variable name
    var firstcheck = [];

    // by the end of this loop, firstcheck will be a testString in reverse
    // ok, got it
    for (var i = 0; i<testString.length; i++)
    {
        firstcheck[testString.length-(i+1)] = testString[i];
    }
    // the short version of this code is
    var firstcheck = testString.slice(0).reverse()

    // this doesn't do what you think it does
    // `[1,2,3] === [1,2,3]` is false in javascript
    // you cannot compare arrays like that
    if ( firstcheck.valueOf() == testString.valueOf())
    {
        // `if (condition) { return true }` is bad code
        // just use `return condition`
        return true;
    }
    // don't worry, you don't have to compare arrays to check for your palindromes
}

快速而肮脏的解决方案

如果输入字符串中有空格或特殊字符,这将不起作用,但您的问题没有说明此类标准。所以也许这就是你要找的全部。

您确实必须比较数组来检测回文。

function isPalindrome(str) {
  return str === str.split('').reverse().join('')
}

console.log(isPalindrome('aabaa')) // true
console.log(isPalindrome('racecar')) // true
console.log(isPalindrome('risetovotesir')) // true
console.log(isPalindrome('sorry but not a palindrome')) // false

字符交换

至于角色交换位,你手上有点问题。什么是合格的掉期?角色只能与近邻交换位置吗?或者任意两个字符可以互换?

input | posssibile swaps
------+------------------------------------------------------------
a     |
ab    | ba
abc   | bac cba acb
abcd  | bacd cbad dbca acbd adcb abdc
abcde | bacde cbade dbcae ebcda acbde adcbe aecdb abdce abedc abced

如您所见,可能的交换增长很快。总可能的掉期可以计算为

((n - 1) * n / 2), where n = length of input

例如,长度为 5 的字符串将有 10 个可能的交换……

((5 - 1) * 5 / 2) = 10

20 的字符串长度将有 190 个可能的交换。 (相关:在这种情况下,ntriangular number

你能想出一个基本程序来生成和检查每个可能的交换吗?

无论哪种方式,我仍然认为您不需要数组。我将首先编写一个通用的charSwap 过程,该过程返回一个带有交换字符的字符串。可能是这样的……

function charSwap(str, x, y) {
  function slice(from,to) {
    return str.substring(from,to)
  }
  let a = str[x], b = str[y]
  return slice(0,x) + b + slice(x+1,y) + a + slice(y+1)
}

console.log(charSwap('abcde',0,1)) // bacde 
console.log(charSwap('abcde',0,2)) // cbade 
console.log(charSwap('abcde',0,3)) // dbcae 
console.log(charSwap('abcde',0,4)) // ebcda 

console.log(charSwap('abcde',1,2)) // acbde 
console.log(charSwap('abcde',1,3)) // adcbe 
console.log(charSwap('abcde',1,4)) // aecdb 

console.log(charSwap('abcde',2,3)) // abdce 
console.log(charSwap('abcde',2,4)) // abedc 

console.log(charSwap('abcde',3,4)) // abced 

我敢肯定,到最后你可能会在那里找到一种模式。然后我会在isOneSwapEnough 中使用charSwap。不过,我将由您来为它编写循环。我可以给你一点框架代码来开始……

function isOneSwapEnough(str) {
  // setup loop
  // let x and y be variables for character indexes to swap
  // begin loop
    if (isPalindrome(charSwap(str, x, y)))
      return true
    else
      // continue loop
  // end loop
  return false
}

【讨论】:

  • 我真的很喜欢你的解决方案,特别是制作了一个交换字符串中两个字符的函数以使代码更简单。
  • @kamoroso94 很高兴你喜欢它。降低复杂性(使代码更简单)在编写健全的代码方面起着主导作用。
【解决方案2】:

我认为这可能与您尝试进行直接数组比较有关。尽管我不确定它是否是您要寻找的,但下面的方法将变为 true。

jsfiddle

if (JSON.stringify(firstcheck) == JSON.stringify(testString)) {
    return true;
}

【讨论】:

    猜你喜欢
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多