String 是否有更好的方法插入“引用”|';输入二进制字符串rep以获取10 | 000 | 001
是否有更好的方法将String 是否有更好的方法插入“引用”|';输入二进制字符串rep以获取10 | 000 | 001,string,go,formatting,String,Go,Formatting,是否有更好的方法将“|”插入字符串 给定十进制200=11001000 此函数返回一个字符串=11 | 001 | 000 当这个函数工作时,它看起来非常笨拙!!为什么会这样 很难在去做一个简单的字符插入 func (i Binary) FString() string { a := strconv.FormatUint(i.Get(), 2) y := make([]string, len(a), len(a)*2) data := []rune(a) r :=
“|”
插入字符串
给定十进制200=11001000
此函数返回一个字符串=11 | 001 | 000
当这个函数工作时,它看起来非常笨拙!!为什么会这样很难在去做一个简单的字符插入
func (i Binary) FString() string {
a := strconv.FormatUint(i.Get(), 2)
y := make([]string, len(a), len(a)*2)
data := []rune(a)
r := []rune{}
for i := len(data) - 1; i >= 0; i-- {
r = append(r, data[i])
}
for j := len(a) - 1; j >= 0; j-- {
y = append(y, string(r[j]))
if ((j)%3) == 0 && j > 0 {
y = append(y, "|")
}
}
return strings.Join(y, "")
}
这取决于你所说的更好。我会使用正则表达式 在这种情况下,从右侧插入分隔符会导致复杂性。如果填充字符串使其长度为3的倍数,则可以从左侧插入分隔符。我们可以很容易地使用正则表达式在每三个字符之前插入
|
。然后,我们可以去掉前面的|
+填充
func (i Binary) FString() string {
a := strconv.FormatUint(i.Get(), 2)
pad_req := len(a) % 3
padding := strings.Repeat("0", (3 - pad_req))
a = padding + a
re := regexp.MustCompile("([01]{3})")
a = re.ReplaceAllString(a, "|$1")
start := len(padding) + 1
if len(padding) == 3 {
// If we padded with "000", we want to remove the `|` before *and* after it
start = 5
}
a = a[start:]
return a
}
符号
组是从右向左计数的,因此从左向右复制数字时,第一个组可能更小。因此,对于第一组,组内数字的计数器不一定从0
开始,而是从len(input)%3开始
下面是一个例子:
func Format(s string) string {
b, count := &bytes.Buffer{}, len(s)%3
for i, r := range s {
if i > 0 && count == i%3 {
b.WriteRune('|')
}
b.WriteRune(r)
}
return b.String()
}
测试它:
for i := uint64(0); i < 10; i++ {
fmt.Println(Format(strconv.FormatUint(i, 2)))
}
fmt.Println(Format(strconv.FormatInt(1234, 2)))
如果您必须多次这样做,而且性能确实很重要,那么请查看我对问题的回答:
基于此,快速解决方案可以是:
func Format(s string) string {
out := make([]byte, len(s)+(len(s)-1)/3)
for i, j, k := len(s)-1, len(out)-1, 0; ; i, j = i-1, j-1 {
out[j] = s[i]
if i == 0 {
return string(out)
}
if k++; k == 3 {
j, k = j-1, 0
out[j] = '|'
}
}
}
输出当然是一样的。在上试试。这是一个分区问题。您可以使用此功能:
func partition(s, separator string, pLen int) string {
if pLen < 1 || len(s) == 0 || len(separator) == 0 {
return s
}
buffer := []rune(s)
L := len(buffer)
pCount := L / pLen
result := []string{}
index := 0
for ; index < pCount; index++ {
_from := L - (index+1)*pLen
_to := L - index*pLen
result = append(result, string(buffer[_from:_to]))
}
if L%pLen != 0 {
result = append(result, string(buffer[0:L-index*pLen]))
}
for h, t := 0, len(result)-1; h < t; h, t = h+1, t-1 {
result[t], result[h] = result[h], result[t]
}
return strings.Join(result, separator)
}
这基本上是对小数进行分组,使用|
作为分隔符。可能的副本。谢谢大家。我想我离你不远了——你的解决方案在大多数情况下都比我的好——谢谢
func partition(s, separator string, pLen int) string {
if pLen < 1 || len(s) == 0 || len(separator) == 0 {
return s
}
buffer := []rune(s)
L := len(buffer)
pCount := L / pLen
result := []string{}
index := 0
for ; index < pCount; index++ {
_from := L - (index+1)*pLen
_to := L - index*pLen
result = append(result, string(buffer[_from:_to]))
}
if L%pLen != 0 {
result = append(result, string(buffer[0:L-index*pLen]))
}
for h, t := 0, len(result)-1; h < t; h, t = h+1, t-1 {
result[t], result[h] = result[h], result[t]
}
return strings.Join(result, separator)
}
func TestSmokeTest(t *testing.T) {
input := "11001000"
s := partition(input, "|", 3)
if s != "11|001|000" {
t.Fail()
}
s = partition(input, "|", 2)
if s != "11|00|10|00" {
t.Fail()
}
input = "0111001000"
s = partition(input, "|", 3)
if s != "0|111|001|000" {
t.Fail()
}
s = partition(input, "|", 2)
if s != "01|11|00|10|00" {
t.Fail()
}
}