使用scala查找所有可能拼字的最佳方法是什么?

使用scala查找所有可能拼字的最佳方法是什么?,scala,Scala,使用scala查找所有可能拼字的最佳方法是什么 有一个可能的单词和字母的字典,可以用来组合这些单词。 例如,有一本字典[“大厅”、“酒吧”、“粗体”、“鲍比”]和字母“博尔布莱德”。结果应该是生成所有可能字母组合的列表。然后过滤掉真正的单词。一定要使用迭代器,以防止炸毁您的计算机。由于迭代器,它不是一个纯函数式的解决方案,因为它们具有可变状态,但它将相当有效 val letters = "borbly" val dictionary = Set("lobby", "bar", "bold", "

使用scala查找所有可能拼字的最佳方法是什么

有一个可能的单词和字母的字典,可以用来组合这些单词。

例如,有一本字典
[“大厅”、“酒吧”、“粗体”、“鲍比”]
和字母
“博尔布莱德”
。结果应该是生成所有可能字母组合的列表。然后过滤掉真正的单词。一定要使用
迭代器
,以防止炸毁您的计算机。由于迭代器,它不是一个纯函数式的解决方案,因为它们具有可变状态,但它将相当有效

val letters = "borbly"
val dictionary = Set("lobby", "bar", "bold", "bobby")
val possibilities = Iterator.range(1, letters.length + 1).flatMap(letters.combinations).flatMap(_.permutations)
possibilities.filter(dictionary).toList
或者,你也可以用另一种方式,这看起来不那么酷,但如果你有很多字母,可能会快得多:

import scala.annotation.tailrec

@tailrec
def canBeMade(word: String, letters: String): Boolean =
  word.isEmpty || (letters.contains(word.head) && canBeMade(word.tail, letters.replaceFirst(word.head.toString, "")))

dictionary.filter(canBeMade(_, letters))

生成所有可能字母组合的列表。然后过滤掉真正的单词。一定要使用
迭代器
,以防止炸毁您的计算机。由于迭代器,它不是一个纯函数式的解决方案,因为它们具有可变状态,但它将相当有效

val letters = "borbly"
val dictionary = Set("lobby", "bar", "bold", "bobby")
val possibilities = Iterator.range(1, letters.length + 1).flatMap(letters.combinations).flatMap(_.permutations)
possibilities.filter(dictionary).toList
或者,你也可以用另一种方式,这看起来不那么酷,但如果你有很多字母,可能会快得多:

import scala.annotation.tailrec

@tailrec
def canBeMade(word: String, letters: String): Boolean =
  word.isEmpty || (letters.contains(word.head) && canBeMade(word.tail, letters.replaceFirst(word.head.toString, "")))

dictionary.filter(canBeMade(_, letters))

似乎有点拼写错误,正如@stefanobaghino所说:“粗体”不应该出现在结果中。我的想法是为每个单词和输入字母构建映射Char->Occurs,并使用这些映射查找加扰词:

def chars2Occurs(chars: Seq[Char]): Map[Char, Int] = {
  chars.foldLeft(Map.empty[Char, Int]) {
    case (map, ch) =>
      val occurs = map.get(ch).getOrElse(0) + 1
      map + ((ch -> occurs))
  }
}
def getScrambleWords(words: Seq[String], letters: Array[Char]): Seq[String] = {
  val etalon: Map[Char, Int] = chars2Occurs(letters)
  val word2Occur: Seq[(String, Map[Char, Int])] = words.map { word =>
    (word, chars2Occurs(word))
  }
  val result: Seq[String] = word2Occur.flatMap { case (word, map) =>
    val isOk = map.forall { case (c, n) =>
      etalon.get(c) match {
        case Some(k) => k >= n
        case None => false
      }
    }
    if (isOk) Some(word) else None
  }
  result
}

似乎有点拼写错误,正如@stefanobaghino所说:“粗体”不应该出现在结果中。我的想法是为每个单词和输入字母构建映射Char->Occurs,并使用这些映射查找加扰词:

def chars2Occurs(chars: Seq[Char]): Map[Char, Int] = {
  chars.foldLeft(Map.empty[Char, Int]) {
    case (map, ch) =>
      val occurs = map.get(ch).getOrElse(0) + 1
      map + ((ch -> occurs))
  }
}
def getScrambleWords(words: Seq[String], letters: Array[Char]): Seq[String] = {
  val etalon: Map[Char, Int] = chars2Occurs(letters)
  val word2Occur: Seq[(String, Map[Char, Int])] = words.map { word =>
    (word, chars2Occurs(word))
  }
  val result: Seq[String] = word2Occur.flatMap { case (word, map) =>
    val isOk = map.forall { case (c, n) =>
      etalon.get(c) match {
        case Some(k) => k >= n
        case None => false
      }
    }
    if (isOk) Some(word) else None
  }
  result
}

这里还有另一种方法——检查字典中的每个单词,仅在以下情况下保留:1)单词长度不超过手上字母的计数,2)从手上字母中删除单词中的每个字符后剩余字母的计数等于原始字母数减去单词长度:

val letters = "borblyd".toSeq
val letterCount = letters.size

val dict = Set("lobby", "bar", "bold", "bobby")

dict.filter( word => 
  word.length <= letterCount &&
  word.foldLeft(letters)(
    (lettersRemained, ch) => lettersRemained.diff(Seq(ch))
  ).size == letterCount - word.length
)
// res1: scala.collection.immutable.Set[String] = Set(lobby, bold)
val letters=“borblyd”toSeq
val letterCount=字母数。大小
val dict=Set(“大厅”、“酒吧”、“粗体”、“波比”)
dict.filter(word=>
字长字母保留差异(序号(ch))
).size==letterCount-word.length
)
//res1:scala.collection.immutable.Set[String]=Set(大厅,粗体)

还有另一种方法——检查字典中的每个单词,只有在以下情况下才保留:1)单词长度不超过手边字母的计数,2)从手边字母中删除单词中的每个字符后剩余字母的计数等于原始字母数减去单词长度:

val letters = "borblyd".toSeq
val letterCount = letters.size

val dict = Set("lobby", "bar", "bold", "bobby")

dict.filter( word => 
  word.length <= letterCount &&
  word.foldLeft(letters)(
    (lettersRemained, ch) => lettersRemained.diff(Seq(ch))
  ).size == letterCount - word.length
)
// res1: scala.collection.immutable.Set[String] = Set(lobby, bold)
val letters=“borblyd”toSeq
val letterCount=字母数。大小
val dict=Set(“大厅”、“酒吧”、“粗体”、“波比”)
dict.filter(word=>
字长字母保留差异(序号(ch))
).size==letterCount-word.length
)
//res1:scala.collection.immutable.Set[String]=Set(大厅,粗体)

添加注释以提供(非常低效的)基线解决方案:
def words(字母:String,dictionary:Set[String]):Seq[String]=(1到字母.长度).flatMap(字母.组合()).flatMap().排列).过滤器(dictionary)
。但是请注意,
bold
不是有效解决方案的一部分(可能是一个输入错误?@stefanobaghino您关于
bold
的看法是正确的,这是一个输入错误。添加注释以提供一个(非常低效的)基线解决方案:
def words(字母:String,字典:Set[String]):Seq[String]=(1到字母.长度)。flatMap(字母.组合()).flatMap(u.排列).过滤器(字典)
。但是请注意,
bold
不是有效解决方案的一部分(可能是一个输入错误?@stefanobaghino关于
bold
,这是一个输入错误。关于
“bold”
,你是对的。我已经解决了这个问题。关于
“bold”你是对的
。我已经解决了这个问题。