我的问题是关于如何在C ++ std::string
上使用按位运算符。通过重载或功能无关紧要。
^
的工作XOR / 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;
}
我现在缺少的是NOT / ~
,AND / &
加OR / |
的替代品。
示例C ++代码(最后两行想要它...... :-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);
在PHP / Perl中我可以做坏事:-像这样的事情
$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));
......我很想念它;-)。然而XOR工作。我怎样才能获得AND / OR / NOT?
答案 0 :(得分:5)
通过[]
运算符从字符串中取出char后,您可以使用所需的所有按位运算符。 C / C ++将有符号/无符号字符视为数字类型(不幸的是)。
如果您正在执行大量按位操作,则可以考虑使用其中一个专用位数据结构
答案 1 :(得分:2)
您可以编写一个与仿函数参数一起使用的通用实现:
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>() );
}
答案 2 :(得分:0)
假设我理解你的需求......
表示AND:
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;
}
而不是
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;
}
和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;
}
我提前为任何错误道歉。 :-S