首页 > 解决方案 > 如何在字符串中找到得分最高的单词?

问题描述

我又在做一些 CodeWars 挑战。

我有一个问题:

“给定一串单词,你需要找到得分最高的单词。

单词的每个字母根据其在字母表中的位置得分:a = 1、b = 2、c = 3 等。

您需要将得分最高的单词作为字符串返回。

如果两个单词得分相同,则返回原始字符串中出现最早的单词。

所有字母都是小写的,所有输入都是有效的。”

我已经在 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

标签: stringscalascoringhighest

解决方案


在 Scala 中,使用集合中提供的函数更容易/(更好)。

在您的示例中-这里有一种可能性:

首先要添加得分,您可以使用它:

"hello".map(_.toInt).sum // 532

这会将所有字符的总和作为 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

推荐阅读