首页 > 解决方案 > 押韵算法Scala的问题

问题描述

我想制作一个方法,它将两个表示两个单词的声音(音素和元音)的字符串列表作为参数。该方法的作用是根据两个音来判断单词是否押韵。

押韵的定义:如果最后一个元音(包括)和之后的元音相同,则押韵。即使最后一个元音发音不同,单词也会押韵。只有元音会有重音(数字)

到目前为止,我的方法是反转列表,使声音以相反的顺序排列,然后添加从行首到第一个元音(包括)的所有内容。然后比较这两个列表,看看它们是否相等。请应用基本代码,我只在 scala 的初级水平。刚学完程序执行。

例1:两个词GEE和NEE会押韵,因为GEE音(“JH”,“IY1”)变成(“IY1”,“JH”),NEE音(“N”,”IY1)变成(“IY1”,“N ”)因为它们具有相同的元音,因此不应再考虑其他所有内容。

例 2:GEE 和 JEEP 两个词不会押韵,因为 GEE 音(“JH”,“IY1”)变为(“IY1”,“JH”),JEEP 音(“JH”,“IY1”,“P”)变为( “P”、“IY1”、“JH”),因为 GEE 中的第一个声音是元音,因此将其与 JEEP 中的“P”和“IY1”进行比较。

例 3:两个词 HALF 和 GRAPH 会押韵,因为 HALF 音(“HH”、“AE1”、“F”)变为(“F”、“AE1”、“HH”)和 GRAPH 音(“G”、“R”) ,”AE2”,”F”) 在这种情况下变为 (“F”,”AE2”,”R”,”G”) 虽然第一个元音有不同的重音(数字)我们忽略重音因为元音是相同的.


def isRhymeSounds(soundList1: List[String], soundList2: List[String]): Boolean={
    val revSound1 = soundList1.reverse
    val revSound2 = soundList2.reverse
    var revSoundList1:List[String] = List()
    var revSoundList2:List[String] = List()
    for(sound1 <- revSound1) {
      if(sound1.length >= 3) {
        val editVowel1 = sound1.substring(0,2)
        revSoundList1 = revSoundList1 :+ editVowel1
      }
      else {
        revSoundList1 = revSoundList1 :+ sound1
      }
    }
    for(sound2 <- revSound2) {
      if(sound2.length >= 3) {
        val editVowel2 = sound2.substring(0, 2)
        revSoundList2 = revSoundList2 :+ editVowel2
      }
      else {
        revSoundList2 = revSoundList2 :+ sound2
      }
    }
    if(revSoundList1 == revSoundList2){
      true
    }
    else{
      false
    }
  }

标签: scala

解决方案


我认为没有必要逆转。

def isRhyme(sndA :List[String], sndB :List[String]) :Boolean = {
  val vowel = "[AEIOUY]+".r
  sndA.foldLeft(""){case (res, s) => vowel.findPrefixOf(s).getOrElse(res+s)} ==
    sndB.foldLeft(""){case (res, s) => vowel.findPrefixOf(s).getOrElse(res+s)}
}

解释

  • "[AEIOUY]+".r- 这是一个正则表达式(这就是.r部分),意思是“String一个或多个这些字符中的一个”。换句话说,任何大写字母元音的组合。
  • findPrefixOf()- 这将返回与正则表达式匹配的测试字符串的第一部分。所以vowel.findPrefixOf("AY2")返回Some("AY"),因为前两个字母匹配正则表达式。并vowel.findPrefixOf("OFF")返回Some("O"),因为只有第一个字母与正则表达式匹配。但vowel.findPrefixOf("BAY")返回None是因为字符串不以任何指定字符开头。
  • getOrElse()- 这会打开一个Option. 所以Some("AY").getOrElse("X")返回"AY",和Some("O").getOrElse("X")返回"O",但是None.getOrElse("X")返回"X"是因为值里面没有任何东西,None所以我们使用 OrElse 默认返回值。
  • foldLeft()()- 这需要一组元素,并从“左侧”开始,将它们“折叠”在一起,直到获得最终结果。

所以,考虑如何List("HH", "AE1", "F", "JH", "IY1", "P")处理。

res    s     result
===    ===   ======
""     HH    ""+HH   //s doesn't match the RE so default res+s
HH     AE1   AE      //s does match the RE, use only the matching part
AE     F     AE+F    //res+s
AEF    JH    AEF+JH  //res+s
AEFJH  IY1   IY      //only the matching part
IY     P     IY+P    //res+s

final result: "IYP"

推荐阅读