【问题标题】:Counting even and odd number of letters in words计算单词中的偶数和奇数个字母
【发布时间】:2017-12-07 00:01:35
【问题描述】:

我目前正在尝试计算文本文件中有多少单词有偶数和奇数个字符,但我似乎无法让它工作。到目前为止我已经完成了

    int countEven = 0;
    int countOdd = 0;
    for (int i = 0; i <latinLength.length(); i++) {
        if (Character.isLetter(latinLength.charAt(i))) {
            countEven++;
        } else {
            countOdd++;
        }
    }
    System.out.println("Total number of unique even words in Latin names = " + countEven);
    System.out.println("Total number of unique odd words in Latin names = " + countOdd);
}

我认为我做错了什么是我没有访问文本文件的正确部分。我确实有一个获取我想要的信息的函数,即 getLatinName,但我不确定如何正确实现它

    String tempLatinName = " ";
    String latinLength = " ";
    int letters = 0;
    for (int i = 0; i < info.size(); i++) {
        tempLatinName = info.get(i).getLatinName();      
        latinLength = tempLatinName.replace(" ","");
        letters += latinLength.length();
    }
    System.out.println("Total number of letters in all Latin names = " + letters);

我已经编辑了代码以显示我在尝试计算有多少个单词有奇数个和偶数个字符之前所做的操作,上面的代码是计算每个单词中的字符总数,然后给我一个总数

/**
*
* @author g_ama
*/
import java.io.*;
import java.util.*;

public class Task1 {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) throws FileNotFoundException, IOException {

    BufferedReader reader = new BufferedReader(new FileReader("shark-data.txt"));
    String line;
    List<Shark> info = new ArrayList<>();
    while ((line = reader.readLine()) != null) {
        String[] data = line.split(":");

        int MaxLength = Integer.parseInt(data[2]);
        int MaxDepth = Integer.parseInt(data[3]);
        int MaxYoung;
        try {
            MaxYoung = Integer.parseInt(data[4]);
        } catch (Exception X) {
            MaxYoung = -1;
        }
        int GlobalPresence = Integer.parseInt(data[5]);

        ArrayList<String> OceanicRegion = new ArrayList<>();
        String[] Region = data[6].split(",");
        for (String Element : Region) {
            OceanicRegion.add(Element);
        }

        Shark shark = new Shark(data[0], data[1], MaxLength, MaxDepth, MaxYoung, GlobalPresence, OceanicRegion);

        info.add(shark);
    }
    Collections.sort(info);
    System.out.println("The three largest sharks");
    System.out.println(info.get(info.size() - 1).getCommonName() + ", " + info.get(info.size() - 1).MaxLength + " cm");
    System.out.println(info.get(info.size() - 2).getCommonName() + ", " + info.get(info.size() - 2).MaxLength + " cm");
    System.out.println(info.get(info.size() - 3).getCommonName() + ", " + info.get(info.size() - 3).MaxLength + " cm");

    System.out.println("The three smallest sharks");
    System.out.println(info.get(0).getCommonName() + ", " + info.get(0).MaxLength + " cm");
    System.out.println(info.get(1).getCommonName() + ", " + info.get(1).MaxLength + " cm");
    System.out.println(info.get(2).getCommonName() + ", " + info.get(2).MaxLength + " cm");

    //count total characters for Latin Name
    String tempLatinName = " ";
    String latinLength = " ";
    int letters = 0;
    for (int i = 0; i < info.size(); i++) {
        tempLatinName = info.get(i).getLatinName();
        latinLength = tempLatinName.replace(" ", "");
        letters += latinLength.length();
    }
    System.out.println("Total number of letters in all Latin names = " + letters);

    //count even or odd words
    int countEven = 0;
    int countOdd = 0;
    for (int i = 0; i < latinLength.length(); i++) {
        if (Character.isLetter(latinLength.charAt(i))) {
            countEven++;
        } else {
            countOdd++;
        }
    }
    System.out.println("Total number of unique even words in Latin names = " + countEven);
    System.out.println("Total number of unique odd words in Latin names = " + countOdd);
}

}

【问题讨论】:

  • 请显示示例输入、所需的输出以及您的程序当前输出的内容。也尝试创建一个minimal reproducible example
  • 你没有做你打算做的事情。你只是在数字母和非字母。多想想问题的逻辑。
  • 您需要将文本拆分为单词tokenize)。之后,对于每个单词,计算字符数。如果是偶数,您可以将countEven 加一。如果数字是奇数,则将countOdd 加一。
  • latinLength 似乎不是一个很好的字符串名称。
  • 我刚刚编辑了它

标签: java for-loop if-statement


【解决方案1】:

说明

目前您只计算您的文本有多少个字母非字母。这当然不是偶数词奇数词的数量。

例如,如果你有一个像这样的词

test12foo!$bar

您的代码当前将输出

countEven => 10  // Amount of letters (testfoobar)
countOdd  => 4   // Amount of non-letters (12!$)

将此与您的 if-condition 进行比较:

if (Character.isLetter(latinLength.charAt(i))) {
    countEven++;
} else {
    countOdd++;
}

