【问题标题】:How to get all combination from bits?如何从位中获得所有组合?
【发布时间】:2017-05-04 16:40:39
【问题描述】:

我正在编写将编写所有可能的子网和主机范围的程序。 例如,我有 4 位用于子网,所以我需要编写所有可能的组合。 输入:4:输出(数组):0000,0001,0010,0011,0100,0101...1111 我做的太慢了:递增十进制数->转换为二进制,我想不转换.

这是我的错误算法,但它有效

   public List<string> getAllCombination(int bits)
    {
        List<string> strarray = new List<string>();
        string temp = "";
        //make 1st word 
        for(int i = 0;i< bits;i++)
        {
            temp += "0";
        }
        strarray.Add(temp);
        int loops = (int)Math.Pow(2, bits) - 1;
        for(int i = 0; i< loops;i++)
        {
            int smallestBitPosition = -1;
            //find last 1
            for(int j = temp.Length -1 ; j >= 0; j--)
            {
                if (temp[j] == '1')
                    smallestBitPosition = j;

            }
            StringBuilder temp1 = new StringBuilder(temp);
            //if there are no 1 
            if (smallestBitPosition == -1)
            {
                temp1[temp1.Length - 1] = '1';
                temp = temp1.ToString();
                strarray.Add(temp);
                continue;
            }

            int lastZeroPosition = -1;
            //find last zero
            for (int j = smallestBitPosition; j< temp.Length; j++)
            {
                if (temp[j] == '0')
                    lastZeroPosition = j;
            }
            //if theres no 0 
            if(lastZeroPosition == -1 )
            {
                temp1[smallestBitPosition - 1] = '1';
                for(int g = smallestBitPosition ; g  < temp.Length; g++ )
                {
                    temp1[g] = '0';
                }
                temp = temp1.ToString();
                strarray.Add(temp);
                continue;
            }
            //i dont even know how to describe this, without this part it makes for example 101 -> 111, when it should be 110
            else if ((lastZeroPosition + 1 != bits) && temp[lastZeroPosition + 1] == '1')
            {
                temp1[lastZeroPosition] = '1';
                for (int g = lastZeroPosition + 1; g < temp.Length; g++)
                {
                    temp1[g] = '0';
                }
                temp = temp1.ToString();
                strarray.Add(temp);
                continue;
            }
            else
            {
                temp1[lastZeroPosition] = '1';

                temp = temp1.ToString();
                strarray.Add(temp);
                continue;
            }
        }
        return strarray;

【问题讨论】:

  • 你在请人做你的工作。首先对您的程序进行基准测试。确定您的程序运行速度以及您希望它运行的速度。然后尝试找到优化它的方法,如果你失败了,然后发布你的代码,告诉你想要它有多快以及你试图实现这一点。
  • 好吧,我的新想法是在字符串上制作自己的“二进制”,我会尝试一下;D
  • 你可以试试看这篇论文math.mcgill.ca/haron/Papers/Journal/coolTOCS.pdf
  • 由于您在某处写入所有这些结果,到目前为止,最慢的事情将是您的 I/O。最有效的方法是在计算下一个结果时异步写入一个结果。在这种情况下,您的算法生成字符串的速度几乎无关紧要,因为即使是最慢的也可能比 I/O 快几个数量级。
  • 查看您的代码,我没有看到您所描述的任何“十进制”。看起来您正在使用字符串手动进行二进制算术运算。一般来说,对于计算机来说,数学和逻辑很快,I/O、内存分配和复制很慢。所以尽量避免字符串操作,因为它往往有很多慢的东西。例如,即使 accessing 来自字符串生成器的字符也很慢。

标签: c# networking binary bit


【解决方案1】:

您的问题基本上是如何生成一个包含所有可能的零和一组合的深度/长字符序列。这个问题已经有了答案here

根据您的要求调整它很容易:GetNthEnumeration(new[] { "0", "1" }, 3).ToList();

【讨论】:

  • 谢谢,我的速度似乎更快......对于 20bites,我得到了结果:ElapsedMine=00:00:00.6530281 ElapsedRecursive=00:00:01.8145570
【解决方案2】:

有一个技巧可以让你非常干净地做到这一点:

假设您希望为一个数字“位”打开所有位组合

bits = 1111
combination = bits
rv = [bits]
while n != 0:
    combination = (combination - 1) & bits
    rv.append(combination)
return rv

这将为您提供“位”中设置的任何位的每种组合。这也不需要是完整的 1 位序列。如果你使用 bits = 1010 它只会返回 1010, 1000, 0010, 0000

如果“位”仅由 1 组成,那么您基本上是通过一次计数 1 从原始数字中减去到零。 (即 & 与 1111 并没有真正做任何事情)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多