我正在尝试反转一个字符串,但是在处理字符时遇到了麻烦。与C不同,GO将字符串视为字节向量,而不是字符,在这里称为符文。我尝试进行一些类型转换来完成分配,但是到目前为止我还做不到。
这里的想法是生成5个具有100、200、300、400和500大小的随机字符的字符串,然后反转它们的字符。我能够轻松地使用C,但是在GO语言中,该语言返回了一个错误,指出无法执行分配。
func inverte() {
var c = "A"
var strs, aux string
rand.Seed(time.Now().UnixNano())
// Gera 5 vetores de 100, 200, 300, 400, e 500 caracteres
for i := 1; i < 6; i++ {
strs = randomString(i * 100)
fmt.Print(strs)
for i2, j := 0, len(strs); i2 < j; i2, j = i+1, j-1 {
aux = strs[i2]
strs[i2] = strs[j]
strs[j] = aux
}
}
}
答案 0 :(得分:3)
如果您想考虑unicode combining characters,请Andrew Sellers参加in this gist。
首先列出所有组合的变音标记(CDM)的Unicode block range
var combining = &unicode.RangeTable{
R16: []unicode.Range16{
{0x0300, 0x036f, 1}, // combining diacritical marks
{0x1ab0, 0x1aff, 1}, // combining diacritical marks extended
{0x1dc0, 0x1dff, 1}, // combining diacritical marks supplement
{0x20d0, 0x20ff, 1}, // combining diacritical marks for symbols
{0xfe20, 0xfe2f, 1}, // combining half marks
},
}
然后,您可以依次读取初始字符串的符文:
sv := []rune(s)
但是,如果按反向的顺序进行操作,则会遇到组合变音标记(CDM) 第一,为了保留其顺序,不不撤消
for ix := len(sv) - 1; ix >= 0; ix-- {
r := sv[ix]
if unicode.In(r, combining) {
cv = append(cv, r)
fmt.Printf("Detect combining diacritical mark ' %c'\n", r)
}
(请注意,%c
组合符周围的空格:'%c'
没有空格,这意味着将标记与第一个'ͤ'
:组合在一起,而不是'''。我尝试使用{ {3}} \u034F
,但无效)
如果最终遇到常规符文,则需要与这些CDM结合,然后再将其添加到反向最终符文阵列中。
} else {
rrv := make([]rune, 0, len(cv)+1)
rrv = append(rrv, r)
rrv = append(rrv, cv...)
fmt.Printf("regular mark '%c' (with '%d' combining diacritical marks '%s') => '%s'\n", r, len(cv), string(cv), string(rrv))
rv = append(rv, rrv...)
cv = make([]rune, 0)
}
表情符号变得更加复杂,例如最近出现的修饰符,例如CGJ Combining Grapheme Joiner,肤色Medium-Dark Skin Tone上的类型5。
如果忽略该选项,则反向“ ??????????⚖️”将给出“ ️⚖???????”,从而使最后两个表情符号上的肤色消失。
???单独是(来自Fitzpatrick Scale):
那些应该保持完全相同的顺序。
别让我开始使用red hair (1f9b0)(200D),它会迫使ZERO WIDTH JOINER的相邻字符(例如阿拉伯字符或受支持的表情符号)结合在一起。可以用来组成顺序组合的表情符号。
??⚖️是由两个表情符号组成的实际 one 字形。 不应该倒置。
下面的程序正确地检测到“零宽度连接符”,并且不反转其组合的表情符号。
Wisdom/Awesome-Unicode
中的完整示例。
Reverse 'Hello, World' => 'dlroW ,olleH'
Reverse '??⃠?' => '??⃠?'
Reverse '???????⚖️' => '??⚖️?????'
Reverse 'aͤoͧiͤ š́ž́ʟ́' => 'ʟ́ž́š́ iͤoͧaͤ'
Reverse 'H̙̖ell͔o̙̟͚͎̗̹̬ ̯W̖͝ǫ̬̞̜rḷ̦̣̪d̰̲̗͈' => 'd̰̲̗͈ḷ̦̣̪rǫ̬̞̜W̖͝ ̯o̙̟͚͎̗̹̬l͔leH̙̖'
答案 1 :(得分:2)
正如您正确识别的go strings are immutable,因此您无法在给定索引处分配符文/字符值。
与其代替就地反转字符串,还必须在字符串中创建一个符文副本,然后反转它们,然后返回结果字符串。
例如(Go Playground):
func reverse(s string) string {
rs := []rune(s)
for i, j := 0, len(rs)-1; i < j; i, j = i+1, j-1 {
rs[i], rs[j] = rs[j], rs[i]
}
return string(rs)
}
func main() {
fmt.Println(reverse("Hello, World!"))
// !dlroW ,olleH
fmt.Println(reverse("Hello, 世界!"))
// !界世 ,olleH
}
由于Unicode的复杂性(例如combining diacritical marks),这种方法存在一些问题,但这会让您入门。