scala - 押韵算法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
}
}
解决方案
我认为没有必要逆转。
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"
推荐阅读
- sql - 用于构建 SRRS Dynamics 365 报告的 SQL 查询
- javascript - 如何检查数组中是否存在id?并获取其他值
- c - select() 是否可以为没有排队数据的套接字返回准备就绪?
- polymer - 为什么 NPM 在聚合物元素中安装另一个 node_modules 文件夹,如何解决?
- firebase - 如何从控制台获取我的特定 Firebase 或 Google Cloud 功能的调用次数?
- google-ads-api - 在虚拟页面视图上触发 Adwords 再营销列表
- ios - 为什么协议的存在元类型会丢失继承信息?
- graphics - 如何在内核空间打开 /dev/graphics/fb0?
- c++ - 使用 virtual 关键字和继承时,如何在 C++ 中确定类大小?
- javascript - 如何在 expressjs 4.x 应用程序中设置集群?