Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从数组中找到前几个值?_C#_Algorithm_Arrays_Max - Fatal编程技术网

C# 如何从数组中找到前几个值?

C# 如何从数组中找到前几个值?,c#,algorithm,arrays,max,C#,Algorithm,Arrays,Max,我有一个浮点值数组,需要这个值,更重要的是最大四个值的位置 我最初构建该系统是为了遍历数组,并以通常的方式找到最大值,方法是将当前位置的值与记录的最大值进行比较,并在最大值发生变化时更新位置变量。这是一个非常简单的O(n)算法,效果很好。后来我了解到,我不仅需要保留最高价值,还需要保留前三名或前四名。我扩展了相同的过程,将max复杂化为一个包含四个max的数组,现在代码很难看 它仍然有效,并且仍然足够快,因为只有少量的计算被添加到过程中。它仍然有效地遍历数组并检查每个值一次 我在MATLAB中使

我有一个浮点值数组,需要这个值,更重要的是最大四个值的位置

我最初构建该系统是为了遍历数组,并以通常的方式找到最大值,方法是将当前位置的值与记录的最大值进行比较,并在最大值发生变化时更新位置变量。这是一个非常简单的O(n)算法,效果很好。后来我了解到,我不仅需要保留最高价值,还需要保留前三名或前四名。我扩展了相同的过程,将max复杂化为一个包含四个max的数组,现在代码很难看

它仍然有效,并且仍然足够快,因为只有少量的计算被添加到过程中。它仍然有效地遍历数组并检查每个值一次

我在MATLAB中使用一个排序函数来实现这一点,该函数返回两个数组,排序列表和附带的原始位置列表。通过查看前几个值,我得到了我所需要的。我正在将此功能复制到C#.NET 2.0程序中

我知道我可以对列表对象做类似的事情,列表对象有一个内置的排序例程,但我不相信它能告诉我原始位置,而这些正是我真正想要的

它一直工作得很好,但现在我发现自己想要第五个max值,并且看到重写max-tour-checker(到目前为止,它是if语句的一团乱麻)只会让它更难看。添加第五个级别会很好,也不会慢,但我想问问SO社区是否有更好的方法

对整个列表进行排序需要比我目前的方法多得多的计算,但我认为这不会是一个问题,因为列表“只有”一到两千个浮点数;因此,如果有一个排序例程可以返回原始位置,那将是理想的


作为背景,这个数组是对一个千字节的波形文件进行傅里叶变换的结果,因此最大值的位置对应于样本数据的峰值频率。我对前四名很满意,但我认为有必要真正收集前五名或前六名,以获得更准确的样本分类。

我可以建议一种替代算法,您必须编写:)

使用大小为K的堆,其中K表示要保存的顶级元素的计数。将其初始化为原始数组的前K个元素。对于所有N-K元素,遍历数组,根据需要插入

proc top_k (array<n>, heap<k>)
heap <- array<1..k-1>
for each (array<k..n-1>) 
  if array[i] > heap.min
     heap.erase(heap.min)
     heap.insert(array[i])
  end if
end for
proc top_k(数组、堆)
heap.min
heap.erase(heap.min)
heap.insert(数组[i])
如果结束
结束

你仍然可以使用你的列表想法——你放在列表中的元素可以是一个存储索引和值的结构;但仅根据值进行排序,例如:

class IndexAndValue : IComparable<IndexAndValue>
{
    public int index;
    public double value;

    public int CompareTo(IndexAndValue other)
    {
        return value.CompareTo(other.value);
    }
}
类索引和值:i可比较
{
公共整数指数;
公共双重价值;
公共整数比较(索引和值其他)
{
返回值.CompareTo(其他.value);
}
}

然后您可以将它们粘贴到列表中,同时保留有关索引的信息。如果您只保留列表中最大的m项,那么您的效率应该是O(mn)。

我不知道您当前使用的是哪种算法,但我建议使用一种简单的算法。 承认您有一个浮点数组
f
,最大容量为
capacity
对于数字,您可以执行以下操作:

int capacity = 4; // number of floats you want to retrieve
float [] f; // your float list
float [] max_so_far = new float[capacity]; // max so far

// say that the first 'capacity' elements are the biggest, for now
for (int i = 0; i < capacity; i++)
  max_so_far[i] = i;

// for each number not processed
for (int i = capacity; i < f.length; i++)
{
  // find out the smallest 'max so far' number
  int m = 0;
  for (int j = 0; j < capacity; j++)
    if (f[max_so_far[j]] < f[max_so_far[m]])
      m = j;

  // if our current number is bigger than the smallest stored, replace it
  if (f[i] > f[max_so_far[m]])
    max_so_far[m] = i;
}
int-capacity=4;//要检索的浮点数
浮动[]f;//你的浮动名单
浮点数[]最大浮点数=新浮点数[容量];//到目前为止
//就目前而言,第一个“容量”要素是最大的
对于(int i=0;if[max_so_far[m]]
max_so_far[m]=i;
}
在算法结束时,将存储最大元素的索引 在
max\u sou\u far

请注意,如果
容量
值增加,它将比 备选方案,即在跟踪初始位置的同时对列表进行排序。
请记住,排序需要O(nlog n)比较,而此算法需要O(ncapacity)。

另一个选项是使用快速选择。 快速选择返回列表中第k个元素的位置。获得第k个元素的位置和值后,检查列表并获取每个值小于/大于第k个元素的元素

我在这里找到了quick select的c#实现:

优点:

  • O(n+k)平均运行时间
  • 缺点:

  • 未对找到的k个元素进行排序。如果对它们进行排序,则运行时间为O(n+logk)
  • 我没有检查这个,但是我认为对于一个非常小的k,最好的选择是在数组上运行k,每次查找下一个最小/最大的元素

  • 重复:Oi,我应该在发布之前搜索我问题的反面:)我想你的意思是“return value.CompareTo(other.value);”+1。非常好的解决方案,只需要O(nlogk)时间和O(k)空间。