Могу ли я "начать заново" Java-сканер? - PullRequest
0 голосов
/ 04 декабря 2018

Можно ли снова запустить сканер с начала его ввода, опять же?

Контекст: я только что узнал, что 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)

Но одно интересное различие между этими двумя задачами состоит в том, что, хотя мне все равно, откуда берутся цифры в первой части, мне нужно a 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 голосов
/ 04 декабря 2018

Если вы просто планируете многократно читать один и тот же ввод, откройте его как RandomAccessFile и seek для начала каждой итерации.

Конечно, ваш алгоритм предполагает ограниченный ввод.Что делать, если вход состоит из одной строки, содержащей «+1»?

0 голосов
/ 04 декабря 2018

Если сканер может быть перезагружен, будет две возможности:

1) Каждый раз, когда вы сбрасываете, он снова начинает чтение из файла.Он не дает никаких преимуществ по сравнению с созданием нового каждый раз.

2) Сохраняет все считанные данные в оперативной памяти.Но вы можете сохранить его и сами.Часто это будет более эффективно.В этом случае вы можете хранить целое число вместо строки, что экономит память.

Если вы хотите просто не закрывать и не открывать файл каждый раз, вы можете использовать некоторый API-интерфейс более низкого уровня, такой как RandomAccessFile , который можно сбросить с помощью seek(0).

Причина, по которой Scanner не имеет метода seek, заключается в том, что он принимает не только файл, но и любой InputStream, такой как System.in, который не можетчитать снова по замыслу.

...