2009-07-08 5 views
2

J'ai besoin d'une suggestion pour une structure de données efficace pour le problème suivant.Structure de données efficace pour comparer les éléments avec les attributs les plus courants

J'ai deux listes d'étudiants (hommes et femmes) avec leurs classes respectives (triées par date) qu'ils ont déjà prises. La liste est déjà alphabétisée avec leur nom, prénom.

Un utilisateur donnera un nom d'étudiant, c.-à-d. L'étudiant X, et ce que le programme doit faire est de trouver quel étudiant partage le plus de classes avec l'étudiant X.

+2

Qu'avez-vous venir avec à ce jour? –

+0

Placez chaque liste dans son tableau respectif. Chaque élément du tableau contient un autre tableau avec la liste des classes triées par date. Trouvez l'élève X dans la liste et copiez sa liste de classes. Comparez chaque élève avec sa liste de classes. Mais cela semble inefficace. –

+0

Le terme «le plus efficace» est celui où toutes les réponses sont déjà pré-calculées: où, pour chaque question (c'est-à-dire pour chaque élève X) vous avez déjà la réponse associée (ex. qui partage le plus de classes avec l'élève X). La structure la plus efficace pourrait alors être un dictionnaire, avec une clé pour chaque étudiant et la réponse associée pour chaque valeur correspondante. – ChrisW

Répondre

2

Il semble que vous ayez besoin de Associative Arrays. Un tableau associatif mappe un objet clé d'un certain type à un autre objet, éventuellement d'un type différent. Il est souvent juste appelé une "carte" puisque c'est ce qu'il fait. Une carte peut être implémentée par un Hash Table, ce qui veut dire que vous avez constamment le temps de chercher vos clés -> mappages d'objets. Je suggère deux tables de hachage pour ce problème. Le premier à mapper les noms des élèves à des listes de classes prises. La seconde pour mapper les noms de classe aux élèves qui ont suivi le cours. Vos recherches étudiant -> cours seront très rapides, et votre recherche de classe -> étudiant sera rapide aussi. En outre, lorsque vous traitez un élève particulier X, vous pouvez en utiliser un troisième pour mapper un nom d'étudiant en nombre entier, en comptant combien de fois il a partagé un cours avec l'élève X. Cela finira par être une mise en œuvre assez efficace.

Mieux encore, cela peut s'avérer être une implémentation très simple. Le mappage relationnel est une tâche si courante et les tableaux associatifs sont si utiles que de nombreuses langues les ont intégrés ou dans la bibliothèque standard. Python a son dictionnaire, Perl a son hash, Java a un HashMap (et beaucoup d'autres types de cartes), C++ a std :: map, bien que cela ne soit pas supporté par une table de hachage et n'a pas d'accès constant. À moins que vous ne soyez interdit d'utiliser la bibliothèque standard de votre langue pour cet exercice, vous ne devriez pas avoir trop de difficulté à faire fonctionner une solution efficace.

+0

+1 pour la description de la table de hachage, mais je ne suis pas sûr que j'utiliserais la deuxième carte pour ce problème. – joeslice

+0

Une raison spécifique pour laquelle vous n'auriez pas la deuxième carte? Vous aurez besoin d'une recherche efficace de qui prend une classe particulière, donc utiliser une carte pour cela est un choix logique. – aberrant80

0

je ferais ceci:

class Clazz { 
    Date when; 
    String name; 
} 
class Student { 
    boolean isFemale; 
    String name; 
    Map<Date, Clazz> classesTaken; 
} 
List<Student> students = ... 

public Student findMostShared(Student who) { 
    Student max = null; 
    int maxCount = 0; 
    for (Student s : students) { 
     if (s == who) { continue; } 
     int c = 0; 
     for (Clazz z : s.classesTaken.values()) { 
      if (who.classesTaken.containsKey(z.when)) { 
       c++; 
      } 
     } 
     if (c > maxCount) { 
      maxCount = c; 
      max = s; 
     } 
    } 
    return max; 
} 
Questions connexes