如何在二维切片字符串元素中添加零

huangapple go评论87阅读模式
英文:

How to add zeros to 2d slice string elements

问题

任务是将二维切片中的字符串元素添加零。因此,输入是[[“7”、“3”、“1”][“2”、“9”]],我需要从每个切片的最后一个元素添加零到第一个元素。每一步,零的计数器增加1。因此,预期的输出是[[“700”,“30”,“1”][“20”,“9”]]。

我尝试了这样的算法,但无法得到预期的答案。这是我的代码:

package main

import (
	"fmt"
	"strings"
)

func addZero(strs [][]string) [][]string {
	zero := "0"
	counter := 0
	for i := range strs {
		for j := range strs[i] {
			strs[i][j] += strings.Repeat(zero, counter)
		}
		counter++
	}
	return strs
}

func main() {
	fmt.Println(addZero([][]string{{"7", "3", "1"}, {"2", "9"}}))// 这里的结果是[[7 3 1] [20 90]]
 
}

如何修改我的代码以获得预期的答案?

英文:

The task is to add zeros to string elements of 2d slice. So the stdin is [["7" "3" "1"]["2" "9"]] and I need to add zeros from the last element of each slice to the first one. For each step the counter of zeros is incremented by +1. Therefore, stdout is expected to be [["700", "30", "1"]["20", "9"]].

I have tried to do such an algorithm but can't get expected answer. Here is my code:

package main

import (
	"fmt"
	"strings"
)

func addZero(strs [][]string) [][]string {
	zero := "0"
	counter := 0
	for i := range strs {
		for j := range strs[i] {
			strs[i][j] += strings.Repeat(zero, counter)
		}
		counter++
	}
	return strs
}

func main() {
	fmt.Println(addZero([][]string{{"7", "3", "1"}, {"2", "9"}}))// here the result is [[7 3 1] [20 90]]
 
}

How to change my code to get an expected answer ?

答案1

得分: 1

计算零的个数必须在每一行中重新开始,所以将该代码移动到第一个循环内部。

此外,范围从索引0开始,你希望从每行的末尾增加零,所以counter必须从len(strs[i])-1开始,并且必须递减:

func addZero(strs [][]string) [][]string {
    for i := range strs {
        zero := "0"
        counter := len(strs[i]) - 1
        for j := range strs[i] {
            strs[i][j] += strings.Repeat(zero, counter)
            counter--
        }
    }
    return strs
}

通过这些更改,输出将是(在Go Playground上尝试):

[[700 30 1] [20 9]]

请注意,如果你从末尾处理行,则要附加的后缀(零)将增加。因此,你可以通过保留并“扩展”先前的后缀来摆脱strings.Repeat()

func addZero(strs [][]string) [][]string {
    for _, line := range strs {
        zeros := ""
        for i := len(line) - 1; i >= 0; i-- {
            line[i] += zeros
            zeros += "0"
        }
    }
    return strs
}

这输出相同的结果。在Go Playground上尝试。

还要注意,字符串可以被切片,并且结果与切片的字符串共享内存。因此,它快速且不会创建垃圾!你可以构建一个单独的、长的zeros字符串,只包含零,并且可以切片这个长字符串,以获得所需附加的零的数量。这种解决方案避免了任何不必要的字符串分配和连接:

var zeros = strings.Repeat("0", 1000) // 在这里使用最大长度

func addZero(strs [][]string) [][]string {
    for _, line := range strs {
        count := len(line) - 1
        for i := range line {
            line[i] += zeros[:count-i]
        }
    }
    return strs
}

这再次输出相同的结果,在Go Playground上尝试。

英文:

Counting zeros has to reset in each line, so move that code inside the first loop.

Also range goes from index 0, and you want increasing zeroes from the end of lines, so counter has to start from len(strs[i])-1, and you have to decrement it:

func addZero(strs [][]string) [][]string {
	for i := range strs {
		zero := "0"
		counter := len(strs[i]) - 1
		for j := range strs[i] {
			strs[i][j] += strings.Repeat(zero, counter)
			counter--
		}
	}
	return strs
}

With these changes output will be (try it on the Go Playground):

[[700 30 1] [20 9]]

Note that if you would process lines from the end, the suffix to append (the zeros) would increase. So you could ditch strings.Repeat() by keeping and "extending" the previous suffix:

func addZero(strs [][]string) [][]string {
	for _, line := range strs {
		zeros := ""
		for i := len(line) - 1; i >= 0; i-- {
			line[i] += zeros
			zeros += "0"
		}
	}
	return strs
}

This outputs the same. Try it on the Go Playground.

Also note that strings can be sliced, and the result shares the memory with the sliced string. So it's fast and does not create garbage! You could build a single, long zeros string holding just zeros, and you could slice this long string to have as many zeros as you need to append. This solution avoids any unnecessary string allocations and concatenations:

var zeros = strings.Repeat("0", 1000) // Use the maximum length here

func addZero(strs [][]string) [][]string {
	for _, line := range strs {
		count := len(line) - 1
		for i := range line {
			line[i] += zeros[:count-i]
		}
	}
	return strs
}

This again outputs the same, try it on the Go Playground.

huangapple
  • 本文由 发表于 2022年11月27日 23:24:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/74591251.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定