【问题标题】:Converting Boolean array into counter [closed]将布尔数组转换为计数器 [关闭]
【发布时间】:2021-01-01 19:47:03
【问题描述】:

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

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

以非常简单的方式,我希望布尔数组表现得像一个旋转编码器。

【问题讨论】:

  • 你试过什么?您至少需要展示一些代码或想法,以便我们为您提供帮助。

标签: c# arrays boolean counter


【解决方案1】:

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

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 封装到一个类中,因为您不希望实现细节泄露并让消费者随意处理您的数据结构。

【讨论】:

    【解决方案2】:
        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 的数组)

    【讨论】:

      【解决方案3】:

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

          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)}");
              }
          }
      

      以及产生的输出:

      【讨论】:

        【解决方案4】:

        你可以这样做:

        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 
        

        然后您可以扩展该类以满足您的需求。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-02
          • 2013-07-04
          • 2015-02-23
          • 1970-01-01
          • 1970-01-01
          • 2022-06-12
          • 2014-08-10
          • 2011-07-28
          相关资源
          最近更新 更多