将布尔数组转换为计数器
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 以满足您的需要。
我有一个大小为 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 以满足您的需要。