将布尔数组转换为计数器

Converting Boolean array into counter

我有一个大小为 12 的布尔数组。在任何时候,只有一个索引为真。数组连接到旋钮上的 12 个位置,从 0 到 11。如果我们将旋钮从位置 5 顺时针移动到 6,则数组中的索引 5 将变为 false,索引 6 将变为 True。 11位后旋钮会移回0位。

我想创建一个随着旋钮顺时针或逆时针移动而增加或减少的计数器。如果位置从 11 变为 0,计数器也将继续增加。同样,从 0 移动到 12,计数器将减少。

以非常简单的方式,我希望布尔数组的行为类似于旋转编码器。

我不会用数组来做。创建具有此特定功能的对象

public class RotaryEncoder {
     private int totalPositions:
     public int ActiveIndex = { get; private set; }

     public RotaryEncoder(int totalPositions) {
          this.totalPositions = totalPositions;
          this.ActiveIndex = 0;
     }

     public void IncreasePosition() {
         ActiveIndex = ActiveIndex + 1 == totalPositions ? 0 : ActiveIndex + 1;
     }
}

你知道如何减少头寸了。布尔数组本身没有作为活动索引的额外属性。

另一种方法是让您创建一个包含布尔值和索引的新对象集合,并同时更改活动项和新活动项。 (效率肯定低)。

如果当然,您将不得不再次将 then 封装到 class 中,因为您不希望实现细节泄露并让消费者随意处理您的数据结构。

    public static void Main(string[] args)
    {
        Console.WriteLine(GetCounter(new[] { false, false, false, true, false }));
        Console.WriteLine(GetCounter(new[] { false, false, false, false, true }));
        Console.WriteLine(GetCounter(new[] { true, false, false, false, false }));
        Console.WriteLine(GetCounter(new[] { false, true, false, false, false }));
    }

    public static int GetCounter(bool[] array)
    {
        if (array.Length == 0)
            throw new ArgumentException("Array must at least be of size 1");

        int counter = -1;
        for (var i = 0; i < array.Length; i++)
        {
            if (array[i])
            {
                if (counter != -1)
                    throw new Exception("Multiple positions are true in the array");
                counter = i;
            }
        }

        if (counter == -1)
            throw new Exception("No positions are true in the array");
        return counter;

    }

这将打印以下内容:

    3
    4
    0
    1

(我在示例中使用了长度为 5 的数组,但它适用于任何长度 > 0 的数组)

这里是布尔数组的解决方案:

    public static void Main()
    {
        var values = new[]
        {
            false, false, false, false, false, false,
            false, false, false, false, false, false
        };
        var length = values.Length;
        var counter = 0;
        var previous = 0;
        var current = 0;

        while (counter < 25) // or any condition
        {
            current = counter++ % length;
            values[previous] = false;
            values[current] = true;
            previous = current;

            Console.WriteLine($"Count: {counter}\tIndex: {current}\t{string.Join(",\t", values)}");
        }
    }

以及产生的输出:

你可以这样做:

public class RotaryEncoder
{
    private const int DefaultTotalPositions = 11;
    
    private readonly int _totalPositions;

    public bool[] Knobs => GetArray();
    
    public int Position { get; private set; }
    
    public RotaryEncoder() : this(DefaultTotalPositions)
    {
        
    }
    
    public RotaryEncoder(int totalPositions)
    {
        if(totalPositions <= 0) 
        {           
            totalPositions = DefaultTotalPositions; 
        }
        
        _totalPositions = totalPositions;       
    }
    
    public void Increase() => Increase(1);
    
    public void Decrease() => Decrease(1);
    
    public void Increase(int positions)
    {
        var adjustedPosition = AdjustBeforeAddOrSubtract(Position + positions);
        Position = adjustedPosition;            
    }
    
    public void Decrease(int positions)
    {
        var adjustedPosition = AdjustBeforeAddOrSubtract(Position - positions);
        Position = adjustedPosition;                
    }
    
    
    private bool[] GetArray()
    {
        var knobs = new bool[_totalPositions];
        knobs[Position] = true;         
        return knobs;
    }

    private int AdjustBeforeAddOrSubtract(int positions)
    {
        return positions > _totalPositions || positions < 0 ? 0 : positions;
    }
}

用法示例:

var knobs = new RotaryEncoder(); // will create a 11 knobs
knobs.Increase(); // would increase by 1
// knobs.Increase(6); // would increase by 6
var currentknobs = knobs.Knobs; // would return a boolean array with the current knobs 

然后您可以扩展 class 以满足您的需要。