【问题标题】:Bulls & Cows in JavaScriptJavaScript 中的牛与牛
【发布时间】:2015-11-04 05:19:24
【问题描述】:

最后一天,我一直在努力应对 LeetCode 'Bulls & Cows' 挑战。我是一名正在学习算法的前端开发人员,我很难理解用 Java 实现的逻辑块并将其移植到我的 JavaScript 解决方案中。

工作的Java Solution

public String getHint(String secret, String guess) {
    int bulls = 0;
    int cows = 0;
    int[] numbers = new int[10];
    for (int i = 0; i<secret.length(); i++) {
        int s = Character.getNumericValue(secret.charAt(i));
        int g = Character.getNumericValue(guess.charAt(i));
        if (s == g) bulls++;
        else {
            if (numbers[s] < 0) cows++;
            if (numbers[g] > 0) cows++;
            numbers[s] ++;
            numbers[g] --;
        }
    }
    return bulls + "A" + cows + "B";
}

具体来说,我很难理解以下功能块:

else {
    if (numbers[s] < 0) cows++;
    if (numbers[g] > 0) cows++;
    numbers[s] ++;
    numbers[g] --;
}

这是我推导出的 JS 解决方案,它通过了除 secret = 1807guess = 7810 之外的所有(已知)测试用例:

var getHint = function(secret, guess) {
  var bulls = 0;
  var cows = 0;
  var nums = [];
  var checkNums = function(num) {
    if(nums.length) {
      for (var l = 0; l < nums.length; l++) {
        if(num === nums[l]) {
          return false;
        } else {
          nums.push(num);
          cows++;

          return true;
        }
      } else {
        // /nums/ is equal to 0
        cows++;
        nums.push(num);
      }
    }
  };

  if(guess) {
    // iterate over the secret to compare it to the guess
    for (var i = 0; i < secret.length; i++) {
      // compare the related location to check for bulls
      if(secret[i] === guess[i]) {
        bulls++;
        nums.push(guess[i]);
      } else {
        // We didnt find a bull, lets check the /guess/ for cows
        for(var j = 0; j < guess.length; j++) {
          // We have a match, what should we do with it?
          if (secret[i] === guess[j]) {

              checkNums(guess[j]);

          }
        }
      }
    }
  }

  return bulls + "A" + cows + "B";
};

我得到的失败测试用例是:

Input:
"1807"
"7810"

Output:
"1A2B"

Expected:
"1A3B"

我很想更好地了解如何更好地复制优雅的 Java 解决方案,以及我可以使这个 JS 解决方案更简洁(和工作)的任何方法。我越是反对这个,for 循环和if 块我写的越多,我只知道我在朝着错误的方向前进。

这是我的解决方案的 JSBin:

http://jsbin.com/jibusa/edit?js,console

感谢您的帮助。

【问题讨论】:

  • 代码有什么问题?你有错误吗?结果不正确?
  • @MarkC。更新了 LeetCode 失败的测试用例响应的答案。
  • 需要看看在输出什么,应该输出什么。
  • +1 用于正确提出的问题。你展示了你做了什么以及你遇到了什么问题。现在,如果我的 javascript 不是那么差就好了。
  • 啊,Mastermind!那个 jsbin 正在输出预期的 "1A0B"..?

标签: javascript java algorithm


【解决方案1】:

这是 Java 解决方案的虚拟副本。对 JavaScript charCodeAt() 的小调整是为了说明它与 Java Character.getNumericValue 的差异。

function getHint(secret, guess) {
  var bulls = 0;
  var cows = 0;
  var numbers = new Array(10);
  for (var i=0; i<10; i++){
    numbers[i] = 0;
  }
  for (var i = 0; i<secret.length; i++) {
    var s = secret.charCodeAt(i) - 48;
    var g = guess.charCodeAt(i) - 48;
    if (s == g) bulls++;
    else {
      if (numbers[s] < 0) cows++;
      if (numbers[g] > 0) cows++;
      numbers[s] ++;
      numbers[g] --;
    }
  }
  return bulls + "A" + cows + "B";
}

console.log(getHint("1807","7810"));

【讨论】:

  • 感谢您提供有效示例的回复。看到移植到 JS 的解决方案确实让它点击了。
【解决方案2】:

numbers[x] 表示到目前为止已扫描的秘密和猜测前缀中不匹配的xs 的数量。正数表示秘密中有盈余。负数表示猜测有余。

代码块

if (numbers[s] < 0) cows++;
if (numbers[g] > 0) cows++;
numbers[s] ++;
numbers[g] --;

翻译成英文如下。如果s(秘密中的当前字母)在猜测中有剩余,则它与猜测中的前一个字母匹配,因此增加奶牛的数量。如果猜测中的当前字母g 在秘密中有盈余,则它与秘密中的前一个字母相匹配,因此增加奶牛的数量。 numbers[s] ++ 非常巧妙:它要么删除猜测中的多余字母,要么在秘密中创建多余的字母。同样,numbers[g] -- 要么删除秘密中的多余字母,要么在猜测中创建一个。

【讨论】:

  • 非常感谢您花时间解释。这为我揭开了逻辑的神秘面纱。
【解决方案3】:

你为什么不这样做?...

  var getHint = function(secret, guess) {
  var bulls = 0;
  var cows = 0;
  var nums = [];
  var length = 10;
  var s;
  var g;
  for (var i2=0; i2 < length; i2++) {nums[i2] = 0;}
  for (var i=0; i < secret.length; i++) {
    s = Number(String(secret).charAt(i));
    g = Number(String(guess).charAt(i));

    if(s == g)bulls++;
    else{
      if(nums[s] < 0)cows++;
      if(nums[g] > 0) cows++;
      nums[s]++;
      nums[g]--;

    }
  }
  return bulls + "A" + cows + "B";
};

console.log(getHint("1123", "0111"));
console.log(getHint("1807", "7810"));

输出:

"1A1B"
"1A3B"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    相关资源
    最近更新 更多