2009-05-18 5 views
0

je la structure de données suivantes:plusieurs foncteurs pour redéfinir l'ordre pour la fonction de tri du vecteur

typedef vector< vector<int> > MxInt2d; 
typedef vector< vector<double> > MxDouble2d; 

class QSweep{ 
public: 
.... 
static MxDouble2d myPoints_; 
MxInt2d myEdges_; 
MxInt2d sweepEvents; 

class order{ 
public: 
    bool operator() (const vector<int>& edge1, const vector<int>& edge2){ 
      return (myPoints_[edge1[0]][0]<myPoints_[edge2[0]][0])|| 
         (myPoints_[edge1[0]][0]==myPoints_[edge2[0]][0]&& 
         myPoints_[edge1[0]][1]<myPoints_[edge2[0]][1]) 
        || 
        (myPoints_[edge1[0]][0]==myPoints_[edge2[0]][0]&& 
         myPoints_[edge1[0]][1]==myPoints_[edge2[0]][1]&& 
        getSlope(myPoints_[edge1[0]][0],myPoints_[edge1[0][1], 
            myPoints_[edge1[1]][0],myPoints_[edge1[1]][1]) 
        < 
         getSlope(myPoints_[edge2[0][0],myPoints_[edge2[0][1],  
            myPoints_[edge2[1]][0],myPoints_[edge2[1]][1])); 
        } 
}; 
static double getSlope(double a, double b, double c, double d); 
static double computeDet(double a, double b, double c, double d, double x, double y); 

};

J'utilise le foncteur de l'ordre() lors de la définition du constructeur de la manière suivante:

QSweep::QSweep(const MxDouble2d& myPoints, const MxInt2d& myEdges){ 
.... 
    //code here for initializing myPoints_, myEdges_ 
sort(myEdges_.begin(),myEdges_.end(),order()); 
} 

De cette façon, mes données myEdges_ sont disposées lorsqu'initialisé en utilisant l'ordre foncteur(). Maintenant, je veux organiser les données sweepEvents (qui a le même type que myEdges_ en utilisant le type de données prédéfini du vecteur C++) en utilisant un critère totalement différent, c'est-à-dire je ne veux pas utiliser la fonction getSlope (...) function computeDet (...) pour sweepEvents. Donc je pensais que j'ai encore besoin d'un autre foncteur pour redéfinir le < de sort() pour le type de données vectoriel? Je dois donc d'écrire un nouveau foncteur ORDER1() dans lequel j'utilise les données calculées avec computeDet (...), puis-je appeler le genre sur mes sweepEvents types de données:

sort(sweepEvents.begin(),sweepEvents.end(),order1()); 

Je ne suis pas sûr si C'est la bonne solution? Puis-je redéfinir de plusieurs façons < si j'utilise des noms différents pour le foncteur? Est-ce que quelqu'un a des suggestions que je serais vraiment reconnaissant. Merci d'avance, madalina

Aucun des deux foncteurs n'utilise de code commun. J'ai écrit la deuxième foncteur insede la classe QSweep comme ceci:

class orderDet{ 
public: 
    bool operator() (const vector<int>& edgeSW1, const vector<int>& edgeSW2 
           ,const vector<int>& edgeC){ 
     return 
      (
      computeDet(myPoints_[edgeSW1[0]],myPoints_[edgeSW1[1]],myPoints_[edgeC[0]]) 
      < 
      computeDet(myPoints_[edgeSW2[0]],myPoints_[edgeSW2[1]],myPoints_[edgeC[0]]) 
      ); 
    }} 

et je l'ai appelé comme:

sort(sweepEvents.begin(), sweepEvents.end(), orderDet()); 

Mais je suis arrivé l'erreur de compilation suivante:

error: no match for call to '(QSweepComplete::orderDet) (std::vector<int, 
std::allocator<int> >&, std::vector<int, std::allocator<int> >&)' 
./QSweepComplete.h:68: note: candidates are: bool 
QSweepComplete::orderDet::operator()(const std::vector<int, std::allocator<int>>&, 
const std::vector<int, std::allocator<int> >&, const std::vector<int, 
std::allocator<int> >&) 

I Je suppose que le paramètre ne correspond pas, car le troisième paramètre de orderDet (...., edgeC) ne fait pas partie de la liste sweepEvents car les autres sont mais fait partie de la variable myEdges _... Peut-être que l'on peut me donner quelques suggestions sur la façon de mettre en œuvre ce foncteur?

merci d'avance. meilleurs voeux, madalina

Répondre

4

Si vous avez 2 critères différents pour le tri alors vous devriez avoir 2 foncteurs différents.

Donnez-leur des noms significatifs tels que:

OrderBySlopes et OrderByXYZ

Si les 2 foncteurs utilisent un code commun, vous pouvez factoriser cela. c'est-à-dire dans une classe de base

0

Ce qui a été dit Glen.

Si vous tenez vraiment à avoir une fonction double, vous pouvez compter sur différents types de paramètres pour surcharger deux versions de l'opérateur().

0

Votre orderDet::operator() prend trois arguments. Le std::sort veut seulement deux pour comparer deux valeurs.

Une solution peut être d'ajouter les arêtes vecteur comme un membre de votre foncteur:

struct orderDet { 
    const vector<int>& edges; 
    orderDet(const vector<int>& edges):edges(edges){}; 

    bool operator()(const vector<int>& v1, const vector<int>& v2) const { 
     .... 
    } 
}; 

Par ailleurs, si vous voulez que les gens à comprendre votre code quand ils ont lu, je pense plutôt que vous devriez utiliser un typedef pour votre vecteur interne que pour l'extérieur. En plus de cela, il est préférable de définir une structure contenant un «premier» et un «deuxième» point, plutôt qu'un vecteur très générique dont vous n'utilisez que les deux premiers points. Cela rendra votre code plus lisible aussi.

Cordialement.

+0

oui cela a fonctionné. Merci. (J'ai utilisé typedef dans mon code, je devrais l'utiliser aussi ici vous avez raison) – madalina

Questions connexes