输入字符串,将每个单词解析为所有小写字母并将每个单词打印在一行上,非字母字符被视为单词之间的分隔符

时间:2019-02-27 00:09:18

标签: java string algorithm parsing java.util.scanner

我试图输入一个字符串,将每个单词解析为所有小写字母,然后将每个单词打印在一行上(按排序顺序),而忽略非字母字符(也算单字母单词)。因此,

样本输入:

execute()

输出:

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

因此,我的程序显然无法正常工作,因为scan.next()会接受字符,直到碰到空白并认为该字符串是字符串,而任何非字母的字符都应视为单词之间的中断。我不确定如何才能操作Scanner方法,以便将换行符视为非字母字符而不是空格,因此这就是我现在遇到的问题。

2 个答案:

答案 0 :(得分:2)

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

我建议另一种解决您的需求的方法。这样的转换对于Java Streams是一个很好的用例–它通常会产生干净的代码:

false

以下是步骤:

  1. 用一个或多个后续字符(不是字母)来分隔字符串;

    GetDoubleFromUser

    这会产生仅包含字母字符的令牌

  2. 使用double greaterThan10 = GetDoubleFromUser("Enter a number greater than 10: ", i => i > 10); 遍历结果数组;

  3. 将每个元素映射为它们的小写字母:

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

    使用默认语言环境。使用input.split("[^A-Za-Z]+") 显式设置区域设置。

  4. 使用Arrays.stream()丢弃重复项。

  5. 只需调用.map(t -> t.toLowerCase()) ;

  6. 即可对流中的元素进行排序
  7. 使用toLowerCase(Locale)将元素收集到Stream.distinct()中。


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

sorted()

但是,如果您需要使用List,则可以使用以下内容:

collect()

然后

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

答案 1 :(得分:0)

请勿使用==!=来比较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);
}