如何为大小可变的2×2数组分配所有元素?

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

GO : how to Assign all elements in 2 by 2 array of variable size?

问题

我遇到了一个问题,即使用GO从文本文件中填充一个2D数组的矩阵。主要问题是创建一个2D数组,因为我需要计算数组的维度,而GO似乎不接受数组维度中的VAR:

nb_lines = 数组的行数
nb_col = 数组的列数

// 从文件中读取矩阵
whole_file,_ := ioutil.ReadFile("test2.txt")
// 将文件的每一行存入tab_whole_file
tab_whole_file := strings.Split(string(whole_file), "\n")
// 表的第一行
tab_first_line := strings.Split(tab_whole_file[0], "\t")
nb_col := len(tab_first_line)
nb_lines := len(tab_whole_file) - 1

// 在这一点上,我尝试构建一个数组来存储来自文本文件的矩阵值

var columns [nb_lines][nb_col]float64 // 不起作用
columns := make([][]float64, nb_lines, nb_col) // 不起作用
columns := make([nb_lines][nb_col]float64) // 不起作用
columns := [nb_lines][nb_col]float64{} // 不起作用
columns := [][]float64{} // 报错:运行时错误:索引超出范围

for i := 0; i < nb_lines ; i++ { // 对于文本文件中的每一行
line := strings.Split(tab_whole_file[0], "\t") // 分割一行以获取每个表的值
for j := 1; j < len(line) ; j++ {
columns[i][j], _ = strconv.ParseFloat(line[j], 64) // 将每个值赋给表columns[i][j]
}
}

英文:

I'm having problems filling a 2D array with a matrix from a text file using GO.

The main problem I have is to create a 2D array because I have to calculate the dimension of the array and GO does not seem to accept VAR in array dimension :

nb_lines = number of line of the array
nb_col = number of columns of the array

// read matrix from file
whole_file,_ := ioutil.ReadFile(&quot;test2.txt&quot;)
// get each line of the file in tab_whole_file
tab_whole_file := strings.Split(string(whole_file), &quot;\n&quot;)
// first line of the table
tab_first_line := strings.Split(tab_whole_file[0], &quot;\t&quot;)
nb_col := len(tab_first_line)
nb_lines := len(tab_whole_file) - 1

// at this point I tried to build a array to contain the matrix values from the texte file

var columns [nb_lines][nb_col]float64 // does not work
columns := make([][]float64, nb_lines, nb_col) // does not work
columns := make([nb_lines][nb_col]float64) // does not work
columns := [nb_lines][nb_col]float64{} // does not work
columns := [][]float64{} // panic: runtime error: index out of range

for i := 0; i &lt; nb_lines ; i++ { // for each line of the table from text file
    line := strings.Split(tab_whole_file[0], &quot;\t&quot;) // split one line to get each table values
    for j := 1; j &lt; len(line) ; j++ {
        columns[i][j], _  = strconv.ParseFloat(line[j], 64) // assign each value to the table columns[i][j]
    }
}

答案1

得分: 1

在Go语言中,使用[][]float64声明一个float64类型的矩阵。

你可以使用:=运算符来初始化矩阵并自动声明类型。

注意,上面的代码行不仅仅是一个简单的声明,它是用于创建一个新的空切片的语法。

// 创建一个空的整型切片
x := []int{}
// 创建一个整型切片
x := []int{1, 2, 3, 4}

使用[]float64{}的方式将定义和分配结合在一起。注意以下两行代码的区别:

// 创建一个包含4个整数的切片
x := []int{1, 2, 3, 4}
// 创建一个包含4个整数的数组
x := [4]int{1, 2, 3, 4}

切片可以调整大小,而数组的大小是固定的。

针对你的问题,这里有一个示例演示了如何创建一个float64类型的矩阵并向矩阵中添加新行。

package main

import "fmt"

func main() {
    matrix := [][]float64{}
    matrix = append(matrix, []float64{1.0, 2.0, 3.0})
    matrix = append(matrix, []float64{1.1, 2.1, 3.1})
    fmt.Println(matrix)
}

你可以从这个示例开始,然后更新你的脚本。

英文:

A matrix of float64 in Go is declared as [][]float64

