创建所有可能的对象状态的集合

时间:2018-12-18 12:29:00

标签: c#

我有五个对象的链。每个对象的状态都可以为True或False。 我需要创建所有可能链的集合或字典,分别取决于对象状态。 例如:

        Value             Key
obj1 obj2 obj3 obj4 obj5  00000   //obj1=false obj2=false obj3=false obj4=false obj5=false
obj1 obj2 obj3 obj4 obj5  00001   //obj1=false obj2=false obj3=false obj4=false obj5=true
obj1 obj2 obj3 obj4 obj5  ..... 
obj1 obj2 obj3 obj4 obj5  11111   //obj1=true obj2=true obj3=true obj4=true obj5=true

如何以适当而优雅的方式做到这一点?

假设每个对象的类型均为

class Unit
{
    public bool State {get;set;}
}

链是

class Chain
{
    public Unit obj1 {get;set;}
    public Unit obj2 {get;set;}
    public Unit obj3 {get;set;}
    public Unit obj4 {get;set;}
    public Unit obj5 {get;set;}
}

词典项应为:链作为值,10101作为键

3 个答案:

答案 0 :(得分:3)

尝试使用 Linq :我们希望将Range中的0..31体现为Dictionary。唯一(可能)困难是位操作

  • 要为范围计算2**n(在我们的情况下为2**5 == 32),我们可以将1n位置向左移动我们的情况:1 << 5 == 0b10000 == 32
  • 要检查是否设置了第k位,我们可以使用value >> k & 1 != 0

关于发生的事情的一小幅画

      011...0101...1 : value
             ^
             k-th bit 

右移 value >> k)后:

            011...01 
                   ^
                   former k-th bit is now the 1st one (`01...1` part's gone)

            011...01 after bitwise & 1
                   1
            --------   
                   1 either 1 or 0 (depending on if k-th bit set or not)

代码:

  using System.Linq;

  ...

  var demo = Enumerable
    .Range(0, 1 << 5)
    .ToDictionary(key => key,
                  key => new {
                    //TODO: put right object here instead the anonymous one
                    obj1 = (key >> 4 & 1) != 0,
                    obj2 = (key >> 3 & 1) != 0,
                    obj3 = (key >> 2 & 1) != 0,
                    obj4 = (key >> 1 & 1) != 0,
                    obj5 = (key >> 0 & 1) != 0,
                  });

   Console.Write(string.Join(Environment.NewLine, demo));

结果:

   [0, { obj1 = False, obj2 = False, obj3 = False, obj4 = False, obj5 = False }]
   [1, { obj1 = False, obj2 = False, obj3 = False, obj4 = False, obj5 = True }]
   [2, { obj1 = False, obj2 = False, obj3 = False, obj4 = True, obj5 = False }]
    ...
   [29, { obj1 = True, obj2 = True, obj3 = True, obj4 = False, obj5 = True }]
   [30, { obj1 = True, obj2 = True, obj3 = True, obj4 = True, obj5 = False }]
   [31, { obj1 = True, obj2 = True, obj3 = True, obj4 = True, obj5 = True }]

答案 1 :(得分:1)

假设像二进制数据一样,00000 = 0和11111 = 31

List<string> result = new List<string>();

for(int i=0;i<32;i++)
{
   result.Add(Convert.ToString(i, 2).PadLeft('5','0'));
}

答案 2 :(得分:1)

保留单位列表而不是为每个项目都具有单独的属性(即

)可能更有意义。
other_job.scheduleBuild();

然后,如果您创建“链”:

class Chain
{
    readonly List<Unit> _units;
    public IReadOnlyList<Unit> Units => _units;

    public string Key => string.Concat(_units.Select(u => u.State ? "1" : "0"));

    public Chain(params bool[] units)
    {
        _units = units.Select(u => new Unit { State = u }).ToList();
    }
}

您可以使用var chain = new Chain(true, false, false, true, false); 来获取其密钥。