使用按位AND查找列表中两个数字之间的最大差异

时间:2016-06-08 03:46:09

标签: c# loops optimization bitwise-and

大家好我正在解决一个问题:

  

给定一组S = {1,2,3,... N}。找到两个整数A和B,其中(A      

样本输入1:5 2,(其中n = 5,k = 2)=>输出:1,

     

样本输入2:8 5,(其中n = 8,k = 5)=>输出:4

我写了代码,这似乎工作正常。但我正在寻找更优化的解决方案。我目前正在使用两个while循环,我不确定可以减少到单个while或for循环。以下是我的功能:

static void Main(String[] args)
{
    string[] tokens_n = Console.ReadLine().Split(' ');
    int n = Convert.ToInt32(tokens_n[0]);
    int k = Convert.ToInt32(tokens_n[1]);
    int i = 1, maxDiff = 0;
    while (i < n)
    {
      int j = i + 1;
      while (j <= n)
      {
        int diff = i & j;
        if (diff < k)
        {
          if (diff > maxDiff)
          {
            maxDiff = diff;
          }
        }
        j++;
      }
      i++;
    }
    Console.WriteLine(maxDiff);
}

我找到了一个解决方案here,但问题似乎是在列表中找到两个任意数字的最大差异,而我需要循环所有组合以找到按位AND值然后进行比较。

3 个答案:

答案 0 :(得分:1)

int maxAnd = INT_MIN;
    for(int i = 1; i < k; i++) {
        for(int j = i + 1; j <= n; j++) {
            int currentAnd = i & j;
            if (currentAnd > maxAnd)
                maxAnd = currentAnd;
        }
    }
    cout << maxAnd << endl;

答案 1 :(得分:0)

从效率角度来看,这可能不是更优化,但更具可读性。

    var list = new[] {1, 2, 3, 4, 5};
    var k = 2;

    var combinations = 
        from item1 in list
        from item2 in list
        where
            (item1 < item2) &&
            (item1 & item2) < k
        orderby item1 & item2 descending
        select new {item1, item2};

    Console
        .WriteLine(combinations.First());

答案 2 :(得分:0)

事实证明,解决方案可以大大简化(就我们检查的内容而言,而不是可读性)。因此,我不是提供改进代码的方法,而是提供原始需求的新解决方案

void Main()
{
    var n = 2;
    var k = 2;

    //Best solution is for k - 1 (that is, B = k - 1, and then we check all possible As)
    for (var i = k - 1; i > 0; i--)
    {
        int j;
        int index = 1;
        //The only possible A is when 
        //1. j <= n
        //2. j contains all the same bits as i since we identify that `i` is the possible solution, 
        //   and we are using bit-wise AND, we
        //So, here were looping while the number is the same as i, continually flipping bits on
        //Since we're shifting bits in, we can assume the first value != i is a solution, as we only care about j becoming too large
        while ((j = (i | index)) == i && j <= n)
            index = (index << 1) | 1;

        // If j <= n, and it contains all the bits of i, and i <= k - 1, then we have a solution
        if (j <= n)
        {
            Console.WriteLine($"i = {i}, j = {j}, Solution = {i & j}");
            return;
        }
    }

    if (n < 2 || k < 1)
        Console.WriteLine("No solution");
    else
        Console.WriteLine($"i = 1, j = 2, Solution = 0");
} 

这种方法可以让我们解决输入,例如:

var n = 24827492;
var k = 2384972;

几乎尽可能快地获得低值。