从文件中读取ArrayList。打印仅出现在ONCE的单词

时间:2017-10-13 02:02:01

标签: java arraylist

新手编码和Java,请善待:)

我正在为一所学校项目工作,我试图迭代我从文本文件中读到的ArrayList

我使用扫描仪将文件读入Collections.sort(),然后使用ArrayListArrayList进行排序,希望我可以使用下一个元素检查每个元素。如果元素与下一个元素相同,则忽略并继续,但如果this this is a a sentence sentence that does not not make sense a sentence not sentence not really really why not this a sentence not sentence a this really why 中的元素不是重复,则将其添加到新的ArrayList

因此,在阅读包含以下单词的文本文件时:

is that does make sense

新的public static void main (String[] args) throws FileNotFoundException { Scanner fileIn = new Scanner(new File("words.txt")); ArrayList<String> uniqueArrList = new ArrayList<String>(); ArrayList<String> tempArrList = new ArrayList<String>(); while (fileIn.hasNext()) { tempArrList.add(fileIn.next()); Collections.sort(tempArrList); } for (String s : tempArrList) { if(!uniqueArrList.contains(s)) uniqueArrList.add(s); else if (uniqueArrList.contains(s)) uniqueArrList.remove(s); Collections.sort(uniqueArrList); System.out.println(uniqueArrList); } 应为

[a, does, is, make, really, sense, that]

因为这些单词只出现一次。

Http.Request

这是我到目前为止所做的,但我一直以Http.post

结束

我希望有人可以告诉我我做错了什么:)

6 个答案:

答案 0 :(得分:1)

您的算法不正确,因为它会不断添加和删除uniqueArrList中的项目。因此,它会查找出现奇数次的单词,并且不关心要排序的列表。

您可以对列表进行一次排序(将sort移出循环),然后使用一个非常简单的策略:

  • 使用整数索引
  • 遍历列表
  • 检查当前索引处的单词与下一个索引处的单词
  • 如果单词不同,请打印当前单词,然后将索引提前一个
  • 如果单词相同,请向前走列表,直到看到不同的单词,然后使用该单词的位置作为循环索引的下一个值。

以下是一个示例实现:

Scanner fileIn = new Scanner(new File("words.txt"));
List<String> list = new ArrayList<>();
while (fileIn.hasNext()) {
    list.add(fileIn.next());
}           
Collections.sort(list);
int pos = 0;
while (pos != list.size()) {
    int next = pos+1;
    while (next != list.size() && list.get(pos).equals(list.get(next))) {
        next++;
    }
    if (next == pos+1) {
        System.out.println(list.get(pos));
    }
    pos = next;
}

Demo.

答案 1 :(得分:0)

此处的一个选项是在解析文件时维护字的哈希映射。然后,在末尾迭代该映射以获得仅出现一次的单词:

Scanner fileIn = new Scanner(new File("words.txt"));
Map<String, Integer> map = new HashMap<>();
ArrayList<String> uniqueArrList = new ArrayList<String>();

while (fileIn.hasNext()) {
    String word = fileIn.next():
    Integer cnt = map.get(word);
    map.put(word, cnt == null ? 1 : cnt.intValue() + 1);
}

// now iterate over all words in the map, adding unique words to a separate list
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    if (entry.getValue() == 1) {
        uniqueArrList.add(entry.getKey());
    }
}

答案 2 :(得分:0)

您当前的方法已接近,您应该在添加所有单词后进行一次排序。然后,您需要保留List的索引,以便测试相等的元素是否相邻。像,

List<String> uniqueArrList = new ArrayList<>();
List<String> tempArrList = new ArrayList<>();

while (fileIn.hasNext()) {
    tempArrList.add(fileIn.next());
}
Collections.sort(tempArrList);

for (int i = 1; i < tempArrList.size(); i++) {
    String s = tempArrList.get(i - 1);
    if (s.equals(tempArrList.get(i))) {
        // skip all equal and adjacent values
        while (s.equals(tempArrList.get(i)) && i + 1 < tempArrList.size()) {
            i++;
        }
    } else {
        uniqueArrList.add(s);
    }
}
System.out.println(uniqueArrList);

答案 3 :(得分:0)

最简单的方法是使用Set或HashSet,因为您忘记控制元素的重复。但是,如果必须使用列表,则无需对元素进行排序。只需在单词上迭代两次就可以了

List<String> uniqueWords = new ArrayList<>();
    for (int i = 0; i < words.size(); i++) {
        boolean hasDuplicate = false;
        for (int j = 0; j < words.size(); j++) {
            if (i != j) {
                if (words.get(i).equals(words.get(j))){
                    hasDuplicate = true;
                }
            }
        }
        if (!hasDuplicate) {
            uniqueWords.add(words.get(i))
        }
    }

答案 4 :(得分:0)

致电

时出现逻辑错误
else if (uniqueArrList.contains(s))
      uniqueArrList.remove(s); 

使用一个数组:

            Scanner fileIn = new Scanner(new File("words.txt"));
            ArrayList<String> tempArrList = new ArrayList<String>();

            while (fileIn.hasNext()) {
                tempArrList.add(fileIn.next());
            }

            Collections.sort(tempArrList);
            System.out.println(tempArrList);

            if (tempArrList.size() > 1) {
                for (int i = tempArrList.size() - 1; i >= 0; i--) {
                    String item = tempArrList.remove(i);
                    if (tempArrList.removeAll(Collections.singleton(item))) {
                        if (i > tempArrList.size()) {
                            i = tempArrList.size();
                        }
                    } else {
                        tempArrList.add(item);
                    }
                }
            }

            System.out.println(tempArrList);

我希望它可以帮到你!如果有帮助,请反馈。

答案 5 :(得分:0)

仅为了完整性,使用distinct()中间操作,这个问题对于Java 8 Streams来说是毫无疑问的:

public static void main (String[] args) throws FileNotFoundException {    
    final Scanner fileIn = new Scanner(new File("words.txt"));
    final List<String> tempArrList = new ArrayList<String>();

    while (fileIn.hasNext()) {
        tempArrList.add(fileIn.next());
    }

    final List<String> uniqueArrList = tempArrList.stream().distinct().collect(Collectors.toList());

    System.out.println(uniqueArrList);
}

此代码打印(对于提供的输入):

[this,is,a,sentence,that,does,not,make,sense,really,why]

如果我们想要对所有单词进行排序,只需将sorted()添加到流管道即可:

tempArrList.stream().sorted().distinct().collect(Collectors.toList());

我们获得了一个排序(和漂亮)的输出:

[a,does,is,make,not,really,sense,sentence,that,this,why]