

新闻资讯
技术学院本文介绍在算法竞赛等场景中,如何优雅、健壮地从标准输入读取指定数量的数值或字符串(如首行给出个数 n,随后 n 行为数据),并对比原始写法,提供更符合 go 语言惯用法的优化方案。
在算法题输入处理中,常见模式是:第一行给出数据个数 n,接下来 n 行依次为具体值(整数、浮点数或字符串)。原始代码使用 for { ... break } 循环配合手动计数,结构松散且未处理输入错误,可读性与鲁棒性均不足。
更推荐的做法是将循环逻辑收敛到 for 语句头部,利用 Go 的多重赋值和条件判断能力,使意图更清晰。同时,必须检查 fmt.Scanf 的返回错误——这是生产级和竞赛级代码的关键实践,避免因格式错误或 EOF 导致静默失败或 panic。
以下为优化后的标准模板(以读取 n 个整数为例):
package main
import "fmt"
func main() {
var nums []int
var count int
var err error
// 读取总数,支持换行符自动跳过(%d\n 隐式吸收)
for _, err = fmt.Scanf("%d\n", &count); err == nil && count > 0; count-- {
var x int
_, err = fmt.Scanf("%d\n", &x)
if err != nil {
break // 输入异常时立即退出,避免追加无效值
}
nums = append(nums, x)
}
if err != nil && err != fmt.EOF {
panic(fmt.Sprintf("input error: %v", err))
}
// 此时 nums 已包含全部有效输入
fmt.Println(nums) // 示例输出:[78 42 99]
}✅ 关键改进点说明:
? 扩展支持其他类型:
import"bufio" // ... scanner := bufio.NewScanner(os.Stdin) scanner.Scan() n, _ := strconv.Atoi(scanner.Text()) for i := 0; i < n; i++ { scanner.Scan() s := strings.TrimSpace(scanner.Text()) // 处理字符串 s }
? 注意事项:
掌握这种简洁、健壮、符合 Go 惯用法的输入模式,能显著提升算法题编码效率与稳定性。