avoir avoir p> Comment puis-je rechercher lbyte pour pas seulement un octet unique, mais pour l'index des ecranes? de
E.g. P> public static Int32 ListIndexOfArray(List<byte> lb, byte[] sbs)
{
if (sbs == null) return -1;
if (sbs.Length == 0) return -1;
if (sbs.Length > 8) return -1;
if (sbs.Length == 1) return lb.FirstOrDefault(x => x == sbs[0]);
Int32 sbsLen = sbs.Length;
Int32 sbsCurMatch = 0;
for (int i = 0; i < lb.Count; i++)
{
if (lb[i] == sbs[sbsCurMatch])
{
sbsCurMatch++;
if (sbsCurMatch == sbsLen)
{
//int index = lb.FindIndex(e => sbs.All(f => f.Equals(e))); // fails to find a match
IndexOfArray = i - sbsLen + 1;
return;
}
}
else
{
sbsCurMatch = 0;
}
}
return -1;
}
3 Réponses :
La force brute est toujours une option. Bien que lent à la comparaison d'autres méthodes, dans la pratique, ce n'est généralement pas trop mauvais. Il est facile à mettre en œuvre et tout à fait acceptable si C'est le même concept que String Brute Force Recherche . P> lbyte code> n'est pas énorme et n'a pas de données pathologiques. P>
Vous pouvez trouver ALGORITHM BOYER-MOORE utile ici. Convertissez votre liste en un tableau et une recherche. Le code d'algorithme est pris de Cet article .
int startIndex = SimpleBoyerMooreSearch(lbyte, searchBytes);
Vous pourrez peut-être éteindre vos tableaux d'octets avec IList code> s pour rendre votre code plus générique
UnUnutunalité La liste change avec chaque appel. Je ne suis pas encore suivi ça mais je vais essayer d'essayer. Si vous implémentez la version iList, veuillez le poster ici.
@BLAM - J'ai ajouté la version iList. Ce n'est pas entièrement générique (accepte uniquement les octets), mais il devrait fonctionner dans votre cas car il gère des listes et des tableaux d'octets.
Je suis trop fatigué pour le suivre maintenant mais je vais le tester.
@Blam - Ce message peut aider à expliquer l'algorithme lui-même. Stackoverflow.com/questions/6207819/... < / a>
@KeyboardP comme je lis cette explication, c'est la même force brute que je suis venu, mais mon code n'est rien comme votre code.
@Blam: B-M n'est pas un algorithme de force brute. Le gist de B-M est que vous pouvez sauter jusqu'à M> M i> caractères (octets) lorsqu'un décalage survient, votre code ne saute toujours que 1 qui le rend plus lent à un ordre de grandeur. Étant donné que votre cas est fondamentalement une recherche de sous-chaîne (c'est-à-dire une commande importante, les valeurs ne sont pas uniques, n'est pas triée) puis B-M est la solution la plus rapide.
@Borisb. Je ne suis tout simplement pas suivi. Si je cherche la chaîne 'Caacattatdog' pour 'Cat' Comment puis-je sauter de la direction et ne pas manquer un match?
@BLAM - B-M analyse vers l'arrière, donc si vous recherchez CAT code>, t code> est le premier à être vérifié. Étant donné que t code> ne correspond pas à a code> (3ème caractère), vous pouvez ignorer les 3 premiers caractères (longueur du modèle de recherche). Maintenant, t code> correspondant t code> (6ème caractère), A code> correspond à un A code> et c code> C code> Correspondances C code>. Ou travaillez à partir de la fin de la chaîne, t code> ne correspond pas g code>, alors skip to longueur - 3 code>. t code> correspondances t code> mais A code> ne correspond pas t code> (6ème caractère). Toutefois, étant donné que t code> existe dans la chaîne de recherche, vous déplacez 1 de sorte que la chaîne de recherche t code> aligne avec le 6ème char t code>. Là vous avez votre match. Ces sauts améliorent les performances.
@Blam - Je ne suis pas un expert sur l'algorithme B-M, mais c'est comme ça que je le comprends de travailler. Heureux d'être corrigé si je me trompe à ce sujet.
@Ok je l'obtiens enfin +1 merci
Une autre façon que vous puissiez faire avec Lambda Expression
int index = lbyte.FindIndex(e => searchBytes.All(i => i.Equals(e));
Manquant) et j'ai testé cela ne trouve pas de matchs.
Voulez-vous s'il vous plaît écrivez votre cas de test?
J'ai ajouté où je le teste au code que j'ai posté dans la question. Je n'ai pas vraiment de "cas de test" pour produire des données. Je lis ces octets d'une base de données. Mais je sais que la force brute correspond correctement.
@Yairnevet une liste d'octets
@Yairnevet Une autre liste d'octets, il s'agit essentiellement de commandes.ConSutenance Il doit y avoir une bonne solution ici comme son essentiellement résolue avec String.Contains, mais c'est un cas plus générique
Essayez de chercher ici pour une méthode d'extension pour le faire.
Êtes-vous sûr que votre méthode de force brute est correcte? On dirait que cela ne vérifie pas le dernier caractère de la chaîne de recherche. Donc, lorsque vous recherchez "FROB", si seulement vérifie "FRO". Je pense que vous voulez incrémenter
sbscurmatch code> après i> la vérification de la longueur. Comme il se trouve, cela échouera sur une chaîne d'un caractère.