0

输入:输入的第一行包含整数 T,表示测试用例的数量。对于每个测试用例,有两个整数输入 a 和 b。

输出:对于每个测试用例,输出是显示 a 和 b 等长后的 XOR 的整数。

约束:1<=T<=100 1<=a,b<=107

示例:输入:4 2 6 3 10 5 24 1 20 输出:2 6 12 4

说明: 1. 2 的二进制表示为 10,6 的二进制表示为 110。由于“10”的长度较小,所以在其上加一个“0”使其变为“100”,使二进制表示的长度相等。 100 和 110 的异或得到 010,即 2。

我的代码是

#include <iostream>
#include <cmath>
#include <sstream>
#include <cstring>
#include <string>
using namespace std;

int main()
{
int cases, binary[100];
cin>>cases;

int *result = new int[cases];
int j;
for(j=0; j<cases; j++){

    stringstream ss[3];
    for(int k=0; k<2; k++)
    {
        int n;
        cin>>n;
        int temp=n, i=0, len;
        while(temp > 0){
            binary[i] = temp%2;
            temp /= 2;
            i++;
        }
        len = i;

        string str ;
        for(int i=0; i<len; ++i){
            stringstream ss;
            ss << binary[(len-1)-i];
            str += ss.str() ;
        }
        ss[k] << str;
    }

    string str1 = ss[0].str(), str2 = ss[1].str();
    int len = (str1.length() > str2.length()) ? str1.length() : str2.length() ;

    if(str1.length() < (unsigned)len){
     int diff = len - str1.length();
     for(int i=0; i<diff; ++i){
            str1 += '0';
        }
    }
    else if(str2.length() < (unsigned)len){
      int diff = len - str2.length();
     for(int i=0; i<diff; ++i){
            str2 += '0';
        }
    }

    string str3 = str1;
    for(int i=0; i<len; ++i){
         if(str1[i]==str2[i]){
            str3[i]='0';
        }else   str3[i]='1';
    }
    int length = str3.length(), val=0;
    for(int i=0, m=length-1; i<length, m>=0; ++i,--m){
        if(str3[i] == '1'){
                val += pow(2, m);
         }
    }
    result[j] = val;
}

for(int i=0; i<cases; i++){
    cout<<result[i]<<endl;
   }

return 0;
}

我想我让它变得更冗长和复杂,如何让它变得简单和简洁。

4

1 回答 1

0
#include <iostream>

using namespace std;

int main() {

    unsigned T;
    cin >> T;

    unsigned a, b;
    for (unsigned i=0; i<T; ++i) {

        cin >> a >> b;

        if (a < b) 
            swap(a, b);

        unsigned shift = 0;

        if (a > b) {
            while(!(a & 0x40)) {
                a <<= 1;
                b <<= 1;
                ++shift;
            }

            while(!(b & 0x40))
                b <<= 1;
            }

        cout << ((a ^ b) >> shift) << ' ';
    }

    return 0;
}

以及一些解释:

  • 虽然 A 和 B 都小于 107 并且每个都可以容纳一个字节,但我们应该使用 int 来处理它以保证 cin 数字解析能够正常工作;
  • 由于 xor 给出了与参数顺序无关的相同结果,我们可以根据需要交换 A 和 B - 并且 A 总是不小于 B 对我们很有用;
  • 由于 A 和 B 小于 107,我们可以事先确定它们的最高有效位(第 8 位)将始终为零,输入任何可能的值,因此初始每位左移(“<<= 1”)可能是执行直到第 7 位等于 1(通过将 0x40 掩码应用于 A/B 值并检查结果是否非零进行测试)而不是第 8 位;之后,B 仍将小于 A;
  • b 的零填充由 b 的进一步左移(如有必要)执行,直到其第 7 位也变为“1”;
  • 为了摆脱两个参数初始左移的影响,我们应该在异或之前将它们都右移回相同数量的位(“>> shift”),或者具有相同效果的右移他们在计算之前的异或结果 - 这更方便(对我来说)。
于 2018-02-25T23:10:44.383 回答