【问题标题】:c++ Decimal to binary, then use operation, then back to decimalc++十进制转二进制,再用运算,再转回十进制
【发布时间】:2016-10-29 18:19:40
【问题描述】:

我有一个带有 x 个数字的数组:sets[ ](long numbers) 和一个带有 x-1 个数字的 char 数组操作 [ ]。对于 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 ---> 和上一个一样

所以基本上我必须读取数字,使它们成为二进制,像使用它们一样使用它们并相应地使用操作,然后返回所有这些操作的结果。

我的代码:

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。

我似乎无法理解或看到我做错了什么......

【问题讨论】:

  • 请避免同时标记 C 和 C++,除非您想比较/使用两者
  • 这几天有很多问题,最后的消息是“我似乎无法理解我哪里出错了”
  • 只需在每个循环的内部和外部使用 cout 或 printf 并带有适当的消息并找到逻辑错误。

标签: c++ codeblocks


【解决方案1】:

您不必“转换为二进制数”。 没有“二进制数”之类的东西。您可以只对变量执行操作。

对于重合,可以使用按位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;

【讨论】:

  • 谢谢!出于某种原因,我认为我应该像他们的示例一样精确地解决它(数字在 0 到 63 之间,并使用子集/位操作检查它们)。猜猜你可以说我“忘了思考”......谢谢你的回答
【解决方案2】:

对整数使用按位运算符,如@Hugal31 的回答所示。

请注意,整数大小通常是 32 位,而不是 64 位。在 64 位系统上,您需要 long long 来获取 64 位整数。使用sizeof 运算符进行检查。 int 是 4 个字节(32 位),long long 是 8 个字节(64 位)。

出于家庭作业等的目的,您转换为矢量是不正确的。您应该对其进行测试以查看它是否输出正确的结果。否则使用这个:

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 &amp; Y;

【讨论】:

  • 谢谢!是的,我知道我应该使用 32 的数组,特别是因为整个函数是 LONG,但由于文本明确表示代表 [0 , 63] 之间的数字,我认为我必须遵守。不知道他们的评估者会如何行动,或者它是否只检查输出或整个代码。再次感谢您的回复
猜你喜欢
  • 2014-12-15
  • 2021-07-05
  • 2016-12-25
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 2014-01-07
  • 2012-04-08
  • 2014-10-30
相关资源
最近更新 更多