如何在字符串中找到得分最高的单词?
How to find a highest scoring word inside a string?
我又在做一些 CodeWars 挑战了。
这个我有问题:
"给定一串单词,你需要找到得分最高的单词。
单词的每个字母根据其在字母表中的位置得分:a = 1、b = 2、c = 3 等
您需要return得分最高的单词作为字符串。
如果两个词得分相同,return原始字符串中最早出现的词。
所有字母均为小写且所有输入均有效。
我已经查过SO上的解决方案了,用了一个人的思路(虽然我也改了一点)。
还是不行。
有什么想法吗?
object Scoring {
def high(s: String): String = {
var max = 0
var whichWord = 0
var x = 0
var y = new Array[Int](100)
for(word <- s.split(" ")){
for(letter <- word) letter match{
case 'a' => y(x)+=1
case 'b' => y(x)+=2
case 'c' => y(x)+=3
case 'd' => y(x)+=4
case 'e' => y(x)+=5
case 'f' => y(x)+=6
case 'g' => y(x)+=7
case 'h' => y(x)+=8
case 'i' => y(x)+=9
case 'j' => y(x)+=10
case 'k' => y(x)+=11
case 'l' => y(x)+=12
case 'm' => y(x)+=13
case 'n' => y(x)+=14
case 'o' => y(x)+=15
case 'p' => y(x)+=16
case 'q' => y(x)+=17
case 'r' => y(x)+=18
case 's' => y(x)+=19
case 't' => y(x)+=20
case 'u' => y(x)+=21
case 'v' => y(x)+=22
case 'w' => y(x)+=23
case 'x' => y(x)+=24
case 'y' => y(x)+=25
case 'z' => y(x)+=26
}
x +=1
}
for(x <- 0 until y.length){
if(y(x) > max)
{
max = y(x)
whichWord = x
}
}
s.substring(whichWord-1, whichWord)
}
}
测试如下:
测试结果:
RandomTestSpec
high("ykvhorsqve kfkq jhjibercdptf efevxax ccr vnsmumqby jwhxvamegupfcj lierziuopbcsutm") should return "lierziuopbcsutm"
Test Failed
"[s]" was not equal to "[lierziuopbcsutm]"
Stack Trace
Completed in 34ms
high("skwwwm") should return "skwwwm"
Test Failed
String index out of range: -1
Stack Trace
Completed in 1ms
high("a") should return "a"
Test Failed
String index out of range: -1
Stack Trace
Completed in 1ms
high("gykoialocufuc wcdwuxksqk bvapztcnqwx") should return "bvapztcnqwx"
Test Failed
"[y]" was not equal to "[bvapztcnqwx]"
Stack Trace
Completed in 1ms
high("gdhfoonwtih xbvsiaqhsesl obrndpz nxt inkklyo lf oyoadxqhuys lbqr oxbqq bopalqknjxvpg") should return "oyoadxqhuys"
Test Failed
"o[]" was not equal to "o[yoadxqhuys]"
Stack Trace
Completed in 1ms
high("bbzlmqhsypato pfufsi ryu oboklfa iigha h m") should return "bbzlmqhsypato"
Test Failed
String index out of range: -1
Stack Trace
Completed in 1ms
high("dbtfwvhk kadarmvldjhkx dgxffryldcxodtn hoffibiayxriqe gtqzeuywpgc nqlgvudy") should return "dgxffryldcxodtn"
Test Failed
"[b]" was not equal to "[dgxffryldcxodtn]"
Stack Trace
Completed in 1ms
high("vhyxdefryeznlkz fcaenzsnoxsn phdqu zjbbbybjmdn dbfhvxwnusz dqbqskfbwuomzsl ogsdioilk") should return "vhyxdefryeznlkz"
Test Failed
String index out of range: -1
Stack Trace
high("yqbzfuprmezbgee yxsewucg u") should return "yqbzfuprmezbgee"
Test Failed
String index out of range: -1
Stack Trace
Completed in 1ms
high("zifha") should return "zifha"
Test Failed
String index out of range: -1
Stack Trace
high("moroydyolj tcfpokvitzwzor rnzeacau") should return "tcfpokvitzwzor"
Test Failed
"[m]" was not equal to "[tcfpokvitzwzor]"
Stack Trace
Completed in 1ms
high("jhieih m") should return "jhieih"
Test Failed
String index out of range: -1
Stack Trace
high("yn ounbzw wk eldpjyikbfs nzm") should return "eldpjyikbfs"
Test Failed
"[ ]" was not equal to "[eldpjyikbfs]"
Stack Trace
Completed in 1ms
在 Scala 中,使用集合中提供的函数更容易/(更好)。
在你的例子中 - 这里有一个可能性:
首先要添加得分你可以使用这个:
"hello".map(_.toInt).sum // 532
这 returns 所有字符的总和作为 Int 值 (a=97; ...; z=122)
要找到可以使用 foldLeft
的最高权重,从“”开始。
scala> List("a", "ab","ba").foldLeft("")((a,b)=> higher(a,b))
res10: String = ab
这里是完整的 higher
函数:
def higher(a:String, b:String):String=
if(a.map(_.toInt).sum >= b.map(_.toInt).sum) a else b
有很多很酷的可能性可以用集合函数来做到这一点——不要使用可变状态!这是切换到 Scala 的一个重要原因。
更新:玩完 https://www.codewars.com 我发现了一个错误和更短的解决方案:
s.split(" ").map(w => (w, w.map(_.toInt - 96).sum)).maxBy(_._2)._1
假设您的输入是
val str = "ykvhorsqve kfkq jhjibercdptf efevxax ccr vnsmumqby jwhxvamegupfcj lierziuopbcsutm"
您可以将每个字符的值维护为
val charMap = Map(
'a' -> 1,
'b' -> 2,
'c' -> 3,
'd' -> 4,
'e' -> 5,
'f' -> 6,
'g' -> 7,
'h' -> 8,
'i' -> 9,
'j' -> 10,
'k' -> 11,
'l' -> 12,
'm' -> 13,
'n' -> 14,
'o' -> 15,
'p' -> 16,
'q' -> 17,
'r' -> 18,
's' -> 19,
't' -> 20,
'u' -> 21,
'v' -> 22,
'w' -> 23,
'x' -> 24,
'y' -> 25,
'z' -> 26,
)
然后您可以添加一个简单的函数来计算每个单词的计数
def countOfWord(str : String): Int = str.map(charMap).sum
然后对您的输入字符串应用以下操作 str
将为您获取所需的结果
str.split(" ").map(word => (word, countOfWord(word))).maxBy(_._2)._1
这会为您获取所需的输出
res0: String = lierziuopbcsutm
val words = s.split(" ")
val scores = words.map(w => (w, w.map(_ - 'a' + 1).sum))
val max = scores.maxBy(_._2)._2
scores.find(_._2 == max).get._1
这个呢?
object HighestWord extends App {
val inputStr: String = "ykvhorsqve kfkq jhjibercdptf efevxax ccr vnsmumqby jwhxvamegupfcj lierziuopbcsutm"
val answer = inputStr.split(" ").map {
str: String =>
val sum = str.map { chr: Char =>
chr.toInt
}.sum
(str, sum)
}.maxBy(_._2)._1
println(answer)
}
我又在做一些 CodeWars 挑战了。
这个我有问题:
"给定一串单词,你需要找到得分最高的单词。
单词的每个字母根据其在字母表中的位置得分:a = 1、b = 2、c = 3 等
您需要return得分最高的单词作为字符串。
如果两个词得分相同,return原始字符串中最早出现的词。
所有字母均为小写且所有输入均有效。
我已经查过SO上的解决方案了,用了一个人的思路(虽然我也改了一点)。
还是不行。
有什么想法吗?
object Scoring {
def high(s: String): String = {
var max = 0
var whichWord = 0
var x = 0
var y = new Array[Int](100)
for(word <- s.split(" ")){
for(letter <- word) letter match{
case 'a' => y(x)+=1
case 'b' => y(x)+=2
case 'c' => y(x)+=3
case 'd' => y(x)+=4
case 'e' => y(x)+=5
case 'f' => y(x)+=6
case 'g' => y(x)+=7
case 'h' => y(x)+=8
case 'i' => y(x)+=9
case 'j' => y(x)+=10
case 'k' => y(x)+=11
case 'l' => y(x)+=12
case 'm' => y(x)+=13
case 'n' => y(x)+=14
case 'o' => y(x)+=15
case 'p' => y(x)+=16
case 'q' => y(x)+=17
case 'r' => y(x)+=18
case 's' => y(x)+=19
case 't' => y(x)+=20
case 'u' => y(x)+=21
case 'v' => y(x)+=22
case 'w' => y(x)+=23
case 'x' => y(x)+=24
case 'y' => y(x)+=25
case 'z' => y(x)+=26
}
x +=1
}
for(x <- 0 until y.length){
if(y(x) > max)
{
max = y(x)
whichWord = x
}
}
s.substring(whichWord-1, whichWord)
}
}
测试如下:
测试结果:
RandomTestSpec
high("ykvhorsqve kfkq jhjibercdptf efevxax ccr vnsmumqby jwhxvamegupfcj lierziuopbcsutm") should return "lierziuopbcsutm"
Test Failed
"[s]" was not equal to "[lierziuopbcsutm]"
Stack Trace
Completed in 34ms
high("skwwwm") should return "skwwwm"
Test Failed
String index out of range: -1
Stack Trace
Completed in 1ms
high("a") should return "a"
Test Failed
String index out of range: -1
Stack Trace
Completed in 1ms
high("gykoialocufuc wcdwuxksqk bvapztcnqwx") should return "bvapztcnqwx"
Test Failed
"[y]" was not equal to "[bvapztcnqwx]"
Stack Trace
Completed in 1ms
high("gdhfoonwtih xbvsiaqhsesl obrndpz nxt inkklyo lf oyoadxqhuys lbqr oxbqq bopalqknjxvpg") should return "oyoadxqhuys"
Test Failed
"o[]" was not equal to "o[yoadxqhuys]"
Stack Trace
Completed in 1ms
high("bbzlmqhsypato pfufsi ryu oboklfa iigha h m") should return "bbzlmqhsypato"
Test Failed
String index out of range: -1
Stack Trace
Completed in 1ms
high("dbtfwvhk kadarmvldjhkx dgxffryldcxodtn hoffibiayxriqe gtqzeuywpgc nqlgvudy") should return "dgxffryldcxodtn"
Test Failed
"[b]" was not equal to "[dgxffryldcxodtn]"
Stack Trace
Completed in 1ms
high("vhyxdefryeznlkz fcaenzsnoxsn phdqu zjbbbybjmdn dbfhvxwnusz dqbqskfbwuomzsl ogsdioilk") should return "vhyxdefryeznlkz"
Test Failed
String index out of range: -1
Stack Trace
high("yqbzfuprmezbgee yxsewucg u") should return "yqbzfuprmezbgee"
Test Failed
String index out of range: -1
Stack Trace
Completed in 1ms
high("zifha") should return "zifha"
Test Failed
String index out of range: -1
Stack Trace
high("moroydyolj tcfpokvitzwzor rnzeacau") should return "tcfpokvitzwzor"
Test Failed
"[m]" was not equal to "[tcfpokvitzwzor]"
Stack Trace
Completed in 1ms
high("jhieih m") should return "jhieih"
Test Failed
String index out of range: -1
Stack Trace
high("yn ounbzw wk eldpjyikbfs nzm") should return "eldpjyikbfs"
Test Failed
"[ ]" was not equal to "[eldpjyikbfs]"
Stack Trace
Completed in 1ms
在 Scala 中,使用集合中提供的函数更容易/(更好)。
在你的例子中 - 这里有一个可能性:
首先要添加得分你可以使用这个:
"hello".map(_.toInt).sum // 532
这 returns 所有字符的总和作为 Int 值 (a=97; ...; z=122)
要找到可以使用 foldLeft
的最高权重,从“”开始。
scala> List("a", "ab","ba").foldLeft("")((a,b)=> higher(a,b))
res10: String = ab
这里是完整的 higher
函数:
def higher(a:String, b:String):String=
if(a.map(_.toInt).sum >= b.map(_.toInt).sum) a else b
有很多很酷的可能性可以用集合函数来做到这一点——不要使用可变状态!这是切换到 Scala 的一个重要原因。
更新:玩完 https://www.codewars.com 我发现了一个错误和更短的解决方案:
s.split(" ").map(w => (w, w.map(_.toInt - 96).sum)).maxBy(_._2)._1
假设您的输入是
val str = "ykvhorsqve kfkq jhjibercdptf efevxax ccr vnsmumqby jwhxvamegupfcj lierziuopbcsutm"
您可以将每个字符的值维护为
val charMap = Map(
'a' -> 1,
'b' -> 2,
'c' -> 3,
'd' -> 4,
'e' -> 5,
'f' -> 6,
'g' -> 7,
'h' -> 8,
'i' -> 9,
'j' -> 10,
'k' -> 11,
'l' -> 12,
'm' -> 13,
'n' -> 14,
'o' -> 15,
'p' -> 16,
'q' -> 17,
'r' -> 18,
's' -> 19,
't' -> 20,
'u' -> 21,
'v' -> 22,
'w' -> 23,
'x' -> 24,
'y' -> 25,
'z' -> 26,
)
然后您可以添加一个简单的函数来计算每个单词的计数
def countOfWord(str : String): Int = str.map(charMap).sum
然后对您的输入字符串应用以下操作 str
将为您获取所需的结果
str.split(" ").map(word => (word, countOfWord(word))).maxBy(_._2)._1
这会为您获取所需的输出
res0: String = lierziuopbcsutm
val words = s.split(" ")
val scores = words.map(w => (w, w.map(_ - 'a' + 1).sum))
val max = scores.maxBy(_._2)._2
scores.find(_._2 == max).get._1
这个呢?
object HighestWord extends App {
val inputStr: String = "ykvhorsqve kfkq jhjibercdptf efevxax ccr vnsmumqby jwhxvamegupfcj lierziuopbcsutm"
val answer = inputStr.split(" ").map {
str: String =>
val sum = str.map { chr: Char =>
chr.toInt
}.sum
(str, sum)
}.maxBy(_._2)._1
println(answer)
}