将单个阵列与多个不同的阵列进行比较
本文关键字:阵列 比较 单个 | 更新日期: 2023-09-27 18:04:49
对于processor affinity
上的一个小项目,我想创建一个更简单的方法,而不仅仅是一堆if(lvProcessors.Items[0].Checked == true && lvProcessors.Items[1] == true etc)
比较它们的确切值,以查看哪些代码需要传输到(IntPtr)
。
为了使代码更加高效,我想将一个包含booleans
的数组与至少14个其他包含booleans
的数组进行比较。
示例代码:
var CheckState = new[] { lvProcessors.Items[0].Checked, lvProcessors.Items[1].Checked, lvProcessors.Items[2].Checked, lvProcessors.Items[3].Checked };
//setcore1 == 1, setcore2 == 2, etc
var SetCore1 = new[] { true, false,false,false };
var SetCore2 = new[] { true, true, false, false };
var SetCore3 = new[] { false, true, false, false };
var SetCore4 = new[] { true, false, true, false };
var SetCore5 = new[] { false, true, true, false };
var SetCore6 = new[] { true, true, true, false };
var SetCore7 = new[] { false, false, false, true };
var SetCore8 = new[] { true, false, false, true };
var SetCore9 = new[] { false, true, false, true };
var SetCore10 = new[] { true, true, false, true };
var SetCore11 = new[] { false, false, true, true };
var SetCore12 = new[] { true, false, true, true };
var SetCore13 = new[] { false, true, true, true };
var SetCore14 = new[] { true, true, true, true };
int switchcounter = 1;
switch (switchcounter)
{
case 15:
break;
default:
if (Enumerable.SequenceEqual(CheckState,<insertdynamicarrayname))
{
AffinityState = (IntPtr)switchcounter;
}
else
{
switchcounter++;
goto default;
}
break;
}
因此,如果检查了listview lvProcessors
中的第一个checkbox
,则var CheckState
将生成包含{ true, false,false,false }
的阵列
这反过来必须与SetCore
阵列中的一个进行比较,并且在这种情况下将导致与SetCore1
匹配。
所以我想知道的是;我如何创建一个动态数组,基于代码上的switchcounter
,它将融合"SetCore"
和switchcounter.ToString()
,从而创建SetCore1, SetCore2, SetCore3, etc
。
[编辑]
正如@Luaan所建议的,我已经将他的代码实现为我想要的样子:
var SetCore1 = new[] { true, false, false, false};
[..]
var SetCore15 = new[] { true, true, true, true };
var allSets = new [] { SetCore1, SetCore2, SetCore3,SetCore4,SetCore5,SetCore6,SetCore7,SetCore8,SetCore9,SetCore10,SetCore11,SetCore12,SetCore13,SetCore14,SetCore15 };
foreach (var set in allSets)
{
MessageBox.Show(counter.ToString());
if (Enumerable.SequenceEqual(set, CheckState))
{
AffinityState = (IntPtr)counter;
break;
}
else if (Enumerable.SequenceEqual(set, CheckState) == false)
{
counter++;
}
}
EditProcess.ProcessorAffinity = (IntPtr)AffinityState;
在该代码中,根据listviewcheckboxes
的输入,它将把依赖的结果与SetCore
匹配,并且使用counter
,它将给出在foreach
循环结束时转换的正确的int
,并设置非常特定的核(即1、2或0、2、3等(用于在代码中较早选择的所选process
(不可见(。
感谢您对比特掩码的建议,它们看起来很有用,但目前我不知道如何在不拆开一半应用程序的情况下实现它们。
只需制作一个数组:
var allSets = new [][] { SetCore1, SetCore2, SetCore3, ... }
然后你可以使用一个简单的循环:
for (var i = 0; i < allSets.Length; i++)
HandleSet(allSets[i]);
使用Enumerable.SequenceEqual
会有点慢。如果你关心性能(我认为在这种情况下你不一定这么做(,看看BitArray
——它的内存要小得多,匹配主要是一个简单的位掩码。
编辑:
如果你想在bool[]
和int
(或者byte
,无论你需要什么(之间转换,你可以使用这样的东西:
public bool[] ToBoolArray(int val)
{
var bits = new bool[sizeof(int) * 8];
for (var i = 0; i < bits.Length; i++)
{
bits[i] = (val & (1 << i)) > 0;
}
return bits;
}
public int ToInt32(bool[] bits)
{
var output = default(int);
for (var i = 0; i < bits.Length; i++)
{
output |= bits[i] ? 1 << i : 0;
}
return output;
}
这样就避免了处理大量烦人的字符串。使用BitArray
更简单——从int
创建BitArray
很简单(有一个构造函数(,并且可以很容易地将其更改回int
,只需使用bits.Get(i)
而不是bits[i]
。
或者更好的是,制作自己的类来处理这个问题:
public sealed class CpuMask
{
private int _bits;
public bool this[int index]
{
get { return (_bits & (1 << index)) > 0; }
set { if (value) _bits |= (1 << index); else _bits &= ~(1 << index); }
}
public CpuMask(int mask)
{
_bits = mask;
}
public CpuMask(IntPtr mask) : this(mask.ToInt32()) { }
public IntPtr ToIntPtr() { return new IntPtr(_bits); }
}