登录
首页 >  Golang >  Go问答

更快的输入扫描

来源:Golang技术栈

时间:2023-04-23 16:59:53 188浏览 收藏

哈喽!大家好,很高兴又见面了,我是golang学习网的一名作者,今天由我给大家带来一篇《更快的输入扫描》,本文主要会讲到golang等等知识点,希望大家一起学习进步,也欢迎大家关注、点赞、收藏、转发! 下面就一起来看看吧!

问题内容

我正在尝试解决可以在此处找到的 SPOJ 问题

以下是我的解决方案:

package main

import "fmt"
import "bufio"
import "os"

func main() {
    var n, k int
    var num int
    var divisible int

    in := bufio.NewReader(os.Stdin)

    fmt.Fscan(in, &n)
    fmt.Fscan(in, &k)

    for n > 0 {
        fmt.Fscan(in, &num)

        if num%k == 0 {
            divisible++
        }

        n--
    }

    fmt.Println(divisible)
}

代码工作正常。这里的问题是我在 SPOJ 中执行它时超时。

我最初只是使用fmt.Scan,但后来我遇到了[这个](https://groups.google.com/forum/#!topic/golang- nuts/W08rFBcHKbc)线程,该线程建议我使用它bufio来进行更快的输入扫描。

但我仍然遇到超时问题。我只是循环获取所有输入,并且在这个循环本身中我确定输入是否可整除。所以,我相信这不是循环,而是需要时间的输入扫描。如何改进这一点以更快地读取输入?还是其他地方的问题?

正确答案

您可以使用bufio.Scanner从输入中读取行。

而且由于我们一直在读取数字,我们可以创建一个高度优化的转换器来获取数字。我们应该避免使用Scanner.Text()which 创建 astring因为我们可以从 . 返回的原始字节中获取数字Scanner.Bytes()Scanner.Text()返回相同的标记,Scanner.Bytes()但它首先转换string为明显较慢的标记并生成“垃圾”并为 gc 工作。

所以这是一个转换器函数,它int从原始字节中获取一个:

func toInt(buf []byte) (n int) {
    for _, v := range buf {
        n = n*10 + int(v-'0')
    }
    return
}

toInt()是有效的[]byte,因为它包含数字的十进制格式的字符串表示的 UTF-8 编码字节序列,它仅包含'0'..'9'其 UTF-8 编码字节被一对一映射的范围内的数字(使用一个字节一位数)。从数字到字节的映射只是一个 shift:'0' -> 48'1' -> 49

使用这个完整的应用程序:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    var n, k, c int
    scanner := bufio.NewScanner(os.Stdin)

    scanner.Scan()
    fmt.Sscanf(scanner.Text(), "%d %d", &n, &k)

    for ;n > 0; n-- {
        scanner.Scan()
        if toInt(scanner.Bytes())%k == 0 {
            c++
        }
    }

    fmt.Println(c)
}

func toInt(buf []byte) (n int) {
    for _, v := range buf {
        n = n*10 + int(v-'0')
    }
    return
}

例如,此解决方案比调用快约 4 倍strconv.Atoi()

笔记:

在上述解决方案中,我假设输入是有效的,即它始终包含有效数字并且在第一个之后至少包含n行(这给了我们nk)。

如果输入在行后关闭n+1,我们可以使用简化for(我们甚至不需要递减和依赖n):

for scanner.Scan() {
    if toInt(scanner.Bytes())%k == 0 {
        c++
    }
}

今天关于《更快的输入扫描》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:Golang技术栈 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表