質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.83%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

AtCoderで fmt.Scanと bufio.Scanner の読み取り差でエラーが生じる原因を知りたい

koooyooo
koooyooo

総合スコア3

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

2回答

0グッド

1クリップ

1216閲覧

投稿2023/01/03 03:32

編集2023/01/03 03:49

前提

AtCoderで初心者向けの課題を解いています。
白昼夢 の課題を Goで実装しているのですが、
標準入力の受け取り方によって 全問AC(正答)の場合と、半数が WA(誤答)の場合に分かれます。

具体的には ① fmt.Scan で読み取ると正答となり、② bufio.Scanner で読み取ると誤答が混ざります。
なぜ後者だと誤答が紛れ込むのかが知りたいです。

尚、その際の入力パターンは不明です。

実現したいこと

  • bufio.Scanner を用いて処理した場合の問題点を知りたい
  • bufio.Scanner をどの様に用いれば正答を得られるのか知りたい

発生している問題・エラーメッセージ

  • 後述のコードで、fmt.Scan で読み込む readA() 関数を用いると全問正答 (AC) となるが、② bufio.Scanner で読み込む readB()を用いると 19パターン中 8パターン で (WA) が紛れてしまう
  • 繰り返しになるが、AtCoder側の入力パターンは不明

該当のソースコード

go

1// 白昼夢 2// https://atcoder.jp/contests/abs/tasks/arc065_a 3 4package main 5 6import ( 7 "bufio" 8 "fmt" 9 "os" 10 "strings" 11) 12 13func main() { 14 var str = readB() // readA() では正答、readB() では誤答が混ざる(AC x 11, WA x 8) 15 16 if check(str) { 17 fmt.Print("YES") 18 } else { 19 fmt.Print("NO") 20 } 21} 22 23func check(line string) bool { 24 keywords := []string{"dream", "dreamer", "erase", "eraser"} 25ChallengeLoop: 26 for line != "" { 27 for _, k := range keywords { 28 if strings.HasSuffix(line, k) { 29 line = strings.TrimSuffix(line, k) 30 continue ChallengeLoop 31 } 32 } 33 return false 34 } 35 return true 36} 37 38func readA() string { 39 var str string 40 fmt.Scan(&str) 41 return str 42} 43 44func readB() string { 45 lines := read() 46 var str = "" 47 if len(lines) > 0 { 48 elm := strings.Split(strings.TrimSpace(lines[0]), " ") 49 str = elm[0] 50 } 51 return str 52} 53 54func read() []string { 55 s := bufio.NewScanner(os.Stdin) 56 var lines []string 57 for s.Scan() { 58 lines = append(lines, s.Text()) 59 } 60 return lines 61} 62

試したこと

  • fmt.Scan は標準入力にスペースが含まれる場合、トークン分割して最初のトークンを返す仕様なので、bufio.Scannerを用いる readB()内でも、読み取った最初の1行に対し、スペースで trimした後、最初のトークンを返すようにしている
  • readB() の実装を以下のように単純化しても結果は変わらなかった
func readB() string { s := bufio.NewScanner(os.Stdin) s.Scan() return s.Text() }

補足情報(FW/ツールのバージョンなど)

  • go 1.14

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答2

1

自己解決

bufio.Scanner の初期バッファが不足していることが原因でした。以下のコードで解決しました。

go

1func read() []string { 2 buff := make([]byte, 100000) 3 s := bufio.NewScanner(os.Stdin) 4 s.Buffer(buff, 100000) // バッファを設定 5 var lines []string 6 for s.Scan() { 7 lines = append(lines, s.Text()) 8 } 9 return lines 10}

投稿2023/01/04 13:46

koooyooo

総合スコア3

yuma.inaura👍を押しています

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

1

原因は分からないですが bufio.NewScanner は繰り返しの読み込みのようなので、1個の入力だけが与えられるこの問題には合ってなさそうですね

投稿2023/01/03 10:18

yuma.inaura

総合スコア1432

koooyooo👍を押しています

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

koooyooo

2023/01/03 15:09

ありがとうございます。 おっしゃるとおりで、この問題には不要ですね。原因が分からない内は `fmt.Scan` を使っておこうと思います。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.83%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。