2015-10-18 2 views
2

Avant de commencer à écrire le code de mon projet, j'ai besoin de conseils. Il s'agit de trouver fréquemment l'occurrence d'éléments (mode). Les éléments peuvent être dans le tableau int, char, any object of class/struct. Donc, je dois utiliser void*. J'ai une fonction qui retourne la première occurrence de l'élément mode. est-ce quepointeur vide constatant fréquemment l'occurrence d'éléments

int arr[] = { 1, 7, 2, 4, 4, 8, 4 } 
mode is 4 
> return value 3 
char arr[] = { 'q', 'w', 'w', 'u', 'u', 'w', 'o' } 
mode is w 
> return value 1 
myClassObj[4]; 
myClassObj[0].mySetter(0,4); 
myClassObj[1].mySetter(1,1); 
myClassObj[2].mySetter(1,1); 
myClassObj[3].mySetter(7,9); 
> return value 1 

Dois-je trier tout type de tableau pour trouver le mode? Devrais-je utiliser la bibliothèque de cartes? Que dois-je faire, comment puis-je commencer?

int indexOfFirstMode (const void * base, int num_of_elements, int size_of_arr, 
         bool (*checker) (const void *, const void *)); 

Edit:

Je ne devrais pas utiliser template pour l'instant

+0

Il semble que vous n'ayez qu'une fonction pour comparer deux éléments d'égalité, donc je ne pense pas que le tri ou l'utilisation de cartes sera toujours possible. – grc

+0

Est-ce à propos de C ou C++? – edmz

+0

_ "Donc, je dois utiliser void *" _ Vous vous trompez. Vous devriez utiliser 'boost :: variant'. Autrement dit, en supposant que votre code est _actually_ C++. Pourquoi l'avez-vous tagué C? –

Répondre

0

Je suppose que, vous pouvez utiliser la technique des modèles au lieu de void*. Cela rend les solutions beaucoup plus facile:

#include <iostream> 

using namespace std; 


template <class T> 
int indexOfFirstMode(T array[], int size, bool (*checker)(const T& a, const T& b)) 
{ 
    int index = -1; 
    int max_num = 0; 

    for (int i = 0; i < size; i++) 
    { 
     int value = array[i]; 
     int num = 1; 

     for (int j = i + 1; j < size; j++) 
      if (array[j] == value) 
       num += 1; 

     if (num > max_num) 
     { 
      index = i; 
      max_num = num; 
     } 
    } 

    return index; 
} 


bool checker(const int& a, const int& b) 
{ 
    return a == b; 
} 


int main() 
{ 
    int A[9] = {15, 3, 5, 7, 3, 1, 5, 5, 5}; 

    cout << indexOfFirstMode(A, 9, checker) << endl; // 2 

    return 0; 
} 
+0

est-ce juste pour le type int? Aussi, je voulais idée mais merci pour le code. Je pense que ça ne marchera pas pour la classe – askque

0

Tout d'abord, il est presque jamais une bonne idée d'utiliser void * en C++; Il y a toujours un meilleur moyen.
Le problème avec void * est qu'ils ne vous donnent que le point de départ d'un objet en mémoire, mais ils ne vous diront pas combien vous devriez aller à partir de là (par exemple, décalage).

dans votre cas, vous pouvez éviter cela, puisque vous avez num_of_elements et size_of_arr vous pouvez calculer le décalage, et puisque vous écrivez un autre vérificateur pour chaque type, la fonction de vérificateur est conscient de la taille de l'objet que vous devez comparer. Pour calculer le mode, il existe plusieurs façons de le faire:

vous pouvez trier la liste et ensuite rechercher l'élément avec la plus longue exécution, une autre façon de le faire est d'utiliser un std::map mappage de chaque élément à son nombre d'occurrences, puis en prenant le maximum.

mais attention, la mise en œuvre avec void * est un peu difficile et vous devrez faire très attention. J'espère que cela aide.