自从峰值以来计数棒

时间:2012-04-02 03:51:24

标签: c# algorithm

我正在编写一个算法来计算自第n个峰值以来经过的柱数。 假设我有一个整数列表,它跟踪所有出现的峰值,如下所示。

  

371013

     

上面告诉我,峰值出现在索引371013。   源数据的长度为15

n = 1

然后我应该看到如下结果列表:

  • index 0 = null - 尚未达到峰值

  • index 1 = null - 尚未达到峰值

  • index 2 = null - 尚未达到峰值

  • index 3 = 0 - 峰值在这里被击中,因此通过的栏数为0

  • index 4 = 1 - 在前一个栏中达到峰值,因此通过的栏数为1

  • index 5 = 2 - 已经达到峰值并且传递的条数为2

  • index 6 = 3 - 已经达到峰值且通过的条数为3

  • index 7 = 0 - 峰值再次点击此处,因此自上次1(n)峰值以来经过的柱数为0,结果如下:

    index 8 = 1index 9 = 2index 10 = 0index 11 = 1index 12 = 2index 13 = 0index 14 = 1

假设n = 2

自最近2个峰值以来经过的柱数。结果如下:

  • index 0 = null

  • index 1 = null

  • index 2 = null

  • index 3 = null - 第一个高峰但是n = 2所以到目前为止没有第二个峰值......

  • index 4 = null

  • index 5 = null

  • index 6 = null

  • index 7 = 4 - 第二个峰值仅在此处命中,因此自上一个峰值以来经过的天数为4,这是从第一个峰值被击中的指数开始计算的,在这种情况下是3

  • index 8 = 5

  • index 9 = 6

  • index 10 = 3 - 此处达到了另一个峰值,此前的峰值(n = 2发生在index = 7,因此它从{{开始计算1}}

  • index = 7

  • index 11 = 4

  • index 12 = 5 - 此处达到了另一个峰值,此前的峰值(index 13 = 3发生在n = 2,因此它从{{开始计算1}}

  • index = 10

我写了一个算法来实现这一点,但它并没有给我正确的输出。如果有人能告诉我算法出了什么问题,或者提出更好的方法,我将不胜感激。

index = 10

2 个答案:

答案 0 :(得分:1)

试试这个:

int n =  GetNValue();// Get the N Value...   
List<int> listPeaks = GetPeakValue(); 
List<int?> result = new List<int?>(listData.Count);
for (int index = 0, peakIndex = -1, nextPeakIndex = peakIndex + n; index < listData.Count; index++)
{
    if (nextPeakIndex < listPeaks.Length && index == listPeaks[nextPeakIndex])
    {
        peakIndex++;
        nextPeakIndex++;
    }

    if (peakIndex < 0)
    {
        result.Add((int?)null);
    }
    else
    {
        result.Add((int?)(index - listPeaks[peakIndex]));
    }
}

答案 1 :(得分:0)

带有工作代码的简单算法(抱歉,但在Delphi中):

function IsPeak(i: Integer): Boolean;//modelling
begin
  Result := i in [3, 7, 10, 13, 15];
end;

var
  i, N: Integer;
  Q: TQueue<Integer>;
begin
  N := 2;

  //queue for last N peaks
  Q := TQueue<Integer>.Create;
  for i := 0 to 20 do begin

    //insert new peak in queue
    if IsPeak(i) then begin
      Q.Enqueue(i);
      //remove too old peak
      if Q.Count > N then
        Q.Dequeue;
     end;

    if Q.Count < N then 
      Memo1.Lines.Add(Format('%d null',[i]))
    else  //return difference with front element of the queue
      Memo1.Lines.Add(Format('%d %d',[i, i - Q.Peek]))
  end;
  Q.Free;

Result:

0 null
1 null
2 null
3 null
4 null
5 null
6 null
7 4
8 5
9 6
10 3
11 4
12 5
13 3
14 4
15 2
16 3
17 4
18 5
19 6
20 7