C# 给定布尔数组,如何使这些循环更具性能?
如果您有:C# 给定布尔数组,如何使这些循环更具性能?,c#,arrays,loops,C#,Arrays,Loops,如果您有: bool[] arrayExample = {false, true, false, false, true, true, false, false, true, true, true}; 给定一个n值,我在数组中循环查找哪个索引具有真值 例如:如果n=1:我想返回所有具有1个真值的索引。因此,返回列表将是{1,4,5,8,9,10} 如果n=2:我想返回一个列表,使其索引在一行中有两个真值:{4,8,9} 另外,我想为n=3做这个 是否有更干净/更高效的方法来运行此代码 List
bool[] arrayExample = {false, true, false, false, true, true, false, false, true, true, true};
给定一个n值,我在数组中循环查找哪个索引具有真值
例如:如果n=1:我想返回所有具有1个真值的索引。因此,返回列表将是{1,4,5,8,9,10}
如果n=2:我想返回一个列表,使其索引在一行中有两个真值:{4,8,9}
另外,我想为n=3做这个
是否有更干净/更高效的方法来运行此代码
List<int> indices = new List<int>();
bool counter = false;
if (n == 1)
{
for (int i = 0; i < arrayExample.Length; ++i)
{
if (arrayExample[i])
{
indices.Add(i);
}
}
}
else if (n == 2)
{
for (int i = 0; i < arrayExample.Length; ++i)
{
if (counter == true && arrayExample[i] == false)
{
counter = false;
}
if (arrayExample [i])
{
if (counter == false)
{
counter = true;
}
else
{
indices.Add(i);
counter = false;
}
}
}
}
这里有一个想法:
以数组为例:[F,T,F,F,T,T,F,F,T,T,T,T]
从头到尾,标记在每个位置遇到的真值数量:[0,1,0,0,2,1,0,0,3,2,1]。
现在您可以得到任意n的答案:返回每个索引,其中array[index]>=n如何:
static void Main(string[] args)
{
bool[] arrayExample = { false, true, false, false, true, true, false, false, true, true, true };
List<int> result = Foo(1, arrayExample);
foreach(var num in result)
Console.WriteLine(num);
Console.ReadKey();
}
static List<int> Foo(int num,bool[] arr)
{
List<int> indices = new List<int>();
int count = 0;
for (int i = 0; i < arr.Length; i++)
{
if(arr[i])
{
for (int j = 0; j < num; j++)
{
if(!arr[i+j])
{
count = 0;
break;
}
count++;
}
if (count > 0)
indices.Add(i);
}
}
return indices;
}
代码的速度可能还可以;但是,您可以简化算法
const bool F = false, T = true;
bool[] arrayExample = { F, T, F, F, T, T, F, F, T, T, T };
var indices = new List<int>();
int count = 0;
int n = 2;
int delta = n - 1;
for (int i = 0; i < arrayExample.Length; i++) {
if (arrayExample[i]) {
count++;
if (count >= n)
indices.Add(i - delta);
} else
count = 0;
}
这对任何人都有效。计算遇到的后续真值的数量,并在该计数至少等于所需序列长度时添加索引。因为您需要序列中第一个索引的索引,所以必须减去n-1
该算法直接按升序生成索引,不需要临时数组,也没有嵌套循环。也就是说,它的时间性能为On,这里n代表输入的长度。我只是想把我的代码放在混合中,无论如何,速度都不足以提供任何有用的见解:
public static IEnumerable<int> TrueIndicesCounter(int counter, List<bool> booleans)
{
if (counter <= 0) return new List<int>();
var truths = new List<int>();
for (var booleanIndex = 0; booleanIndex < booleans.Count; booleanIndex++)
{
var boolean = booleans[booleanIndex];
if (boolean != true) continue;
if (counter == 1)
{
truths.Add(booleanIndex);
continue;
}
var counterIndex = 1;
var counterSatisfied = false;
while (counterIndex <= counter)
{
var targetBoolean = booleans.ElementAtOrDefault(booleanIndex + counterIndex);
if (targetBoolean != true) break;
counterIndex++;
if (counterIndex != counter) continue;
counterSatisfied = true;
break;
}
if (counterSatisfied)
truths.Add(booleanIndex);
}
return truths;
}
您可以尝试@Dennis_E给出的想法,如下所示:
int i, j;
int[] rep = new int[arrayExample.Length];
if (rep[arrayExample.Length - 1])
rep[arrayExample.Length - 1] = 1;
for (i = arrayExample.Length - 2; i >= 0; i--)
if (arrayExample[i])
rep[i] = rep[i + 1] + 1;
for (i = 0 ; i < arrayExample.Length; i++)
if (count == n)
indices.Add(i);
什么是计数器、间隔和可用性阵列?性能是瓶颈吗?这看起来像意大利面代码,为了清晰起见需要重写,但是除非性能不可接受,否则不要尝试微优化。这段代码给出了正确的答案吗?如果是这样的话,你应该结帐以获得关于如何改进它的反馈。这可能包括如何使您的代码更易于理解,以及如何使用来自C的惯用构造以及优化。间隔只能为1或2?使用linq:int[]results=arrayExample.Selectx,i=>new{x=x,i=i}。其中x=>x.x.Selectx=>x.i.ToArray;我真的很喜欢这种方法。我会看看我是否能编程。非常感谢。