我正在编写将编写所有可能的子网和主机范围的程序。 例如,我有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;
答案 0 :(得分:0)
您的问题基本上是如何使用零和1的所有可能组合生成n个字符深/长序列。这个问题已有答案here。
根据您的要求进行调整很简单:GetNthEnumeration(new[] { "0", "1" }, 3).ToList();
答案 1 :(得分:0)
有一个技巧可以让你非常干净地做到这一点:
假设您希望为数字“位”打开所有位组合
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 并没有真正做任何事情)