采用字符串输入,将每个单词解析为全部小写,并将每个单词打印在一行上,非字母字符被视为单词之间的中断



我正在尝试接受字符串输入,将每个单词解析为所有小写字母,并在一行上打印每个单词(按排序顺序),忽略非字母字符(单个字母单词也计数)。所以

示例输入:

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() 会接收字符,直到它到达空格并认为这是一个字符串,而任何不是字母的东西都应该被视为单词之间的中断。我不确定我如何能够操作 Scanner 方法,以便将中断视为非字母字符而不是空格,所以这就是我现在陷入困境的地方。

另一个答案已经提到了代码的一些问题。

我建议另一种方法来满足您的要求。这样的转换是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. 元素收集到带有collect()List中。


如果您需要从文件中读取它,您可以使用以下内容:

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

不要使用==!=来比较String。此外,在检查空之前执行转换。这

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);
}

最新更新