概要
競プロでSwiftの標準入力が面倒だったので,C++のcin >> a
みたいな動作を実現するクラスを作ってみました.これで簡単に入力を受け取れます.
環境
Swift 5.1.3
実装
実際に作ったものがこちらです
import Foundation
infix operator >>>: MultiplicationPrecedence
protocol Initializable {
init?(_ description: String)
}
extension Int: Initializable {}
extension String: Initializable {}
class Input {
var inputs: [String] = [];
func read() {
self.inputs = readLine()!.components(separatedBy: " ")
self.inputs.reverse()
}
func pop() -> (String) {
if self.inputs.count == 0 {
self.read()
}
return self.inputs.popLast()!
}
@discardableResult
static func >>><T: Initializable> (cin: Input, right: inout T) -> (Input) {
right = T.init(cin.pop())!
return cin
}
@discardableResult
static func >>><T: Initializable> (cin: Input, right: inout [T]) -> (Input) {
for i in 0..<right.count {
right[i] = T.init(cin.pop())!
}
return cin
}
}
使い方
C++のcin
のように使います.次のコードはAtCoder Beginners Selection Aの回答例です.
let cin = Input()
var (a, b, c, s) : (Int, Int, Int, String) = (0, 0, 0, "")
cin >>> a >>> b >>> c >>> s
print(a + b + c, s)
C++のcin >> a
の>>
が>>>
になっただけのように使えます.ただし変数の型は指定する必要があり,またInt型とString型のみにしか対応していないので,必要に応じてメソッドを追加する必要があります.
配列に対応
配列への入力に対応しました.次のように
5
1 2 3 4 5
1行目に配列の大きさ,2行目以降にデータが与えられる入力の場合は
let cin = Input()
var N: Int = 0
cin >>> N
var A = [Int](repeating: 0, count: N)
cin >>> A
このように受け取ることができます.ちなみに2行目以降が改行区切りであっても同じように受け取れます.
おわりに
ジェネリクス使うとシンプルにできそう.使えました.