9

我必须使用 Java 计算文本文档中唯一单词的数量。首先,我必须去掉所有单词中的标点符号。我使用Scanner该类扫描文档中的每个单词并输入一个 String ArrayList

所以,下一步就是我遇到问题的地方!如何创建一个可以计算数组中唯一字符串数量的方法?

例如,如果数组包含apple、bob、apple、jim、bob;此数组中唯一值的数量为 3。


public countWords() {
    try {
        Scanner scan = new Scanner(in);
        while (scan.hasNext()) {
            String words = scan.next();
            if (words.contains(".")) {
                words.replace(".", "");
            }
            if (words.contains("!")) {
                words.replace("!", "");
            }
            if (words.contains(":")) {
                words.replace(":", "");
            }
            if (words.contains(",")) {
                words.replace(",", "");
            }
            if (words.contains("'")) {
                words.replace("?", "");
            }
            if (words.contains("-")) {
                words.replace("-", "");
            }
            if (words.contains("‘")) {
                words.replace("‘", "");
            }
            wordStore.add(words.toLowerCase());
        }
    } catch (FileNotFoundException e) {
        System.out.println("File Not Found");
    }
    System.out.println("The total number of words is: " + wordStore.size());
}
4

9 回答 9

24

你可以使用 Set 吗?如果是这样,您的HashSet可能会解决您的问题。HashSet不接受重复。

HashSet noDupSet = new HashSet();
noDupSet.add(yourString);
noDupSet.size();

size()方法返回唯一单词的数量。

如果你必须真的ArrayList只使用,那么实现的一种方法可能是,

1) Create a temp ArrayList
2) Iterate original list and retrieve element
3) If tempArrayList doesn't contain element, add element to tempArrayList
于 2012-10-04T03:50:11.003 回答
17

Java 8开始,您可以使用Stream

在您添加元素后ArrayList

long n = wordStore.stream().distinct().count();

它将您转换ArrayList为流,然后仅计算不同的元素。

于 2016-02-05T12:12:50.023 回答
3

我建议使用HashSetadd这会在调用方法时自动过滤重复项。

于 2012-10-04T03:58:53.660 回答
2

尽管我相信 set 是最简单的解决方案,但您仍然可以使用原始解决方案,只需添加一个 if 语句来检查列表中是否已经存在值,然后再进行添加。

if( !wordstore.contains( words.toLowerCase() )
   wordStore.add(words.toLowerCase());

那么列表中的单词数就是唯一单词的总数(即: wordStore.size() )

于 2012-10-04T04:06:23.273 回答
1

这种通用解决方案利用了 Set 抽象数据类型不允许重复的事实。Set.add() 方法特别有用,因为它返回一个布尔标志,指示“添加”操作是否成功。HashMap 用于跟踪每个原始元素的出现。该算法可适用于此类问题的变体。该解决方案产生 O(n) 性能..

public static void main(String args[])
{
  String[] strArray = {"abc", "def", "mno", "xyz", "pqr", "xyz", "def"};
  System.out.printf("RAW: %s ; PROCESSED: %s \n",Arrays.toString(strArray), duplicates(strArray).toString());
}

public static HashMap<String, Integer> duplicates(String arr[])
{

    HashSet<String> distinctKeySet = new HashSet<String>();
    HashMap<String, Integer> keyCountMap = new HashMap<String, Integer>();

    for(int i = 0; i < arr.length; i++)
    {
        if(distinctKeySet.add(arr[i]))
            keyCountMap.put(arr[i], 1); // unique value or first occurrence
        else
            keyCountMap.put(arr[i], (Integer)(keyCountMap.get(arr[i])) + 1);
    }     

    return keyCountMap; 
} 

结果:

RAW:[abc,def,mno,xyz,pqr,xyz,def];已处理:{pqr=1,abc=1,def=2,xyz=2,mno=1}

于 2016-09-26T16:03:23.783 回答
0

您也可以创建 HashTable 或 HashMap。键将是您的输入字符串,值将是该字符串在您的输入数组中出现的次数。O(N) 时间和空间。

解决方案2:

对输入列表进行排序。相似的字符串将彼此相邻。比较 list(i) 和 list(i+1) 并计算重复的数量。

于 2012-10-04T03:51:25.070 回答
0

简而言之,您可以按以下方式进行...

    ArrayList<String> duplicateList = new ArrayList<String>();
    duplicateList.add("one");
    duplicateList.add("two");
    duplicateList.add("one");
    duplicateList.add("three");

    System.out.println(duplicateList); // prints [one, two, one, three]

    HashSet<String> uniqueSet = new HashSet<String>();

    uniqueSet.addAll(duplicateList);
    System.out.println(uniqueSet); // prints [two, one, three]

    duplicateList.clear();
    System.out.println(duplicateList);// prints []


    duplicateList.addAll(uniqueSet);
    System.out.println(duplicateList);// prints [two, one, three]
于 2012-10-04T04:06:11.387 回答
0
public class UniqueinArrayList {

    public static void main(String[] args) { 
        StringBuffer sb=new StringBuffer();
        List al=new ArrayList();
        al.add("Stack");
        al.add("Stack");
        al.add("over");
        al.add("over");
        al.add("flow");
        al.add("flow");
        System.out.println(al);
        Set s=new LinkedHashSet(al);
        System.out.println(s);
        Iterator itr=s.iterator();
        while(itr.hasNext()){
            sb.append(itr.next()+" ");
        }
        System.out.println(sb.toString().trim());
    }

}
于 2013-02-08T22:16:51.607 回答
0

3种不同的可能解决方案:

  1. 按照上面的建议使用 HashSet。

  2. 创建一个临时ArrayList并仅存储唯一元素,如下所示:

    public static int getUniqueElement(List<String> data) {
        List<String> newList = new ArrayList<>();
        for (String eachWord : data)
        if (!newList.contains(eachWord))
            newList.add(eachWord);
        return newList.size();
    }
    
  3. Java 8 解决方案

    long count = data.stream().distinct().count();
    
于 2017-05-28T12:04:51.663 回答