Возьмите строковый ввод, проанализируйте каждое слово для всех строчных букв и напечатайте каждое слово в строке, не алфавитные символы обрабатываются как разрыв между словами - PullRequest
0 голосов
/ 27 февраля 2019

Я пытаюсь взять строковый ввод, разобрать каждое слово в нижнем регистре и распечатать каждое слово в строке (в отсортированном порядке), игнорируя не алфавитные символы (количество слов также учитывается).Итак,

Пример ввода:

Adventures in Disneyland

Two blondes were going to Disneyland when they came to a fork in the
road. The sign read: "Disneyland Left."

So they went home.

Вывод:

a
adventures
blondes
came
disneyland
fork
going
home
in
left
read
road
sign
so
the
they
to
two
went
were
when

Моя программа:

        Scanner reader = new Scanner(file);
        ArrayList<String> words = new ArrayList<String>();
        while (reader.hasNext()) {
            String word = reader.next();
            if (word != "") {
                word = word.toLowerCase();
                word = word.replaceAll("[^A-Za-z ]", "");
                if (!words.contains(word)) {
                    words.add(word);
                }
            }
        }
        Collections.sort(words);
        for (int i = 0; i < words.size(); i++) {
            System.out.println(words.get(i));
        }

Это работает для ввода выше,но выводит неправильный вывод для такого ввода:

a  t\|his@ is$ a)( -- test's-&*%$#-`case!@|?

Ожидаемый вывод должен быть

a
case
his
is
s
t
test

Вывод, который я получаю,

*a blank line is printed first*
a
is
testscase
this

Итак,Моя программа, очевидно, не работает, так как scanner.next () принимает символы, пока не достигнет пробела, и считает, что это строка, тогда как все, что не является буквой, должно рассматриваться как разрыв между словами.Я не уверен, как мне удастся манипулировать методами сканера, чтобы разрывы считались не алфавитными символами, а не пробелами, поэтому я застрял прямо сейчас.

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

В другом ответе уже упоминались некоторые проблемы с вашим кодом.

Я предлагаю другой подход к вашим требованиям.Такие преобразования являются хорошим примером использования для Java Streams - он часто дает чистый код:

List<String> strs = Arrays.stream(input.split("[^A-Za-Z]+"))
    .map(t -> t.toLowerCase())
    .distinct()
    .sorted()
    .collect(Collectors.toList());

Вот шаги:

  1. Разделить строку на один или несколькопоследующие символы не являются алфавитными;

    input.split("[^A-Za-Z]+")
    

    Это дает токены , состоящие исключительно из буквенных символов.

  2. Перемещение по результирующему массиву с использованием Arrays.stream();

  3. Сопоставить каждый элемент с их строчными эквивалентами:

    .map(t -> t.toLowerCase())
    

    Используется языковой стандарт по умолчанию.Используйте toLowerCase(Locale) для явной установки локали.

  4. Удалите дубликаты, используя Stream.distinct().

  5. Сортируйте элементы в потоке, просто вызвавsorted();

  6. Соберите элементы в List с collect().


Если вам нужно прочитать егоиз файла вы можете использовать это:

Files.lines(filepath)
    .flatMap(line -> Arrays.stream(line.split("[^A-Za-Z]+")))
    .map(... // Et cetera

Но если вам нужно использовать Scanner, то вы можете использовать что-то вроде этого:

Scanner s = new Scanner(input)
    .useDelimiter("[^A-Za-z]+");
List<String> parts = new ArrayList<>();
while (s.hasNext()) {
    parts.add(s.next());
}

И затем

List<String> strs = parts.stream()
    .map(... // Et cetera
0 голосов
/ 27 февраля 2019

Не используйте == или != для сравнения String (s).Кроме того, выполните преобразование до , которое вы проверяете на пустое.Это,

if (word != "") {
    word = word.toLowerCase();
    word = word.replaceAll("[^A-Za-z ]", "");
    if (!words.contains(word)) {
        words.add(word);
    }
}

должно выглядеть примерно так:

word = word.toLowerCase().replaceAll("[^a-z ]", "").trim();
if (!word.isEmpty() && !words.contains(word)) {
    words.add(word);
}
...