8
votes

Façon efficace de trouver la longueur des drapeaux enum?

Considérez ceci:

UInt32 v = (UInt32)co;
v = v - ((v >> 1) & 0x55555555); 
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); 
UInt32 count = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; 


2 commentaires

Dupliquer? Stackoverflow.com/Questtions/677204


Oui, c'est, mais cette question a des réponses plus intéressantes que l'original. Devrais-je supprimer la question?


10 Réponses :



1
votes

Une approximation approximative ne comptera simplement que le nombre de bits définis dans mycolors , mais qui ne fonctionnera que si la valeur de chaque énumération est la puissance de 2.


0 commentaires

-3
votes

Essayez ceci ... xxx

... ou est-ce trop évident?

EDIT:

OK, je viens de lire le question à nouveau et réalisa que vous avez besoin de la longueur des «mycolors», pas des «couleurs» - laissez-moi penser à cela.

autre édition:

maintenant je suis confus - le La solution postée de l'OP ne fonctionnerait jamais, car myColor.tostring () renvoie "5" et appliquer la division (nouveau caractère [] {','}) à cela entraînerait une matrice d'une longueur de 1. L'OP a-t-il réellement obtenu cela pour travailler?


6 commentaires

Ce n'est pas évident parce que c'est faux! L'OP tente de déterminer le nombre de drapeaux définis dans une variable Enum, et non combien sont définis dans l'énum.


Je crois que votre code est une erreur, désolé. Ce que vous vouliez dire était: Enum.getvalues ​​(typeof (couleurs)). Longueur; Mais cela calcule la longueur des couleurs, pas des mycolors. Veuillez lire la question.


Belugabob: Il comptait le nombre de virgules. Lorsqu'il y a plus d'un article de la valeur (A | B), il aura deux virgules. C'est une très mauvaise façon de faire le comptage, d'où la raison à laquelle il a posé sa question :)


@Silky: BTW, ma méthode est correcte, mais un peu lent. Je compte la longueur de la matrice après avoir fractionné la chaîne par virgule. Il n'y a pas d'erreurs algorithmiques, juste un tas de chaînes temporaires ;-)


Je conviens que c'est correct, mais pas une bonne approche, car je suis sûr que vous savez :)


@Valentin: il revenait «5», car j'ai accidentellement omis l'attribut [Drapeaux] - j'ai évidemment besoin de plus de café ce morineur. :-)



2
votes

Voici un moyen raisonnablement facile de compter les bits. Chaque bit est décalé à l'intérieur du LSB d'un int64 code> qui est et code> avec 1 (pour masquer l'un des autres bits), puis ajouté à la course à pied. Total.

int length = Enumerable.Range(0, 64).Sum(x => ((long)myColor >> x) & 1);


9 commentaires

Ce n'est pas plus difficile; Continuez à changer jusqu'à ce que vous atteigniez 0, en supposant qu'un changement ne porte pas le MSB.


@strager: Je ne suis pas sûr de ce que vous entendez par "jusqu'à 0". Peux-tu élaborer?


@Luke - Voir mon exemple, pas trop difficile à gérer un certain nombre de largeur.


@Luke, quelque chose comme: int tmp = mycolor; tandis que (TMP! = 0) {TMP >> = 1; ++ bitsset; }. Cela a des problèmes avec des numéros signés, comme je l'ai mentionné.


@Luke - Je ne suis pas pleinement à la hauteur des fonctions de Lambda, mais on dirait que vous allez itérer 64 fois?


@ Stevo3000: Oui, il itère 64 fois. Une fois pour chaque morceau.


@Luke - c'est assez excessif! Si vous regardez ma réponse, il ne dépend que une fois pour chaque jeu. J'aime comme la façon dont vous pouvez faire beaucoup avec une seule ligne, mais c'est l'un de ces cas où il est inefficace.


@ Stevo3000: J'ai dit que cette technique était facile, pas efficace! L'utilisation de Linq pour ce type de chose ne livrera jamais la solution la plus rapide: la doublure ci-dessus instanticule en réalité plusieurs objets d'itérateur et effectuant des dizaines d'appels de méthode dans les coulisses, par rapport à votre réponse qui nécessite une boucle simple et un entier. / Arithmétique Bitwise.


@Luke - Je ne doutais pas que c'était facile, mais l'OP avait demandé l'efficacité de la question. Bon de voir différentes approches cependant.



11
votes

Le code suivant vous donnera le nombre de bits définis pour un nombre donné de tout type de taille variable à partir d'octet jusqu'à long.

public static int GetSetBitCount(long lValue)
{
  int iCount = 0;

  //Loop the value while there are still bits
  while (lValue != 0)
  {
    //Remove the end bit
    lValue = lValue & (lValue - 1);

    //Increment the count
    iCount++;
  }

  //Return the count
  return iCount;
}


3 commentaires

BTW: suppose que chaque drapeau définit un seul bit et aucun déclenchement des drapeaux.


@Luke - Je ne pouvais pas le dire mieux moi-même.


@DevStuff - Le commentaire de Luke semble avoir été supprimé. Un drapeau valide est un peu ou un composite composé de plusieurs bits (utilisés comme sténographie). Cette fonction est uniquement destinée à calculer les bits indervidaux.



2
votes

Voici mon prise sur cela ... il compte le nombre de bits définis dans la valeur xxx


2 commentaires

@Matt - Cela ressemble à cela fonctionne, mais il semble que cela a besoin de plus d'itérations que de bits de bits, vous obligeant à avoir besoin d'un bloc IF.


@ Stevo3000 - Ouais, tu as raison ça va itéralement tous les bits jusqu'à l'ensemble le plus important. Votre solution ne le fait pas, gentille! :) Je me souviendrai certainement de ça pour l'avenir



3
votes

Voici quelques méthodes d'extension pour manipuler les drapeaux énumérations: xxx

Dans votre cas, vous pouvez utiliser la méthode getflags : < / p> xxx

Ce n'est probablement pas aussi efficace que la réponse de Luke, mais il est plus facile d'utiliser ...


0 commentaires

0
votes

La solution la plus fiable est de tester pour chaque valeur dans l'énumération:

[Flags]
enum Colors {
   Red = 0xFF0000,
   Green = 0x00FF00,
   Blue = 0x0000FF
}


1 commentaires

BTW: Si vous utilisez ceci dans une boucle, il fonctionnera beaucoup plus rapidement si le résultat reflété Enum.getValues ​​() est extrait d'une variable statique.



1
votes

J'ai fait une méthode d'assistance pour moi-même. Peut-être que ce sera utile pour les autres. XXX


0 commentaires

0
votes
int value = Enum.GetNames(typeof(Colors)).Length;
public static int NumberOfOptions(int value)
{
    int result = (int)Math.Pow(2, value-1);
    return result;
}

0 commentaires