2017-05-06 76 views
2

我试图从文本文件输入数千个字符串,然后能够对最流行的字符串进行排名。 我迷失在如何跟踪每个字符串有多少。字符串在Java哈希表中出现的次数

我是否需要实现另一个ADT,如链表? 我不允许使用除ArrayList之外的java库。

这是我到目前为止。

public class StudentTrends implements Trends { 
    int entries = 0; 
    //ArrayList<Integer> list; 
    String[] table; 
    int arraySize; 

public StudentTrends() { 
    //this.list = new ArrayList<Integer>(); 
    this.table = new String[10]; 
    Arrays.fill(table, "-1"); 
} 

//Method I'm having trouble with 
@Override 
public void increaseCount(String s, int amount) { 
    int key = horner(s); 

    if(table[key] == null){ 
     entries++; 
     //table[key] = table[key]; 
    } 
    else{ 
     amount += 1+amount; 
    } 
} 


/** 
* The hashing method used 
* @param key 
*   Is the String inputed 
* @param size 
*   Size of the overall arraylist 
* @return 
*   The int representation of that string 
*/ 
private int horner(String key){ 
    int val = 0; 

    for(int a = 0; a < key.length(); a++){ 
     val = ((val << 8) | (a)) % table.length; 
    } 
    table[val] = key; 
    return val; 
} 

这里是我需要实现的接口。 对帖子不重要,但它可以用来更好地理解我正在尝试做什么。

public interface Trends { 

/** 
* Increase the count of string s. 
* 
* @param s   String whose count is being increased. 
* @param amount  Amount by which it is being increased. 
*/ 
public void increaseCount(String s, int amount); 

/** 
* Return the number of times string s has been seen. 
* @param s  The string we are counting. 
* @return int The number of times s has been seen thus far. 
*/ 
public int getCount(String s); 


/** 
* Get the nth most popular item based on its count. (0 = most popular, 1 = 2nd most popular). 
* In case of a tie, return the string that comes first alphabetically. 
* @param n   Rank requested 
* @return string nth most popular string. 
*/ 
public String getNthMostPopular(int n); 

/** 
* Return the total number of UNIQUE strings in the list. This will NOT be equal to the number of 
* times increaseCount has been called, because sometimes you will add the same string to the 
* data structure more than once. This function is useful when looping through the results 
* using getNthPopular. If you do getNthPopular(numEntries()-1), it should get the least popular item. 
* @return Number of distinct entries. 
*/ 
public int numEntries(); 

};

+0

就效率而言,我认为可排序的hashmap更为理想。你可以看看TreeMap,它是一个实现SortedMap的结构。 http://stackoverflow.com/questions/7427758/how-to-use-sortedmap-interface-in-java –

+1

你可能不得不实现类似哈希表的东西,用String作为关键字并且计数为所说的次数字符串被提及。确切地说,我认为列表不会有帮助。如果您只需要一种最受欢迎​​的字符串,则可以使用单个引用来跟踪该字符串。但是,如果您需要所有字符串,则需要从表格中取出所有条目,根据计数对其进行排序,然后将其用作“最受欢迎”列表。 – markspace

+0

我不认为TreeMap会起作用。你必须增加计数后,他们在树中,这将搅乱树上的顺序。这意味着您必须删除每个条目,增加其数量,然后将其重新插入树中。对所有参赛作品进行一次快速排序听起来对我来说效率更高,尽管我还没有测试过。 – markspace

回答

1

如果只有Java的ADT你被允许使用的是ArrayList,我建议你使用一个并呼吁它Collections#sort一个自定义Comparator,然后Collections#frequency找到最常见的元素的频率。

假设list已初始化每个String

Collections.sort(list, Comparator.comparing(s -> Collections.frequency(list, s)).reversed()); 

// Frequency of most common element 
System.out.println(Collections.frequency(list, list.get(0))); 

看到,因为你只允许使用一个ArrayList,这种方法很可能是对你太先进。有些方法可以用嵌套的for循环来完成,但这会非常麻烦。

+0

我是否与数组一起使用列表?或者只是使用列表? –

+0

我只是坚持一个'List',因为你可能不知道文件中有多少行。 –

+0

这是有道理的。我遇到的唯一问题是为什么哈希对我所要做的事情来说确实是必要的? –

1

你不必为此写一个散列表。你可能只是有这样的事情:

class Entry { 
    String key; 
    int count; 
} 

List<Entry> entries; 

然后当你想找到一个入口,只是环比列表:

for (Entry e : entries) { 
    if (e.key.equals(searchKey)) { 
     // found it 
    } 
} 

哈希表中的时间复杂度方面要好很多,但对于刚接触数据结构的人来说,坦白说这是一项艰巨的任务。如果散列表真的是这项任务的必要组成部分,那就不要理会这一点,但我只想指出,这不是绝对必要的。

+0

如果我被要求使用数据集中第18个最受欢迎的字符串,这将无法很好地工作。这项任务的很大一部分是效率,所以我可能不得不使用哈希表。虽然,我无法使用Java库 –

+0

这很好。例如,您可以使用比较器对列表进行排序。 – Radiodef

+0

在这种情况下,我将如何使用比较器进行排序? –