C# 从高峰开始数吧
我正在写一个算法来计算自第n个峰值以来通过的条数。 假设我有一个整数列表,它跟踪所有出现的峰值,如下所示C# 从高峰开始数吧,c#,algorithm,C#,Algorithm,我正在写一个算法来计算自第n个峰值以来通过的条数。 假设我有一个整数列表,它跟踪所有出现的峰值,如下所示 3,7,10,13 上面告诉我,峰值出现在索引3、7、10和13 源数据的长度为15 让n=1 然后我会看到一个结果列表,如下所示: 索引0=null-还没有峰值 索引1=null-还没有峰值 索引2=null-还没有峰值 索引3=0-此处达到峰值,因此通过的条数为0 索引4=1-上一条中达到峰值,因此通过的条数为1 索引5=2-已达到峰值,通过的条数为2 索引6=3-已达到峰值,通过的条
3
,7
,10
,13
上面告诉我,峰值出现在索引3
、7
、10
和13
源数据的长度为
15
让n=1
然后我会看到一个结果列表,如下所示:
-还没有峰值索引0=null
-还没有峰值索引1=null
-还没有峰值索引2=null
-此处达到峰值,因此通过的条数为0索引3=0
-上一条中达到峰值,因此通过的条数为1索引4=1
-已达到峰值,通过的条数为2索引5=2
-已达到峰值,通过的条数为3索引6=3
-再次达到峰值,因此自最后1(n)个峰值以来通过的条数为0,结果如下:索引7=0
,索引8=1
,索引9=2
,索引10=0
,索引11=1
,索引12=2
,索引13=0
索引14=1
n=2
自最近两个峰值以来通过的棒数。因此,结果如下:
索引0=null
index 1=null
index 2=null
-第一个峰值,但索引3=null
因此目前没有第二个峰值n=2
index 4=null
index 5=null
index 6=null
-此处仅出现第二个峰值,因此自最后两个峰值以来经过的天数为4天,这从出现第一个峰值的索引开始计算,在本例中为3天索引7=4
索引8=5
索引9=6
-这里又出现了一个峰值,在此之前的峰值(index 10=3
)发生在n=2
,因此它是从index=7
开始计算的index=7
索引11=4
索引12=5
-这里又出现了一个峰值,在此之前的峰值(index 13=3
)发生在n=2
,因此从index=10
开始计算index=10
索引14=4
int nth = GetNValue();// Get the N Value...
//SourceData = listData
int peakCount = 0;
int value= 0;
int barssince = 0;
List<Data> listValue = new List<Data>();
List<int> listResult = new List<int); //to hold the result..
List<int> listPeaks = GetPeakValue();
for (int index = 0; index < listData.Count; index++)
{
if (peakcount > 0)
{
barssince++;
listValue[listValue.Count - 1].Value = barssince;
}
int foundPeak = listPeaks.Find(delegate(int p) { return p == index; });
if (foundPeak != -1)//Peak FOund
{
peakcount++;
listValue.Add(new Data() { Value = barssince });
if (peakcount > nth)
{
listValue.RemoveAt(0);
}
barssince = 0;
}
value = listValue.Count >= nth ? listValue.Sum(p => p.Value) : null;
listResult.Add(value);
}
private class Data
{
public int Value { get; set; }
}
int nth=GetNValue();//获取N值。。。
//SourceData=listData
int peakCount=0;
int值=0;
int barssince=0;
List listValue=新列表();
列表结果=新列表(0)
{
barssince++;
listValue[listValue.Count-1].Value=barssince;
}
Find(委托(intp){returnp==index;});
if(foundPeak!=-1)//找到峰值
{
peakcount++;
Add(新数据(){Value=barssince});
如果(峰值计数>第n个)
{
listValue.RemoveAt(0);
}
barssince=0;
}
value=listValue.Count>=n?Sum(p=>p.Value):null;
listResult.Add(值);
}
私有类数据
{
公共int值{get;set;}
}
试试这个:
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]));
}
}
int n=GetNValue();//获取N值。。。
List listPeaks=GetPeakValue();
列表结果=新列表(listData.Count);
对于(int index=0,peakIndex=-1,nextPeakIndex=peakIndex+n;index
带有工作代码的简单算法(抱歉,在Delphi中):
函数IsPeak(i:Integer):布尔型//造型
开始
结果:=i在[3,7,10,13,15]中;
结束;
变量
i、 N:整数;
Q:TQUUE;
开始
N:=2;
//排队等待最后N个峰值
Q:=TQueue.Create;
对于i:=0到20,开始
//在队列中插入新峰值
如果是IsPeak(i),则开始
Q.排队(i);
//删除太旧的峰值
如果Q.计数>N,则
Q.出列;
结束;
如果Q.计数
使用堆栈查找峰值并将其存储在列表中。您可能可以使用某种二进制搜索来加速为给定索引i
传递的条数。如果要查找整个数组,可以在O(n)
中完成。
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