📜  将给定a转换为b的最小按位运算。

📅  最后修改于: 2021-05-25 09:00:18             🧑  作者: Mango

给定两个正整数a和b,您必须通过对a的二进制形式应用这三个操作中的任何一个来将a更改为b。您可以从a的二进制形式中选择ai和aj(i!= j的任何两个位),然后执行以下操作:

  • AND运算为:temp = ai&aj,ai = temp&ai,aj = temp&aj
  • 或运算为:temp = ai | aj,ai = temp | ai,aj = temp | j
  • XOR运算为:temp = ai ^ aj,ai = temp ^ ai,aj = temp ^ aj

其中&=按位与,| | = bitwiese或,^ =按位XOR。
找到将a转换为b所需的最小操作。另外,如果无法将a转换为b,则打印-1。

例子:

Input : a = 12 (1100), b = 10 (1010)
Output : 1
Explanation : select a2 and a3 and perform XOR 

Input : a = 15 (1111), b = 10 (1010)
Output : -1
Explanation : Conversion from a to b is not possible

说明:首先,让我们了解这三个操作的工作原理。

  1. AND运算为:temp = ai&aj,ai = temp&ai,aj = temp&aj

    如果ai或aj中的任何一个为0,则将两者都设为0,否则对ai和aj没有影响。

  2. 或运算为:temp = ai | aj,ai = temp | ai,aj = temp | j

    如果ai或aj中的任何一个为1,则两者都为1,否则对ai和aj没有影响。

  3. XOR运算为:temp = ai ^ aj,ai = temp ^ ai,aj = temp ^ aj

    只需互换ai和aj的值即可。

根据运营工作得出的一些结论:

  1. 如果a的所有位均为1或0,则我们无法更改a的值。
  2. 如果a等于b,则不需要任何操作。
  3. 令n为索引i的数量,其中ai = 0且bi = 1。
    令m为索引i的数量,其中ai = 1,bi = 0。

    让我们考虑n个元素,其中ai = 0和bi =1。我们必须将所有这些零更改为1。请注意,这至少需要进行n次操作。
    类似地,对于所有m个元素,其中ai = 1和bi =0。我们必须将所有这些元素都更改为零。请注意,这至少需要进行m次操作。

    令res = max(n,m)。我们可以使a和b在res运算中相等,如下所示。

    令n> = m。取A中的m 1和n 0,然后应用XOR操作将0与1交换。之后,您将剩下的总nm零元素更改为1。您可以通过将这些零中的每一个与单个零相乘并应用“或”运算来实现。
    令m> = n。取A中的m 1和n 0,然后应用XOR操作将0与1交换。之后,您将剩下的总数mn个元素变为零。您可以通过将每个这些取一个单个零并应用“或”运算来实现。

// Cpp program to find min operation to convert a to b
#include 
using namespace std;
  
// function to return min operation
int minOp(bitset<32> a1, bitset<32> b1)
{
    // if a1 == b1 return 0
    if (a1 == b1)
        return 0;
  
    // if all bits of a = 0
    if (a1 == 0)
        return -1;
  
    // if all bits of a =1
    // first convert a1 to int and then cal a1 & a1+1
    if (((int)a1.to_ulong() & ((int)a1.to_ulong() + 1)) 
                                               == 0)
        return -1;
  
    // convert a and b to binary string
    string a = a1.to_string();
    string b = b1.to_string();
  
    // check where ai and bi are different
    // and count n where ai = 1 and m where ai = 0
    int n = 0, m = 0;
    for (int i = 0; i < b.size(); i++) {
        if (b[i] != a[i]) {
            if (a[i] == '1')
                n++;
            else
                m++;
        }
    }
  
    // return result
    return max(n, m);
}
  
// driver program
int main()
{
    bitset<32> a = 14, b = 1;
    cout << minOp(a, b);
    return 0;
}

输出:

3