var matrix [][]float64

You can use the := operator to initialize the matrix and declare the type automatically

matrix := [][]float64{}

Note that this the line above is not a simple declaration, is the syntax used to create a new empty slice

// creates an empty slice of ints
x := []int{} 
// creates a slice of ints
x := []int{1, 2, 3, 4} 

The use of []float64{} combines together the definition and the allocation. Note that the following two lines are different

// creates a slice of 4 ints
x := []int{1, 2, 3, 4} 
// creates an array of 4 ints
x := [4]int{1, 2, 3, 4} 

Slices can be resized, arrays have fixed size.

Back to your problem, here's an example that demonstrates how to create a matrix of float64 and append new rows to the matrix.

package main

import &quot;fmt&quot;

func main() {
	matrix := [][]float64{}
	matrix = append(matrix, []float64{1.0, 2.0, 3.0})
	matrix = append(matrix, []float64{1.1, 2.1, 3.1})
	fmt.Println(matrix)
}

You can start from this example and update your script.

答案2

得分: 1

例如,

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "strconv"
)

func loadMatrix(filename string) ([][]float64, error) {
    var m [][]float64
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        return nil, err
    }

    rows := bytes.Split(data, []byte{'\n'})
    for r := len(rows) - 1; r >= 0; r-- {
        if len(rows[r]) != 0 {
            break
        }
        rows = rows[:len(rows)-1]
    }
    m = make([][]float64, len(rows))

    nCols := 0
    for r, row := range rows {
        cols := bytes.Split(row, []byte{'\t'})
        if r == 0 {
            nCols = len(cols)
        }
        m[r] = make([]float64, nCols)
        for c, col := range cols {
            if c < nCols && len(col) > 0 {
                e, err := strconv.ParseFloat(string(col), 64)
                if err != nil {
                    return nil, err
                }
                m[r][c] = e
            }
        }
    }
    return m, nil
}

func main() {
    filename := "matrix.tsv"
    m, err := loadMatrix(filename)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Matrix:")
    fmt.Println(m)

    fmt.Println("\n按[行,列]:")
    for r := range m {
        for c := range m[0] {
            fmt.Printf("[%d,%d] %5v  ", r, c, m[r][c])
        }
        fmt.Println()
    }

    fmt.Println("\n按[列,行]:")
    for c := range m[0] {
        for r := range m {
            fmt.Printf("[%d,%d] %5v  ", c, r, m[r][c])
        }
        fmt.Println()
    }
}

输出:

$ cat matrix.tsv
3.14    1.59    2.7 1.8
42

$ go run matrix.go
Matrix:
[[3.14 1.59 2.7 1.8] [42 0 0 0]]

按[行,列]:
[0,0]  3.14  [0,1]  1.59  [0,2]   2.7  [0,3]   1.8  
[1,0]    42  [1,1]     0  [1,2]     0  [1,3]     0  

按[列,行]:
[0,0]  3.14  [0,1]    42  
[1,0]  1.59  [1,1]     0  
[2,0]   2.7  [2,1]     0  
[3,0]   1.8  [3,1]     0  
$
英文:

For example,

package main

import (
	&quot;bytes&quot;
	&quot;fmt&quot;
	&quot;io/ioutil&quot;
	&quot;strconv&quot;
)

