英文:
How can I iterate over a pair of strings rune by rune in Go?
问题
在Go语言中,遍历两个字符串并逐个比较字符的惯用方法是什么?
根据我对Go的有限了解,一个简单的方法如下:
arunes := []rune(astr)
brunes := []rune(bstr)
for i, a := range arunes {
b := brunes[i]
// 使用a和b进行操作
}
当astr
和bstr
较短或者无论如何都需要完整扫描时,这种方法可以正常工作。但是,当它们很长并且有很高的可能性提前退出循环时,这种方法可能效率低下,因为据我了解,[]rune(..)
需要对字符串进行完整扫描。特别是,如果字符串非常长,而我只需要查看两个字符串的前1%之类的内容,我希望避免扫描整个字符串。
(我最初的想法是使用某种形式的zip
,但据我所知,Go中并不存在这样的函数,并且由于缺乏泛型,函数签名可能会变得非常复杂。但如果Go确实有一个干净好用的zip
替代方案,我会非常高兴和兴奋地了解它)
简而言之,是否有一种在两个字符串中以字符对的方式进行迭代的惯用Go方法,同时在只需要查看两个字符串的一小部分时仍然高效?
英文:
What's the idiomatic Go way of iterating over two strings and comparing them rune by rune?
Given my limited understanding of Go, a simple way to do this would look like:
arunes := []rune(astr)
brunes := []rune(bstr)
for i, a := range arunes {
b := brunes[i]
// do something with a and b
}
Which works ok when astr
and bstr
are short or a full scan is required anyway, but when they are long and there is a high chance of breaking the loop early, this may be inefficient because from what I understand, []rune(..)
requires a full scan of the string. In particular, if the strings are very long, and I only need to look at, for example, the first 1% of the two strings, I want to avoid scanning the entire string.
(my first thought was for some sort of zip
, but afaik, this doesn't exist in Go, and due to the lack of generics, the function signature would have looked really gross anyway - but if Go did have a good clean alternative to zip
, I would be most delighted and excited to learn about it)
TL;DR Is there an idiomatic Go way to iterate over runes in pairs of strings while still being efficient when only a small fraction of the two strings need to be looked at?
答案1
得分: 6
使用 utf8.DecodeRuneInString 函数从每个字符串中获取符文。
s1 := "hello world"
s2 := "Hello, 世界"
for {
r1, n1 := utf8.DecodeRuneInString(s1)
r2, n2 := utf8.DecodeRuneInString(s2)
// 当字符串的末尾达到时,DecodeRuneInString 函数会返回一个大小为零的符文。
// 在这里,当字符串的末尾达到时,我会跳出循环。
// 根据你的应用程序,根据需要更新逻辑。
if n1 == 0 || n2 == 0 {
break
}
// 处理符文。
fmt.Printf("%c %c\n", r1, r2)
// 前进到下一个符文。
s1 = s1[n1:]
s2 = s2[n2:]
}
英文:
Use utf8.DecodeRuneInString to get runes from each string.
s1 := "hello world"
s2 := "Hello, 世界"
for {
r1, n1 := utf8.DecodeRuneInString(s1)
r2, n2 := utf8.DecodeRuneInString(s2)
// DeocdeRuneInString returns a zero size rune
// at the end of the string. I break the loop
// here when the end of a string is reached. Update
// the logic as appropriate for your application.
if n1 == 0 || n2 == 0 {
break
}
// Process the runes.
fmt.Printf("%c %c\n", r1, r2)
// Advance to next rune.
s1 = s1[n1:]
s2 = s2[n2:]
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论