【问题标题】:How can I check a word is made of letters in different array如何检查一个单词是否由不同数组中的字母组成
【发布时间】:2020-02-07 22:19:37
【问题描述】:

我正在用 Vue 写一个文字游戏。

您从一串随机字符开始,您必须输入一个可由该字符串组成的单词,例如对于“ABEOHSTD”,用户可以输入“BASE”获得 4 分。

我在 .txt 文件中有一个外部单词列表(我也无法使用,但这是一个单独的问题)我需要验证单词,但我无法验证单词是否可以生成来自给定的随机字符串。

我不知道如何确保每个字母只能在数组中出现的次数使用,甚至存储分数,但我只想让第一部分正常工作。

我尝试将输入的单词和随机字符串拆分为每个字符的数组,循环遍历数组并检查用户输入的字符串中的每个字符是否包含在随机字符串数组中。

      splitUserCurrentWord = this.userAttemptedWord.split("");
      for (var i = 0; i <= splitUserCurrentWord.length; i++) {
        if (this.randomStringForGame.split("").includes(splitUserCurrentWord[i])) {
          return true;
          //i++
        }
        else {
          return false;
        }
      }
    }

目前,如果用户输入的单词中的所有字母都存在于随机字符串数组中,我希望解析为 true,但它似乎只根据数组的第一个字母解析为 true 或 false,这不是很好,因为只要第一个字母在随机字符串数组中,它就会注册为真/正确。

到目前为止整个事情的jsfiddle: https://jsfiddle.net/sk4f9d8w/

【问题讨论】:

  • return 将在第一次运行时退出 for 循环。 return true 需要在它之外。您可以尽快返回 false 并在整个过程中假设为 true

标签: javascript arrays vue.js


【解决方案1】:

您的return 语句在第一次迭代后退出循环。

一种方法是使用Array.every 验证所有字母并使用String.includes 检查该字母是否是接受字符串的一部分

const randomString = "ABEOHSTD";

console.log(isWordValid(randomString, "BASE"));
console.log(isWordValid(randomString, "BASEU"));

function isWordValid(validLetters, attemtedWord) {
  const attemptedWordSplitted = attemtedWord.split("");
  return attemptedWordSplitted.every(attemptedLetter => validLetters.includes(attemptedLetter));
}

如果您不允许多次重复使用同一个字母,则需要另一种方法,即从可接受的字母列表中删除使用过的字母

const randomString = "ABEOHSTD";

console.log(isWordValid(randomString, "BASE"));
console.log(isWordValid(randomString, "BAASE"));
console.log(isWordValid(randomString, "BASEU"));

function isWordValid(validLetters, attemptedWord) {
  const validLettersSplitted = validLetters.split("");
  const attemptedWordSplitted = attemptedWord.split("");
  return attemptedWordSplitted.every(attemptedLetter => {
    const letterIndex = validLettersSplitted.indexOf(attemptedLetter);
    if(letterIndex > -1){
      validLettersSplitted.splice(letterIndex, 1);
      return true;
    } else {
      return false
    }
  });
}

【讨论】:

    【解决方案2】:

    您的方法是正确的,您需要检查用户单词中的每个字母并检查它们是否在随机单词中。如果一个字母在随机词中,则将其从随机词中删除,这样它就不能被使用两次。 :

    let randomWord = "ABEOHSTD";
    let userWordThatFail = "BAASE";
    let userWord = "BASE";
    
    // optionnaly, uppercase both words.
    
    // we split into letters to make it easiers to process
    let randomLetters = randomWord.split('');
    let userLetters = userWord.split('');
    
    let score = 0;
    
    //we parse each letter of the user input
    userLetters.forEach((letter) => {
      // the letter exists in the random word.
      let indexOfTheCurrentLetter = randomLetters.indexOf(letter);
      // the letter exists, we remove it and increment the score.
      if(indexOfTheCurrentLetter !== -1) {
        randomLetters.splice(indexOfTheCurrentLetter, 1);
        score++;
      }
    });
    
    // the user input contains letters that are not in the random input.
    if(score < userLetters.length) {
      console.log('fail');
    } else {
      console.log('win : ' + score);
    }

    【讨论】:

    • 这对我有用,但我在控制台记录我的函数的布尔返回时遇到问题。更新的 jsfiddle:jsfiddle.net/ztxgu9Lj/1 第 40 行和第 61 行没有控制台记录任何内容,所以我看不出为什么第 16 行的条件什么都不做
    • 在这两种情况下,您都会在 console.log 执行之前返回。
    • 啊,好吧,听起来我根本不了解 return 和/或 console.log() 是如何工作的,我将不得不更多地研究它
    • @DipoOgunmodede 基本上,返回指令是您的函数要执行的最后一条指令。在那之后你就什么都没有了。请注意,您可以在同一个函数中有多个返回值。
    • 我现在已将其更改为:jsfiddle.net/ea5jx9g1 我注意到我无法控制我的 wordHasValidCharacters(),但我可以 console.log 返回 true 或 false 的实际函数,即isWordValid 在第 48 行
    【解决方案3】:

    一种简单的方法可能是为要测试的字符串中遇到的每个字符迭代有效字符列表。使用 string.includes 将属于此括号。有问题的是,每次比较的时间复杂度都是O(n_validchars * n_testchars)。对于较长的字符串,这可能是不可取的。

    JavaScript Set 对象可以在这里提供帮助。

    使用这个高阶函数(很大程度上依赖于字符串的iterable 特性),您可以为一组有效字符生成可重用函数:

    function testFor(validChars) {
      const charSet = new Set(validChars);
      return testString =>
        Array.prototype.every.call(testString, c => charSet.has(c));
    }
    
    // And to use it:
    
    const testForABC = testFor("ABC"); //returns a function
    
    console.log(testForABC("AABBCC")); //true
    console.log(testForABC("abc")); //false

    现在,因为Set 查找是O(1),我们正在查看O(n) 复杂性,其中n 是我们正在测试的字符串的长度。好多了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-28
      • 2015-12-08
      • 2015-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-07
      相关资源
      最近更新 更多