【问题标题】:How to adjust the size of two-dimensional array in Go?Go中如何调整二维数组的大小?
【发布时间】:2016-08-09 20:05:23
【问题描述】:

我编写了一个程序,它读取输入行并检查一行是否以 # 开头。
如果是这样,当前行和下一行将保存在二维数组中同一行的两列中:

Go Playground

package main

import (
        "bufio"
        "fmt"
        "strings"
)

func main() {
        const input = "#FooBar1\nFooBar1\n#Foobar2\nFooBar2\n#FooBar3\nFooBar3"

        var multiDimArr [3][2]string
        var lineCount int

        scanner := bufio.NewScanner(strings.NewReader(input))
        for line := 0; scanner.Scan(); line++ {
                if strings.HasPrefix(scanner.Text(), "#") {
                        multiDimArr[line][0] = scanner.Text()
                        scanner.Scan()
                        multiDimArr[line][1] = scanner.Text()
                        lineCount++
                }
        }
        for i := 0; i < lineCount; i++ {
                for j := 0; j < 2; j++ {
                        fmt.Printf("multiDimArr[%d][%d] = %s\n", i, j, multiDimArr[i][j])
                }
        }
}

输出:

multiDimArr[0][0] = #FooBar1
multiDimArr[0][1] = FooBar1
multiDimArr[1][0] = #Foobar2
multiDimArr[1][1] = FooBar2
multiDimArr[2][0] = #FooBar3
multiDimArr[2][1] = FooBar3

我的问题是在构建程序的时候需要知道输入的行数,所以可以调整multiDimArr的大小。

我可以做些什么来让它占用任意数量的行吗?

【问题讨论】:

标签: go


【解决方案1】:

试试this variation:

package main

import (
    "bufio"
    "fmt"
    "strings"
)

func main() {
    const input = "#FooBar1\nFooBar1\n#Foobar2\nFooBar2\n#FooBar3\nFooBar3"

    var multiDimArr [][2]string

    scanner := bufio.NewScanner(strings.NewReader(input))
    for scanner.Scan() {
        if strings.HasPrefix(scanner.Text(), "#") {
            firstLine := scanner.Text()
            scanner.Scan()
            secondLine := scanner.Text()
            multiDimArr = append(multiDimArr, [2]string{firstLine, secondLine})
        }
    }
    for i, row := range multiDimArr {
        for j, line := range row {
            fmt.Printf("multiDimArr[%d][%d] = %s\n", i, j, line)
        }
    }
}

【讨论】:

  • 谢谢。完美运行。
【解决方案2】:

使用这个Slice:[][2]string{},这样就不用统计输入的行数了:

试试这个工作示例代码:

package main

import "bufio"
import "fmt"
import "strings"

func main() {
    const input = "#FooBar1\nFooBar1\n#Foobar2\nFooBar2\n#FooBar3\nFooBar3"
    multiDimArr := [][2]string{}
    for i, r := 0, bufio.NewScanner(strings.NewReader(input)); r.Scan(); i++ {
        line1 := r.Text()
        if !strings.HasPrefix(line1, "#") || !r.Scan() {
            break
        }
        multiDimArr = append(multiDimArr, [2]string{line1, r.Text()})
    }
    fmt.Println(multiDimArr)
}

输出:

[[#FooBar1 FooBar1] [#Foobar2 FooBar2] [#FooBar3 FooBar3]]

如果您需要预扫描输入以计算行数,您也可以使用此工作示例代码,使用multiDimArr := make([][2]string, n) 使此切片[][2]stringlength = capacity = n

package main

import "bufio"
import "fmt"
import "strings"

func main() {
    const input = "#FooBar1\nFooBar1\n#Foobar2\nFooBar2\n#FooBar3\nFooBar3"
    n := 0
    for r := bufio.NewScanner(strings.NewReader(input)); r.Scan() && strings.HasPrefix(r.Text(), "#") && r.Scan(); n++ {
    }
    multiDimArr := make([][2]string, n)
    for i, r := 0, bufio.NewScanner(strings.NewReader(input)); r.Scan(); i++ {
        line1 := r.Text()
        if !strings.HasPrefix(line1, "#") || !r.Scan() {
            break
        }
        multiDimArr[i] = [2]string{line1, r.Text()}
    }
    fmt.Println(multiDimArr)
}

输出:

[[#FooBar1 FooBar1] [#Foobar2 FooBar2] [#FooBar3 FooBar3]]

Array types:

长度是数组类型的一部分;它必须评估为 非负 constant 可以用 int 类型的值表示。

所以你不能使用数组,因为它的长度是恒定的,使用multiDimArr := [n][2]string{}会导致编译时错误:non-constant array bound n

n := preScan(input) 
//multiDimArr := [n][2]string{} // error: non-constant array bound n

【讨论】:

  • 谢谢。我对 Go 还没有太多经验。与 Amit Kumar Gupta 发布的示例相比,这两个示例是否或多或少有效和惯用?
  • @JohnSmith:是的,第一个示例代码与那篇文章类似,除了我检查了r.Scan() 是否返回 true,但他需要检查它(在第二个 scanner.Scan() 他没有' t (但应该)),所以如果第二个 scanner.Scan() 返回 false 则代码失败。
猜你喜欢
  • 2011-02-08
  • 2020-11-15
  • 2017-01-05
  • 2018-05-02
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
相关资源
最近更新 更多