你想要的是计算你的单词长度是偶数还是奇数的频率,所以假设像这样的单词

test     // length 4, even
foo      // length 3, odd
bartest  // length 7, odd

那么你想要

countEven => 1 // (test)
countOdd  => 2 // (foo, bartest)

解决方案

相反,您需要将文本拆分单词(标记化)。之后,您需要计算每个单词的字符数。如果是这样,您可以将countEven 加一。同样countOdd++ 如果是奇数。

核心会是这个条件

word.length() % 2 == 0

如果单词的长度为 even,则为 true,如果为奇数,则为 false。您可以自己轻松验证这一点(% 返回除法后的余数,在这种情况下为01)。

假设您的文本结构很简单,单词总是用whitespace 分隔,例如

test foo bar John Doe

你的所有代码可能看起来像

Path path = Paths.get("myFile.txt");
AtomicInteger countEven = new AtomicInteger(0);
AtomicInteger countOdd = new AtomicInteger(0);
Pattern wordPattern = Pattern.compile(" ");

Files.lines(path)                         // Stream<String> lines
    .flatMap(wordPattern::splitAsStream)  // Stream<String> words
    .mapToInt(String::length)             // IntStream length
    .forEach(length -> {
        if (length % 2 == 0) {
            countEven.getAndIncrement();
        } else {
            countOdd.getAndIncrement();
        }
    });


System.out.println("Even words: " + countEven.get());
System.out.println("Odd words: " + countOdd.get());

或者没有Stream 的所有东西:

Path path = Paths.get("myFile.txt");

List<String> lines = Files.readAllLines(path);
List<String> words = new ArrayList<>();

// Read words
for (String line : lines) {
    String[] wordsOfLine = line.split(" ");
    words.addAll(Arrays.asList(wordsOfLine));
}

// Count even and odd words
int countEven = 0;
int countOdd = 0;
for (String word : words) {
    if (word.length() % 2 == 0) {
        countEven++;
    } else {
        countOdd++;
    }
}

System.out.println("Even words: " + countEven);
System.out.println("Odd words: " + countOdd);

已根据您的特定代码进行了调整

由于您刚刚添加了特定代码,我将添加一个适合它的解决方案。

在您的代码中,列表info 包含所有Sharks。从这些鲨鱼中,您要考虑的词由Shark#getLatinName 表示。所以你需要做的就是这样:

List<String> words = info.stream()  // Stream<Shark> sharks
    .map(Shark::getLatinName)       // Stream<String> names
    .collect(Collectors.toList());

您可以完全按照其他代码示例中所示使用此words。或者您不需要将所有内容收集到新列表中,您可以直接留在Stream 并继续使用前面显示的流方法。总而言之:

AtomicInteger countEven = new AtomicInteger(0);
AtomicInteger countOdd = new AtomicInteger(0);

info.stream()                             // Stream<Shark> sharks
    .map(Shark::getLatinName)             // Stream<String> names
    .mapToInt(String::length)             // IntStream length of names
    .forEach(length -> {
        if (length % 2 == 0) {
            countEven.getAndIncrement();
        } else {
            countOdd.getAndIncrement();
        }
    });

System.out.println("Even words: " + countEven);
System.out.println("Odd words: " + countOdd);

并将其替换为代码中的该部分:

//count even or odd words

(substitute here)

【讨论】:

  • 而不是做 line.split ,因为我之前已经这样做了,因为他们在每个部分之间都有“:”,是否可以做 String[] wordsOfLine = getLatinName?或类似的东西,因为我只是想对文本文件中的一组文本执行此操作,如果我对我的意思的解释不清楚,我很抱歉,不是最好的解释事情
  • 当然,如果你以前做过文件读取和拆分部分,你可以完全交换。在某些时候,您应该准备好某种List&lt;String&gt; words,不是吗?只需跳过我只设置该数据结构的所有内容。或者在Stream 方法中,只需跳过前两个表达式,直接以words.stream().mapToInt(String::length).forEach(...) 开头。
  • 我的意思是重要的部分是if-else 的最后一点。这决定了单词的长度是奇数还是偶数:word.length() % 2 == 0,如果true,则为even,如果false,则为odd
  • 到目前为止,我了解您所做的一切并说,我只是不确定如何编写它以适应我到目前为止所做的代码,我有 但我猜我做的不同?除非我查看我的代码的错误部分并进行比较? gyazo.com/17b9d8ab174b94da48499fc668d6bc6d 这是我比较你的代码的第一位的截图,问题是我明白你现在是怎么做的,但我不知道如何链接它来选择我的 .txt 文件的特定部分想让它说它是偶数还是奇数,因为我不希望它对整个文本文件这样做
  • data 是否包含所有单词?那就让这成为我在上一届 cmets 中谈到的words。将Arrays.stream(data) 用于Stream 方法,其他方法无需修改即可工作。请注意,您读取文件的方式是 legacy,现在使用 NIO(就像在我的方法中看到的那样)。
猜你喜欢
  • 2022-06-21
  • 1970-01-01
  • 1970-01-01
  • 2013-12-10
  • 2020-11-16
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 2023-02-11
相关资源
最近更新 更多