2010-02-01 5 views
3

Ma question concerne l'utilisation des opérateurs au niveau du bit sur C++ std::string. Par surcharge ou comme fonction n'a pas d'importance.Opérateurs binaires au format C++ pour std :: string

Exemple pour un XOR de travail/fonction ^ pour std::string:

std::string XOR(std::string value, std::string key) 
{ 
    std::string retval(value); 
    long unsigned int klen = key.length(); 
    long unsigned int vlen = value.length(); 
    unsigned long int k = 0; 
    unsigned long int v = 0; 
    for (; v < vlen; v++) { 
    retval[v] = value[v]^key[k]; 
    k = (++k < klen ? k : 0); 
    } 
    return retval; 
} 

Ce que je manque maintenant pour remplacer NON/~ ET/OU &, plus/|. Exemple C++ code (les deux dernières lignes aimeraient avoir ... :-P):

//note: matrix_content[][] holds unsigned, *checked* integers... 
//  char(foo) works... 
std::string vertical_master = ""; 
for (unsigned short int k = 0; k < axis_max; k++) { 
    for (unsigned short int l = 0; l < axis_max; l++) { 
    horizontal_master += char(matrix_content[l][k]); 
    vertical_master += char(matrix_content[k][l]); 
    } 
} 

std::string vertical_shift1_0 = vertical_master; 
usigned short int bit = "@"; //<- just an example... chatched via 
          // std::string::substr() and std::string::c_str() 
for (unsigned long int x = 0; x < axis_max; x++) { 
    vertical_shift1_0 += char(bit); 
} 
std::string vertical_shift2_0; 
for (unsigned long int x = 0; x < axis_max; x++) { 
    vertical_shift2_0 += char(0); 
} 
vertical_shift2_0 += vertical_master; 

std::string vertical_or = ~(vertical_shift1 | vertical_shift2); 
std::string vertical_and = ~(vertical_shift1_0 & vertical_shift2_0); 

En PHP/Perl, je peux faire des choses désagréables comme :-P cette

$vertical_shift1_0 = $vertical_master.str_repeat(chr(0), $axis_max); 
$vertical_shift2_0 = str_repeat(chr(0), $axis_max).$vertical_master; 
$vertical_or  = chunk_split(~($vertical_shift1 | $vertical_shift2), $axis_max, chr(170)); 
$vertical_and  = chunk_split(~($vertical_shift1_0 & $vertical_shift2_0), $axis_max, chr(170)); 

... et il me manque ;-). Cependant XOR fonctionne. Comment puis-je obtenir ET/OU/NON?

+1

Si la longueur de la "chaîne" est fixe, vous devez utiliser un 'std :: bitset ' qui a surchargé ces '>>', '<<', '|', '&', etc pour toi déjà. – kennytm

+0

Votre code pour XOR n'est pas symétrique en raison de la manipulation de la longueur de la chaîne – danio

+0

Hi Georg! Probablement je devrais m'excuser pour la question de débutant après, mais ne devriez-vous pas vérifier pour les longueurs de paramètre? Ou: Qu'arrive-t-il à la fonction XOR si la valeur est plus courte que la clé? Le reste des symboles devrait alors correspondre à la clé, ne devraient-ils pas?) TIA pour des conseils! – astriffe

Répondre

5

Une fois que vous sortez un caractère d'une chaîne via l'opérateur [], vous pouvez utiliser tous les opérateurs au niveau du bit que vous voulez. C/C++ traite les caractères signés/non signés comme des types numériques (malheureusement).

Si vous faites beaucoup d'opérations binaires, vous pouvez envisager l'une des structures de données binaires dédiés

  • bitset de STL pour bitsets de longueur fixe
  • bit_vector de boost pour bitsets de longueur dynamique
2

Vous pouvez écrire une implémentation générique qui fonctionne avec un paramètre foncteur:

template <typename T> 
struct or { 
    T operator()(T ch1, T ch2) { 
     return ch1 | ch2; 
    } 
}; 
template <typename T> 
struct xor { 
    T operator()(T ch1, T ch2) { 
     return ch1^ch2; 
    } 
}; 
template <typename InputIterator1, typename InputIterator2, 
      typename OutputIterator, typename Functor> 
void apply(InputIterator1 begin1, InputIterator1 end1, 
      InputIterator2 begin2, InputIterator2 end2, 
      OutputIterator output, Functor f) 
{ 
    if ((end1-begin1) != (end2-begin2)) throw std::exception(); // throw some more meaningful exception... 
    while (begin1 != end1) 
    { 
     *output++ = f(*begin1++, *begin2++); 
    } 
} 
// usage: 
void string_operations(std::string str1, // by value so we can change it 
    std::string const & str2) 
{ 
    // in place modification 
    apply(str1.begin(), str1.end(), str2.begin(), str2.end(), 
      str1.begin(), or<char>()); 

    // out of place: copy 
    std::string and_string; 
    apply(str1.begin(), str1.end(), str2.begin(), str2.end(), 
      std::back_inserter(and_string), and<char>()); 
} 
+0

+1 pour le style fonctionnel :) – leemes

0

en supposant que je comprends vos besoins ...

pour ET:

std::string AND(std::string value, std::string key) 
{ 
    uint32_t klen = key.length(); 
    uint32_t vlen = value.length(); 
    uint32_t max_len = (klen > vlen) ? klen : vlen; 
    char * ret_str = (char *)calloc(max_len, sizeof(char)); 
    const char * v_str = value.c_str(); 
    const char * k_str = key.c_str(); 
    for (uint32_t i = 0; i < max_len; i++) 
    { 
    if (i >= klen || i >= vlen) 
     ret_str[i] = 0x00; 
    else 
     ret_str[i] = v_str[i] & k_str[i]; 
    } 
    std::string to_return(ret_str); 
    free(ret_str); 
    return to_return; 
} 

et NON

std::string NOT(std::string value) 
{ 
    const char v_str = value.c_str(); 
    char * ret_str = (char *)calloc(value.size(), sizeof(char)); 
    for (uint32_t i = 0; i < value.size(); i++) 
    { 
    ret_str[i] = ~(v_str[i]); 
    } 
    string to_return(ret_str); 
    free(ret_str); 
    return to_return; 
} 

et OR:

std::string OR(std::string value, std::string key) 
{ 
    uint32_t klen = key.length(); 
    uint32_t vlen = value.length(); 
    uint32_t max_len = (klen > vlen) ? klen : vlen; 
    char * ret_str = (char *)calloc(max_len, sizeof(char)); 
    const char * v_str = value.c_str(); 
    const char * k_str = key.c_str(); 
    for (uint32_t i = 0; i < max_len; i++) 
    { 
    if (i >= klen || i >= vlen) 
    { 
     ret_str[i] = (klen > vlen) ? k_str[i] : v_str[i]; 
    } 
    else 
    { 
     ret_str[i] = v_str[i] | k_str[i]; 
    } 
    } 
    std::string to_return(ret_str); 
    free(ret_str); 
    return to_return; 
} 

J'excuse à l'avance pour des erreurs. : -S

Questions connexes