2009-10-15 5 views
0

J'ai deux chaînes hexadécimales, accompagnées de masques, que je voudrais fusionner en une seule paire valeur/masque. Les chaînes peuvent avoir des octets qui se chevauchent mais après l'application des masques, aucun bit de chevauchement ne doit contredire la valeur de ce bit, par exemple value1 = 0x0A mask1 = 0xFE et value2 = 0x0B, mask2 = 0x0F indique essentiellement que la fusion résultante doit avoir Le quart supérieur doit être tous '0 et le quartet inférieur doit être 01011La meilleure façon de fusionner des chaînes hexadécimales en C++? [fortement édité]

Je l'ai déjà fait en utilisant straight c, en convertissant des chaînes en tableaux d'octets et en les mémorisant dans des tampons en tant que prototype. Il a été testé et semble fonctionner. Cependant, il est moche et difficile à lire et ne jette pas d'exceptions pour les exigences de bits spécifiques qui contredisent. J'ai envisagé d'utiliser des ensembles de bits, mais y a-t-il une autre façon de ne pas exiger le temps de conversion? La performance serait bien, mais pas cruciale.


EDIT: Plus de détails, bien que la rédaction de ce me fait réaliser que j'ai fait un simple problème trop difficile. Mais, ça y est, de toute façon.

Je reçois un grand nombre d'entrées qui sont des recherches binaires d'un document à contenu mixte. Le document est divisé en pages, et les pages sont fournies par un API qui délivre une seule page à la fois. Chaque page doit être recherchée avec les termes de recherche fournis. J'ai tous les termes de recherche avant de demander des pages. Les entrées sont des chaînes représentant des chiffres hexadécimaux (c'est ce que je veux dire par des chaînes hexadécimales) ainsi qu'un masque pour indiquer les bits significatifs dans la chaîne hexadécimale en entrée. Depuis que j'ai reçu toutes les entrées, je voulais améliorer la recherche de chaque page retournée. Je voulais pré-traiter fusionner ces chaînes hexagonales ensemble. Pour rendre le problème plus intéressant, chaque chaîne a un décalage facultatif dans la page où ils doivent apparaître et un manque d'un décalage indique que la chaîne peut apparaître n'importe où dans une page demandée. Donc, quelque chose comme ceci:

class Input { 
    public: 
    int input_id; 
    std::string value; 
    std::string mask; 
    bool offset_present; 
    unsigned int offset; 
}; 

Si un objet d'entrée donné a offset_present = false, toute valeur attribuée à décalage est ignoré. Si offset_present est false, il est clair qu'il ne peut pas être fusionné avec d'autres entrées. Pour rendre le problème plus intéressant, je veux signaler une sortie qui fournit des informations sur ce qui a été trouvé (input_id qui a été trouvé, où le décalage était, etc.). La fusion de certaines entrées (mais pas d'autres) rend cela un peu plus difficile. J'avais envisagé de définir une classe CompositeInput et pensais à la fusion sous-jacente comme un bitet, mais en lisant plus sur les bitsets, j'ai réalisé que ce n'était pas ce que je pensais vraiment. Mon inexpérience m'a fait abandonner l'idée composite et aller à la force brute. J'ai nécessairement ignoré certains détails sur d'autres types d'entrées une information supplémentaire à collecter pour la sortie (disons, numéro de page, numéro de paragraphe) lorsqu'une entrée est trouvée. Voici un exemple de classe de sortie:

class Output { 
    public: 
    Output(); 
    int id_result; 
    unsigned int offset_result; 
}; 

Je voudrais produit N de ceux-ci si je fusionne les chaînes hexagonales N, en gardant tous les détails de la fusion cachés de l'utilisateur.

+2

S'il vous plaît développez l'exemple, en montrant les valeurs (en hexadécimal et en binaire), comment vous « fusionner » et comment ce que le résultat est. – Will

Répondre

0

il semble que |, & et ~ fonctionnerait?

2

Je ne sais pas ce qu'est un hexstring ...mais à part qu'il devrait être comme ceci:

outcome = (value1 & mask1) | (value2 & mask2); 
0
const size_t prefix = 2; // "0x" 
const size_t bytes = 2; 
const char* value1 = "0x0A"; 
const char* mask1 = "0xFE"; 
const char* value2 = "0x0B"; 
const char* mask2 = "0x0F"; 
char output[prefix + bytes + 1] = "0x"; 

uint8_t char2int[] = { /*zeroes until index '0'*/ 0,1,2,3,4,5,6,7,8,9 /*...*/ 10,11,12,13,14,15 }; 
char int2char[] = { '0', /*...*/ 'F' }; 

for (size_t ii = prefix; ii != prefix + bytes; ++ii) 
{ 
    uint8_t result1 = char2int[value1[ii]] & char2int[mask1[ii]]; 
    uint8_t result2 = char2int[value2[ii]] & char2int[mask2[ii]]; 
    if (result1 & result2) 
     throw invalid_argument("conflicting bits"); 
    output[ii] = int2char[result1 | result2]; 
} 
Questions connexes