我可以“重新开始” java扫描仪吗?

时间:2018-12-03 23:03:18

标签: java kotlin io java.util.scanner

是否有一种方法可以使扫描仪再次从其输入开始?

上下文:我刚刚得知https://adventofcode.com/是一回事。

第一个任务很简单(就像第一个任务经常这样)。

为您提供了一系列带符号前缀的(+-)整数值

-7
+16
+5
[...]

并需要添加它们。

没什么。

task01.kts

import java.util.*

val scanner = Scanner(System.`in`)

private var total = 0
while(scanner.hasNext()){
    val number = scanner.nextInt()
    total += number
}

println(total)

第二项任务指出,读取的输入会被重复一遍又一遍,我们对第一个total会被访问两次感兴趣。

同样,非常简单:

task02.kts

import java.util.*
import java.io.File
import Task02.Result.*

sealed class Result{
    object None: Result()
    data class Found(val duplicate:Int):Result()
}

if(args.size < 1) throw IllegalStateException("please provide input file as first arg")

val input = File(args[0])

private var total = 0
private val seen = mutableSetOf(0)

private var result: Result = None
while(result is None){
    val scanner = Scanner(input)
    while(scanner.hasNext()){
        val number = scanner.nextInt()
        total += number

        if(seen.contains(total)){
            result = Found(total)
            break;
        }
        else seen.add(total)
    }
}

println((result as Found).duplicate)

但这两个任务之间的一个有趣的区别是,尽管我不在乎第一部分中的数字来自何处,但是我 中第二个是File

这让我开始思考。是否有“环绕式扫描仪”之类的东西?

我可以手动重置扫描仪的指针吗?

或者我可以链接扫描程序,使第一个扫描程序看到的所有内容(包括它跳过的内容)都传递给第二个扫描程序吗?

你知道吗?

       Scanner1                    Scanner2
[ O | L | L | E | H ]        [   |   |   |   |   ]
[   | O | L | L | E ]        [   |   |   |   | H ]
[   |   | O | L | L ]        [   |   |   | E | H ]
[   |   |   | O | L ]        [   |   | L | E | H ]
[   |   |   |   | O ]        [   | L | L | E | H ]
[   |   |   |   |   ]        [ O | L | L | E | H ]

还是其他类似的东西?

我有一个预感,不是因为我能想到的大多数东西都需要缓存所有输入(取决于输入大小,这可能并不合理),但是我仍然很好奇是否没有没什么事。

2 个答案:

答案 0 :(得分:3)

如果可以重置扫描仪,则有两种可能性:

1)每次重置时,它将重新开始从文件读取。每次创建一个新的都没有任何好处。

2)将所有读取的数据保存在RAM中。但是您也可以自己保存它。通常它会更高效。在这种情况下,您可以存储整数而不是字符串,这样可以节省内存。

如果您不想每次都关闭并重新打开文件,则可以使用一些较低级别的文件专用API,例如RandomAccessFile,可以使用seek(0)进行重置。

Scanner没有seek方法的原因是,它不仅接受文件,而且还接受InputStream之类的System.in,而这些private static Map<Integer, Integer> memo = new HashMap<>(); public static int fibonacci(int n) { if(n == 0) { return 0; } if(n <= 2) { return 1; } if(memo.containsKey(n)) { return memo.get(n); } int result = fibonacci(n - 1) + fibonacci(n - 2); memo.put(n, result); return result; } 不能被设计再次读取。

答案 1 :(得分:1)

如果您打算重复读取相同的输入,则在每次迭代开始时分别以RandomAccessFileseek的形式打开它。

当然,您的算法假设输入是受约束的。如果输入包含一行包含“ +1”的行,怎么办?