2017-05-06 1 views
2

J'essaie d'entrer des milliers de chaînes à partir d'un fichier texte, puis de classer les chaînes les plus populaires. Je suis perdu sur la façon de garder une trace du nombre de chaînes qu'il y a. Dois-je implémenter un autre ADT, comme linkedlist? Je ne suis pas autorisé à utiliser les bibliothèques Java à l'exception de ArrayList.Nombre de fois qu'une chaîne apparaît dans une table de hachage Java

Voici ce que j'ai jusqu'à présent.

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; 
} 

Et voici l'interface que je dois implémenter. Pas essentiel pour le poste, mais il peut être utilisé pour mieux comprendre ce que je suis en train de faire.

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

En termes d'efficacité, je suppose qu'un hashmap triable est plus idéal. Vous pouvez regarder dans TreeMap, qui est une structure qui implémente SortedMap. http://stackoverflow.com/questions/7427758/how-to-use-sortedmap-interface-in-java –

+1

Vous devez probablement implémenter quelque chose comme une table de hachage, avec String comme clé et compter comme le nombre de fois indiqué la chaîne est mentionnée. Je ne pense pas qu'une liste aidera ici, exactement. Si vous avez besoin d'une seule chaîne qui est la plus populaire, vous pouvez suivre cela avec une seule référence. Cependant, si vous avez besoin de toutes les chaînes, vous devez retirer toutes les entrées de votre table, les trier en fonction du nombre, puis utiliser cette liste comme "la plus populaire". – markspace

+0

Je ne pense pas qu'un TreeMap fonctionnera. Vous devez augmenter les comptes après qu'ils sont dans l'arbre, ce qui gâchera l'ordre sur l'arbre. Cela signifie que vous devez supprimer chaque entrée, augmenter son nombre, puis le réinsérer dans l'arborescence. Un tri rapide après que toutes les entrées sont comptées semble plus efficace pour moi, même si je n'ai pas testé cela. – markspace

Répondre

1

Si le seul Java ADT vous êtes autorisé à utiliser est un ArrayList, je vous suggère d'utiliser un et appelez Collections#sort sur elle avec une coutume Comparator, puis Collections#frequency pour trouver la fréquence de l'élément le plus commun.

En supposant list est déjà initialisés avec chaque 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))); 

Voyant que vous êtes autorisé à utiliser un ArrayList, cette méthode sera très probablement trop avancé pour vous. Il y a des façons de le faire avec des boucles for-imbriquées, mais ce serait très compliqué.

+0

Ai-je la liste en conjonction avec le tableau?Ou utilisez simplement la liste? –

+0

Je voudrais juste coller avec un 'List', car vous pourriez ne pas savoir combien de lignes sont dans le fichier. –

+0

Cela a du sens. Le seul problème que j'ai est alors pourquoi hashing vraiment nécessaire pour ce que j'essaye de faire? –

1

Il n'est pas nécessaire d'écrire une table de hachage pour cela. Vous pourriez avoir quelque chose comme ceci:

class Entry { 
    String key; 
    int count; 
} 

List<Entry> entries; 

Et puis quand vous voulez trouver une entrée, boucle un peu plus de la liste:

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

Une table de hachage est beaucoup mieux en termes de complexité de temps , mais franchement, c'est une tâche vraiment décourageante pour quelqu'un qui est nouveau dans les structures de données. Si la table de hachage est vraiment une partie nécessaire de l'assignation, alors ne tenez pas compte de cela, mais je voulais juste faire remarquer que ce n'est pas strictement nécessaire.

+0

Cela ne fonctionnerait pas très bien si on me demandait la 18ème chaîne la plus populaire dans l'ensemble de données. Une grande partie de la mission est l'efficacité, donc je dois aller avec une table de hachage. Bien que, je ne peux pas utiliser la bibliothèque Java –

+0

C'est parfaitement bien. Vous pouvez trier la liste avec un comparateur, par exemple. – Radiodef

+0

Comment ferais-je le tri avec un comparateur dans ce contexte? –