func loadMatrix(filename string) ([][]float64, error) {
	var m [][]float64
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	rows := bytes.Split(data, []byte{&#39;\n&#39;})
	for r := len(rows) - 1; r &gt;= 0; r-- {
		if len(rows[r]) != 0 {
			break
		}
		rows = rows[:len(rows)-1]
	}
	m = make([][]float64, len(rows))

	nCols := 0
	for r, row := range rows {
		cols := bytes.Split(row, []byte{&#39;\t&#39;})
		if r == 0 {
			nCols = len(cols)
		}
		m[r] = make([]float64, nCols)
		for c, col := range cols {
			if c &lt; nCols &amp;&amp; len(col) &gt; 0 {
				e, err := strconv.ParseFloat(string(col), 64)
				if err != nil {
					return nil, err
				}
				m[r][c] = e
			}
		}
	}
	return m, nil
}

func main() {
	filename := &quot;matrix.tsv&quot;
	m, err := loadMatrix(filename)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(&quot;Matrix:&quot;)
	fmt.Println(m)

	fmt.Println(&quot;\nBy [row,column]:&quot;)
	for r := range m {
		for c := range m[0] {
			fmt.Printf(&quot;[%d,%d] %5v  &quot;, r, c, m[r][c])
		}
		fmt.Println()
	}

	fmt.Println(&quot;\nBy [column,row]:&quot;)
	for c := range m[0] {
		for r := range m {
			fmt.Printf(&quot;[%d,%d] %5v  &quot;, c, r, m[r][c])
		}
		fmt.Println()
	}
}

Output:

$ cat matrix.tsv
3.14	1.59	2.7	1.8
42

$ go run matrix.go
Matrix:
[[3.14 1.59 2.7 1.8] [42 0 0 0]]

By [row,column]:
[0,0]  3.14  [0,1]  1.59  [0,2]   2.7  [0,3]   1.8  
[1,0]    42  [1,1]     0  [1,2]     0  [1,3]     0  

By [column,row]:
[0,0]  3.14  [0,1]    42  
[1,0]  1.59  [1,1]     0  
[2,0]   2.7  [2,1]     0  
[3,0]   1.8  [3,1]     0  
$

答案3

得分: 0

我对程序进行了一些修改,这是一个“几乎”工作的示例...不太优雅 如何为大小可变的2×2数组分配所有元素? 矩阵中仍然存在一个问题:矩阵的第一列对应文件的第一行,所以我无法访问列 如何为大小可变的2×2数组分配所有元素?

func main() {

    matrix := [][]float64{} // 对应文本文件的矩阵

    // 打开文件。
    whole_file,_ := ioutil.ReadFile("test2.tsv")
    // 测量表格的大小
    tab_whole_file := strings.Split(string(whole_file), "\n")
    tab_first_line := strings.Split(tab_whole_file[0], "\t")
    nb_col := len(tab_first_line)
    nb_lines := len(tab_whole_file) - 1 
    // 我不知道为什么这个数字比我预期的要长,所以我必须减去1

    for i := 0; i < nb_lines ; i++ {
        numbers := []float64{} // 临时数组
        line := strings.Split(tab_whole_file[i], "\t")
        for j := 1; j < nb_col ; j++ { // 1而不是0,因为我不想要行名的第一列,也无法将其存储在浮点数组中
            if nb, err := strconv.ParseFloat(line[j], 64); err == nil {
                numbers = append(numbers,nb) // 不太优雅/高效的临时数组
            }
        }
        matrix = append(matrix, numbers)
    }
}
英文:

I did few modifications to my program and this is a "almost" working example... not very elegant 如何为大小可变的2×2数组分配所有元素? There is still a problem in the matrix : the 1st column of the matrix correspond to the 1st line of the file so I dont have access to columns 如何为大小可变的2×2数组分配所有元素?

func main() {

    matrix := [][]float64{} // matrix corresponding to the text file
  
    // Open the file.
    whole_file,_ := ioutil.ReadFile(&quot;test2.tsv&quot;)
    // mesasure the size of the table
    tab_whole_file := strings.Split(string(whole_file), &quot;\n&quot;)
    tab_first_line := strings.Split(tab_whole_file[0], &quot;\t&quot;)
    nb_col := len(tab_first_line)
    nb_lines := len(tab_whole_file) - 1 
// I dont know why this number is longer than I expected so I have to substract 1
   

    for i := 0; i &lt; nb_lines ; i++ {
      numbers := []float64{} // temp array
      line := strings.Split(tab_whole_file[i], &quot;\t&quot;)
      for j := 1; j &lt; nb_col ; j++ { // 1 instead of 0 because I dont want the first column of row names and I cant store it in a float array
        if nb, err := strconv.ParseFloat(line[j], 64); err == nil {
          numbers = append(numbers,nb) // not very elegant/efficient temporary array
        }
      }
      matrix = append(matrix, numbers)
    }
}

huangapple
  • 本文由 发表于 2016年3月13日 20:07:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/35970010.html
匿名

发表评论

匿名网友

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

确定