3 回答
TA贡献1815条经验 获得超10个赞
取决于你叫什么更好。我会使用正则表达式。
在这种情况下,复杂性来自于从右侧插入分隔符。如果我们填充字符串使其长度是 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
}
TA贡献1863条经验 获得超2个赞
如果性能不重要并且您只想要一个紧凑的版本,您可以将输入数字复制到输出,并在将|一组 2 写入输出时插入一个符号。
组从右到左计数,因此当从左到右复制数字时,第一组可能更小。因此,组内的数字计数器不一定从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)))
输出(在Go Playground上试试):
0
1
10
11
100
101
110
111
1|000
1|001
10|011|010|010
如果您必须多次执行此操作并且性能确实很重要,请查看我对问题的回答:How to fmt.Printf an integer with many comma
基于此,一个快速的解决方案可以是:
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] = '|'
}
}
}
输出当然是一样的。在Go Playground上尝试一下。
TA贡献1807条经验 获得超9个赞
这是一个分区问题。您可以使用此功能:
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)
}
并且s := partition("11001000", "|", 3)会给你11|001|000。
这是一个小测试:
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()
}
}
- 3 回答
- 0 关注
- 139 浏览
添加回答
举报