自学内容网 自学内容网

【华为OD机试真题】4、字符统计及重排

输入 输入一行,为一个仅包含字母的字符串。  输出 按照字母出现次数从大到小的顺序输出各个字母和字母次数,用英文分号分隔,注意末尾的分号; 字母和次数间用英文冒号分隔 

第一次写的代码,空间复杂度很高,可读性差,但是运行结果没问题。

package main

import (
"fmt"
"sort"
)

func getIndexByValue(list []string, value string) int {
for i, s := range list {
if s == value {
return i
}
}
return -1
}

func main() {
var inputStr string
fmt.Scan(&inputStr)
inputAlphabetList := make([]string, len(inputStr))

alphabets := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
alphabetIndexCount := make([]int, len(alphabets))
for i, v := range inputStr {
inputAlphabetList[i] = string(v)
alphabetIndexCount[getIndexByValue(alphabets, string(v))] = alphabetIndexCount[getIndexByValue(alphabets, string(v))] + 1
}

characterCountList := make([]int, 0)
for _, i := range alphabetIndexCount {
if i > 0 {
notFind := false
for _, i2 := range characterCountList {
if i2 == i {
notFind = true
}
}
if !notFind {
characterCountList = append(characterCountList, i)
}
}
}

//sort.Ints(characterCountList)
sort.Slice(characterCountList, func(i, j int) bool {
return characterCountList[i] > characterCountList[j]
})
groupCharacterListByCount := make([][]string, len(characterCountList))
for i, characterCount := range characterCountList {

for alphabetIndex, alphabetItem := range alphabets {
if characterCount == alphabetIndexCount[alphabetIndex] {
groupCharacterListByCount[i] = append(groupCharacterListByCount[i], alphabetItem)
}
}
}

outputStr := ""
for i, count := range characterCountList {

itemCharacters := groupCharacterListByCount[i]
for _, character := range itemCharacters {
if outputStr == "" {
outputStr = fmt.Sprintf("%s:%d;", character, count)
} else {
outputStr = fmt.Sprintf("%s%s:%d;", outputStr, character, count)
}

}

}

fmt.Println(outputStr)

}

开始思考如何重构:

package main

import (
"fmt"
"sort"
"unicode"
)

type myCharacterCount struct {
Key   rune
Count int
}

func main() {
var inputStr string
fmt.Scan(&inputStr)

characterCountMapList := make(map[rune]int)
for _, character := range inputStr {
characterCountMapList[character]++
}

characterCountList := make([]*myCharacterCount, 0)
for s, i := range characterCountMapList {
characterCountList = append(characterCountList, &myCharacterCount{
Key:   s,
Count: i,
})
}

// 根据出现次数降序排序,如果次数相同则按字母本身排序(小写在前)
sort.Slice(characterCountList, func(i, j int) bool {
if characterCountList[i].Count != characterCountList[j].Count {
return characterCountList[i].Count > characterCountList[j].Count // 次数降序
} else {
if unicode.IsLower(characterCountList[i].Key) != unicode.IsLower(characterCountList[j].Key) {
return unicode.IsLower(characterCountList[i].Key)
}
return characterCountList[i].Key < characterCountList[j].Key
}

})

outputStr := ""
for _, item := range characterCountList {

if outputStr == "" {
outputStr = fmt.Sprintf("%c:%d;", item.Key, item.Count)
} else {
outputStr = fmt.Sprintf("%s%c:%d;", outputStr, item.Key, item.Count)
}

}

fmt.Println(outputStr)

}

在这里有一个细节开始我没有注意:在golang获取字符的unicode编码时,相同字符的大写<小写(如

  • 小写字母 a 的 rune 值(97)比大写字母 A 的 rune 值(65)大。

)。所以做排序时,不能只根据unicode值排序,还要先判断大小写,讲小写字符放到前面


原文地址:https://blog.csdn.net/u014381782/article/details/142416317

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!