Java 我如何计算重复的单词?

Java 我如何计算重复的单词?,java,algorithm,word-count,Java,Algorithm,Word Count,给定一个1GB(非常大)的文件,其中包含单词(有些重复),我们需要读取该文件并输出每个单词的重复次数。请让我知道我的解决方案是否高效 (为了简单起见,假设我们已经捕获了arraylist中的单词) 我认为大O(n)是“n”。我说的对吗 public static void main(String[] args) { ArrayList al = new ArrayList(); al.add("math1"); al.ad

给定一个1GB(非常大)的文件,其中包含单词(有些重复),我们需要读取该文件并输出每个单词的重复次数。请让我知道我的解决方案是否高效

(为了简单起见,假设我们已经捕获了
arraylist
中的单词)

我认为大O(n)是“n”。我说的对吗

public static void main(String[] args) {

            ArrayList al = new ArrayList();
            al.add("math1");
            al.add("raj1");
            al.add("raj2");
            al.add("math");
            al.add("rj2");

            al.add("math");
            al.add("rj3");
            al.add("math2");
            al.add("rj1");
            al.add("is");
            Map<String,Integer> map= new HashMap<String,Integer>();

            for (int i=0;i<al.size();i++)
            {
                String s= (String)al.get(i);

                    map.put(s,null);

            }
            for (int i=0;i<al.size();i++)
            {
                String s= (String)al.get(i);
                if(map.get(s)==null)
                    map.put(s,1);
                else
                {
                    int count =(int)map.get(s);
                        count=count+1;
                        map.put(s,count);
                }


            }

            System.out.println("");
        }
publicstaticvoidmain(字符串[]args){
ArrayList al=新的ArrayList();
新增(“第1条”);
al.添加(“raj1”);
al.添加(“raj2”);
加上(“数学”);
新增(“rj2”);
加上(“数学”);
新增(“rj3”);
新增(“第2条”);
新增(“rj1”);
添加(“is”);
Map Map=newhashmap();

对于(int i=0;i理论上,由于HashMap访问通常是O(1),我猜您的算法是O(n),但实际上有几个低效之处。理想情况下,您只需在文件内容上迭代一次,在读取时处理(即计数)单词。无需将整个文件内容存储在内存中(您的ArrayList)。您将内容循环三次—一次读取内容,第二次和第三次读取上面代码中的两个循环。特别是,上面代码中的第一个循环完全没有必要。最后,您使用HashMap的速度将比需要的慢,因为构建时的默认大小非常小,并且必须在内部增长结盟了很多次,强迫每次哈希表的重建。最好将它从适合你期望的大小开始。你还必须考虑负载因子。

< P>理论上,由于HashMap访问通常是O(1),所以我猜你的算法是O(n)。,但实际上有几个低效之处。理想情况下,您只需在文件内容上迭代一次,在读入时处理(即计数)单词。无需将整个文件内容存储在内存中(您的ArrayList)。您将内容循环三次—一次读取内容,第二次和第三次读取上面代码中的两个循环。特别是,上面代码中的第一个循环完全没有必要。最后,您使用HashMap的速度将比需要的慢,因为构建时的默认大小非常小,并且必须在内部增长结盟了很多次,强迫每次哈希表的重建。最好将它从适合你期望的大小开始。你还必须考虑负载因子。

你应该只用一次单词读文件。

无需预先设置空值-您可以在主循环中执行此操作


在这两种情况下,复杂度实际上都是O(n),但您希望使常数尽可能小。(O(n)=1000*O(n,右:)

您应该只使用单词阅读一次文件

无需预先设置空值-您可以在主循环中执行此操作


在这两种情况下,复杂性实际上都是O(n),但您希望使常数尽可能小。(O(n)=1000*O(n,右:)

要回答您的问题,首先,您需要了解HashMap是如何工作的。它由多个存储桶组成,每个存储桶都是一个链表。如果由于散列,另一对存储桶需要占用同一个存储桶,它将被添加到链表的末尾。因此,如果map具有高负载因子,则搜索和插入将不会是O(1)此外,如果地图负载因子超过预定义的负载因子(默认值为0.75),整个地图将被重新灰化

这是JavaDoc的摘录:

映射中的预期条目数及其加载因子应为 在设置其初始容量时应予以考虑,以便 尽量减少再灰化操作的次数。如果初始容量为 大于最大条目数除以负载系数, 不会发生任何再灰化操作

因此,我建议您预先定义地图容量,猜测每个单词都是唯一的:

Map<String,Integer> map= new HashMap<String,Integer>(al.size());
Map Map=newhashmap(al.size());

如果没有这一点,你的解决方案是不够有效的,虽然它仍然有一个线性近似O(3n),因为由于重新灰化的摊销,插入元素将花费3n而不是n。

要回答您的问题,首先,您需要了解HashMap是如何工作的。它由多个存储桶组成,每个存储桶都是一个链表。如果由于散列,另一对元素需要占用同一个存储桶,它将被添加到链表的末尾。因此,如果地图具有高负载因子,搜索和插入将不再是O(1),算法将变得低效。此外,如果地图负载因子超过预定义的负载因子(默认为0.75),整个地图将被重新灰化

这是JavaDoc的摘录:

映射中的预期条目数及其加载因子应为 在设置其初始容量时应予以考虑,以便 尽量减少再灰化操作的次数。如果初始容量为 大于最大条目数除以负载系数, 不会发生任何再灰化操作

因此,我建议您预先定义地图容量,猜测每个单词都是唯一的:

Map<String,Integer> map= new HashMap<String,Integer>(al.size());
Map Map=newhashmap(al.size());

如果没有这一点,您的解决方案是不够有效的,尽管它仍然具有线性近似O(3n),因为由于重新灰化的摊销,插入元素将花费3n而不是n。我认为您可以比使用HashMap做得更好

hashmap解决方案值得思考

您的ANWSER是可以接受的,但考虑到这一点:为了简单起见,假设您一次读取一个字节的文件到一个String缓冲区,直到您命中一个空格。此时您将调用toString()将String缓冲区转换为一个字符串。然后检查字符串是否在HasMMAP中。