c++十进制转二进制,然后用运算,再转回十进制
c++ Decimal to binary, then use operation, then back to decimal
我有一个包含 x 个数字的数组:sets[ ](长数字)和一个包含 x-1 个数字的 char 数组 operations[ ]。对于 sets[ ] 中的每个数字,其二进制形式(64 位)将与一组数字(这些数字从 0 到 63)相同,1 和 0 表示它是否在子集中( 1 2 4将是 1 1 0 1,因为缺少 3)
ex: decimal 5 --->000...00101 ,意味着这个子集里面只有最后两个数字(#63 和#61)
现在,使用我在操作中获得的字符[],我应该使用它们和这些数字的二进制文件,就好像它们是对子集的操作(我希望子集是正确的词),这些操作是:
U = 团聚 ---> 101 U 010 = 111
A = 交叉点 ---> 101 A 001 = 001
\ = A - B ---> 1110 - 0011 = 1100
/ = B-A ---> 和上一个一样
所以基本上我必须读取数字,将它们变成二进制,像使用它们一样使用它们并相应地使用操作,然后 return 对它们进行所有这些操作的结果。
我的代码:
include <iostream>
using namespace std;
void makeBinaryVector(int vec[64], long xx)
{
// put xx in binary form in array "vec[]"
int k = 63;
long x = xx;
if(xx == 0)
for(int i=0;i<64;i++)
vec[i] = 0;
while(x != 0)
{
vec[k] = x % 2;
x = x / 2;
k--;
}
}
void OperationInA(int A[64], char op, int B[64])
{
int i;
if(op == 'U') //reunion
for(i=0;i<64;i++)
if(B[i] == 1)
A[i] = 1;
if(op == 'A') //intersection
for(i=0;i<64;i++)
{
if((B[i] == 1) && (A[i] == 1))
A[i] = 1;
else
A[i] = 0;
}
if(op == '\') //A-B
for(i=0;i<64;i++)
{
if( (A[i] == 0 && B[i] == 0) || (A[i] == 0 && B[i] == 1) )
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 1))
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 0))
A[i] = 1;
}
if(op == '/') //B-A
for(i=0;i<64;i++)
{
if(B[i] == 0)
A[i] = 0;
else
if((B[i] == 1) && (A[i] == 0))
A[i] = 1;
else
if((B[i] == 1) && (A[i] == 1))
A[i] = 0;
}
}
unsigned long setOperations(long sets[], char operations[], unsigned int x)
{
unsigned int i = 1; //not 0, since i'll be reading the 1st number separately
unsigned int j = 0;
unsigned int n = x;
int t;
long a = sets[0];
int A[64];
for(t=0;t<64;t++)
A[t] = 0;
makeBinaryVector(A, a); //hold in A the first number, binary, and the results of operations
long b;
int B[64];
for(t=0;t<64;t++) //Hold the next number in B[], in binary form
B[t] = 0;
char op;
while(i < x && j < (x-1) )
{
b = sets[i];
makeBinaryVector(B, b);
op = operations[j];
OperationInA(A, op, B);
i++; j++;
}
//make array A a decimal number
unsigned int base = 1;
long nr = 0;
for(t=63; t>=0; t--)
{
nr = nr + A[t] * base;
base = base * 2;
}
return nr;
}
long sets[100];
char operations[100];
long n,i;
int main()
{
cin>>n;
for(i=0;i<n;i++)
cin>>sets[i];
for(i=0;i<n-1;i++)
cin>>operations[i];
cout<<setOperations(sets,operations,n);
return 0;
}
所以一切似乎都很好,除非我正在尝试这样做:
组 = {5, 2, 1}
操作 = {'U' , '\'}
5 U 2 为 7(111), 7 \ 1 为 6 (111 - 001 = 110 --> 6)
结果应该是 6,但是当我这样输入它们时,结果是 4 (??)
然而,如果我简单地输入 {7,1} 和 { \ } 结果是 6,这是应该的。但是如果我像我第一次提到的那样输入它们 {5,2,1} 和 {U,} 然后它会输出 4.
我似乎无法理解或看不出我做错了什么...
您不必 "convert to binary numbers"。
没有 'binary numbers' 这样的东西。您可以只对变量执行操作。
对于reunion,可以使用按位OR运算符'|',对于交集,可以使用按位AND 运算符 '&'。
像这样:
if (op == 'A')
result = a & b;
else if (op == 'U')
result = a | b;
else if (op == '\')
result = a - b;
else if (op == '/')
result = b - a;
如@Hugal31 的回答所示,对整数使用按位运算符。
请注意,整数大小通常为 32 位,而不是 64 位。在 64 位系统上,64 位整数需要 long long
。使用 sizeof
运算符进行检查。 int
是 4 个字节(32 位),long long
是 8 个字节(64 位)。
出于作业等目的,你转成vector不可能是对的。您应该测试它以查看它是否输出正确的结果。否则使用这个:
void makebinary(int vec[32], int x)
{
int bitmask = 1;
for (int i = 31; i >= 0; i--)
{
vec[i] = (x & bitmask) ? 1 : 0;
bitmask <<= 1;
}
}
注意移位运算符的使用。要对数字进行 AND,您可以执行以下操作:
int vx[32];
int vy[32];
makebinary(vx, x);
makebinary(vy, y);
int result = 0;
int j = 1;
for (int i = 31; i >= 0; i--)
{
int n = (vx[i] & vy[i]) ? 1 : 0;
result += n * j;
j <<= 1;
}
这当然毫无意义,因为你可以直接说 int result = X & Y;
我有一个包含 x 个数字的数组:sets[ ](长数字)和一个包含 x-1 个数字的 char 数组 operations[ ]。对于 sets[ ] 中的每个数字,其二进制形式(64 位)将与一组数字(这些数字从 0 到 63)相同,1 和 0 表示它是否在子集中( 1 2 4将是 1 1 0 1,因为缺少 3)
ex: decimal 5 --->000...00101 ,意味着这个子集里面只有最后两个数字(#63 和#61)
现在,使用我在操作中获得的字符[],我应该使用它们和这些数字的二进制文件,就好像它们是对子集的操作(我希望子集是正确的词),这些操作是:
U = 团聚 ---> 101 U 010 = 111
A = 交叉点 ---> 101 A 001 = 001
\ = A - B ---> 1110 - 0011 = 1100
/ = B-A ---> 和上一个一样
所以基本上我必须读取数字,将它们变成二进制,像使用它们一样使用它们并相应地使用操作,然后 return 对它们进行所有这些操作的结果。
我的代码:
include <iostream>
using namespace std;
void makeBinaryVector(int vec[64], long xx)
{
// put xx in binary form in array "vec[]"
int k = 63;
long x = xx;
if(xx == 0)
for(int i=0;i<64;i++)
vec[i] = 0;
while(x != 0)
{
vec[k] = x % 2;
x = x / 2;
k--;
}
}
void OperationInA(int A[64], char op, int B[64])
{
int i;
if(op == 'U') //reunion
for(i=0;i<64;i++)
if(B[i] == 1)
A[i] = 1;
if(op == 'A') //intersection
for(i=0;i<64;i++)
{
if((B[i] == 1) && (A[i] == 1))
A[i] = 1;
else
A[i] = 0;
}
if(op == '\') //A-B
for(i=0;i<64;i++)
{
if( (A[i] == 0 && B[i] == 0) || (A[i] == 0 && B[i] == 1) )
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 1))
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 0))
A[i] = 1;
}
if(op == '/') //B-A
for(i=0;i<64;i++)
{
if(B[i] == 0)
A[i] = 0;
else
if((B[i] == 1) && (A[i] == 0))
A[i] = 1;
else
if((B[i] == 1) && (A[i] == 1))
A[i] = 0;
}
}
unsigned long setOperations(long sets[], char operations[], unsigned int x)
{
unsigned int i = 1; //not 0, since i'll be reading the 1st number separately
unsigned int j = 0;
unsigned int n = x;
int t;
long a = sets[0];
int A[64];
for(t=0;t<64;t++)
A[t] = 0;
makeBinaryVector(A, a); //hold in A the first number, binary, and the results of operations
long b;
int B[64];
for(t=0;t<64;t++) //Hold the next number in B[], in binary form
B[t] = 0;
char op;
while(i < x && j < (x-1) )
{
b = sets[i];
makeBinaryVector(B, b);
op = operations[j];
OperationInA(A, op, B);
i++; j++;
}
//make array A a decimal number
unsigned int base = 1;
long nr = 0;
for(t=63; t>=0; t--)
{
nr = nr + A[t] * base;
base = base * 2;
}
return nr;
}
long sets[100];
char operations[100];
long n,i;
int main()
{
cin>>n;
for(i=0;i<n;i++)
cin>>sets[i];
for(i=0;i<n-1;i++)
cin>>operations[i];
cout<<setOperations(sets,operations,n);
return 0;
}
所以一切似乎都很好,除非我正在尝试这样做:
组 = {5, 2, 1} 操作 = {'U' , '\'}
5 U 2 为 7(111), 7 \ 1 为 6 (111 - 001 = 110 --> 6) 结果应该是 6,但是当我这样输入它们时,结果是 4 (??)
然而,如果我简单地输入 {7,1} 和 { \ } 结果是 6,这是应该的。但是如果我像我第一次提到的那样输入它们 {5,2,1} 和 {U,} 然后它会输出 4.
我似乎无法理解或看不出我做错了什么...
您不必 "convert to binary numbers"。 没有 'binary numbers' 这样的东西。您可以只对变量执行操作。
对于reunion,可以使用按位OR运算符'|',对于交集,可以使用按位AND 运算符 '&'。
像这样:
if (op == 'A')
result = a & b;
else if (op == 'U')
result = a | b;
else if (op == '\')
result = a - b;
else if (op == '/')
result = b - a;
如@Hugal31 的回答所示,对整数使用按位运算符。
请注意,整数大小通常为 32 位,而不是 64 位。在 64 位系统上,64 位整数需要 long long
。使用 sizeof
运算符进行检查。 int
是 4 个字节(32 位),long long
是 8 个字节(64 位)。
出于作业等目的,你转成vector不可能是对的。您应该测试它以查看它是否输出正确的结果。否则使用这个:
void makebinary(int vec[32], int x)
{
int bitmask = 1;
for (int i = 31; i >= 0; i--)
{
vec[i] = (x & bitmask) ? 1 : 0;
bitmask <<= 1;
}
}
注意移位运算符的使用。要对数字进行 AND,您可以执行以下操作:
int vx[32];
int vy[32];
makebinary(vx, x);
makebinary(vy, y);
int result = 0;
int j = 1;
for (int i = 31; i >= 0; i--)
{
int n = (vx[i] & vy[i]) ? 1 : 0;
result += n * j;
j <<= 1;
}
这当然毫无意义,因为你可以直接说 int result = X & Y;