最佳实践来接受输入

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

Best practices to take input

问题

我已经编写了一个mergeSort函数,它可以在750毫秒内对100万个整数进行排序,但输入需要花费9秒钟。

以下是我用于将输入放入要排序的切片的方法。

代码片段:

array := make([]int,n)
for i := 0; i < n; i++ {
    fmt.Scanf("%d",&array[i])
}

我需要的是一种高效的方法将整数输入到切片中。
输入只包含整数,可以用空格分隔,也可以每个整数占一行。

示例输入1:

3
9
1
13

示例输入2:

3    9    1    13

如果对于任何一种类型的输入都有高效的解决方案,那就足够了。

英文:

I have written a mergeSort function, which sorted 1 million integers in 750ms, but it takes 9 seconds to take input.

This is how I have taken input to my slice, which is to be sorted.

code snippet:

array := make([]int,n)
for i := 0; i &lt; n; i++ {
    fmt.Scanf(&quot;%d&quot;,&amp;array[i])
}

What I need is, an efficient way to take integers as input into a slice.
Input contains only integers, seperated by space or each integer in new-line.

Sample Input 1:

3
9
1
13

Sample Input 2:

3 9 1 13

If efficient solution is available for any one type of Input, it would suffice

答案1

得分: 1

假设您的输入是以空格分隔的有符号整数(十进制),请尝试以下代码:

s := bufio.NewScanner(os.StdIn)
s.Split(bufio.ScanWords)
i := 0
for s.Scan() && i < n {
    dest[i], _ = strconv.ParseInt(s.Text(), 10, 64)
    i++
}

这段代码通过一个快速的基准测试显示比使用fmt.Scanf快大约5倍。通过编写一个自定义的分割函数,不需要解析UTF-8字符,只需在空格上进行分割,可能可以进一步优化。

英文:

On the assumption that your input is space separated signed integers (in base 10), try the following:

s := bufio.NewScanner(os.StdIn)
s.Split(bufio.ScanWords)
i := 0
for s.Scan() &amp;&amp; i &lt; n {
    dest[i], _ = strconv.ParseInt(s.Text(), 10, 64)
	i++
}

This shows with a quick benchmark to be about 5 times faster than using fmt.Scanf. It could probably be further optimised by writing a custom split function that did not worry about parsing UTF-8 runes and simply split on &#39; &#39;.

答案2

得分: 0

包 main

import (
"io/ioutil"
"os"
)
// inp 是一个变量,我们将整个输入存储在其中
var inp []byte
// loc 用作索引,并记住我们已经查看了输入的位置
var loc int

func main() {
// 我们读取整个输入并将其存储在 inp 中,然后追加 '\n',这样我们在扫描最后一个数字时就不会出现索引越界错误。
inp, _ = ioutil.ReadAll(os.Stdin)
inp = append(inp, '\n')
// 每当调用 scanInt 时,它将返回一个 int 类型的单个值
// 用法:
// n := scanInt()

}

func scanInt() (res int) {
// 跳过字节值不属于整数的部分,并在遇到整数时停止
for ; inp[loc] < 48 || inp[loc] > 57; loc++ {
}
// 如果是整数,则完全解析它,否则中断并返回结果

for ; inp[loc] > 47 && inp[loc] < 58 ; loc++ {
    res = (res << 1  ) + (res << 3) + int(inp[loc]-48)
}
return

}

英文:
package main

import (
	&quot;io/ioutil&quot;
	&quot;os&quot;
)
// inp is a variable in which we store our whole input
var inp []byte
// loc is used as index and remember till where we have seen our input
var loc int

func main() {
    // we read whole input and store it in inp and then append &#39;\n&#39;, so
    // that we don&#39;t get any type index out of bound error, while 
    // scanning the last digit.
	inp, _ = ioutil.ReadAll(os.Stdin)
	inp = append(inp, &#39;\n&#39;)
    // when ever scanInt is called, it will return single value of type int
    // usage:
    // n := scanInt()

}

func scanInt() (res int) {
    // skip if byte value doesn&#39;t belong to integer and break when it is
    // an integer
	for ; inp[loc] &lt; 48 || inp[loc] &gt; 57; loc++ {
	}
    // If it is an integer parse it completely else break return the result
    
	for ; inp[loc] &gt; 47 &amp;&amp; inp[loc] &lt; 58 ; loc++ {
		res = (res &lt;&lt; 1  ) + (res &lt;&lt; 3) + int(inp[loc]-48)
	}
	return
}

huangapple
  • 本文由 发表于 2017年7月26日 16:52:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/45321981.html
匿名

发表评论

匿名网友

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

确定