面试题答案
一键面试package main
import (
"fmt"
"unicode"
)
func countWordsByLanguage(s string) map[string]int {
result := make(map[string]int)
words := splitWords(s)
for _, word := range words {
lang := detectLanguage(word)
result[lang]++
}
return result
}
func splitWords(s string) []string {
var words []string
start := 0
for i, r := range s {
if unicode.IsSpace(r) {
if i > start {
words = append(words, s[start:i])
}
start = i + 1
}
}
if len(s) > start {
words = append(words, s[start:])
}
return words
}
func detectLanguage(word string) string {
for _, r := range word {
if unicode.Is(unicode.Han, r) {
return "Chinese"
} else if unicode.Is(unicode.Hiragana, r) || unicode.Is(unicode.Katakana, r) {
return "Japanese"
} else if unicode.IsLetter(r) {
return "English"
}
}
return "Other"
}
你可以通过以下方式调用这个函数:
func main() {
s := "你好 world こんにちは"
result := countWordsByLanguage(s)
fmt.Println(result)
}
对Unicode字符属性的理解和应用
- rune类型:在Go语言中,
rune
类型等同于int32
,它用于表示一个Unicode码点。由于不同语言的字符可能占用不同字节数,使用rune
可以精确处理每个字符,避免字节边界问题。例如,中文字符在UTF - 8编码下通常占用3个字节,如果按字节处理可能会出现错误。 - Unicode字符属性检测:
unicode
包提供了一系列函数来检测字符的属性。例如,unicode.IsHan
用于检测是否为中文字符(属于Han表意文字块),unicode.IsHiragana
和unicode.IsKatakana
分别用于检测平假名和片假名字符,unicode.IsLetter
用于检测通用的字母字符(包括英文字母等)。通过这些函数,可以判断字符所属的语言类别,从而实现按语言统计单词数量。 - 处理字符边界:在
splitWords
函数中,使用rune
遍历字符串,当遇到空格字符(通过unicode.IsSpace
判断)时,将之前的子串作为一个单词切分出来。这样可以确保不同语言的字符在切分单词时不会出现边界错误,例如不会把一个中文字符切成两半。