使用连接计数数组在数组中的索引处查找项的有效方法

时间:2012-02-02 16:24:47

标签: c# arrays processing-efficiency

我有一个包含两个数组的对象,第一个是斜率数组:

double[] Slopes = new double[capacity];

接下来是一个包含各种斜率计数的数组:

int[] Counts = new int[capacity];

数组是相关的,因为当我向对象添加斜率时,如果在斜率数组中输入的最后一个元素与新项目的斜率相同,而不是将其添加为新元素,则计数会增加。

即。如果我有斜坡15 15 15 12 4 15 15,我得到:

Slopes = { 15, 12, 4, 15 }
Counts = {  3,  1, 1,  2 }

是否有更好的方法在斜率中找到第i个项目而不是使用索引迭代Counts并在Slopes中找到相应的索引?

编辑:不确定我的问题是否可能不清楚。我需要能够访问发生的第i个斜率,因此从示例中出现的零索引i = 3斜率是12,问题是是否存在更有效的解决方案以在新结构中找到相应的斜率。

也许这有助于更好地理解这个问题:这是我现在如何获得i_th元素:

public double GetSlope(int index)
        int countIndex = 0;
        int countAccum = 0;
        foreach (int count in Counts)
        {
            countAccum += count;
            if (index - countAccum < 0)
            {
                return Slopes[countIndex];
            }
            else
            {
                countIndex++;
            }
        }
        return Slopes[Index];
}

我想知道是否有更有效的方式?

6 个答案:

答案 0 :(得分:1)

如果您一次加载斜坡并执行许多这些“第i项”查找,则可能有助于获得第三个(或者代替计数,取决于用于什么)数组与总计。对于您的示例,这将是{ 0, 3, 4, 5 }。然后你不需要为每次查找添加它们,这只是“我在Totals [x]和Totals [x + 1]之间”的问题。如果你期望有很少的斜坡铲斗,或者在整个加工过程中增加斜坡,或者如果你没有做很多这些观察,那么它可能不会给你买任何东西。从本质上讲,这只是一次性完成所有这些新增功能。

答案 1 :(得分:1)

您可以使用第三个数组来存储重复斜率的第一个索引

double[] Slopes = new double[capacity];
int[] Counts = new int[capacity]; 
int[] Indexes = new int[capacity]; 

使用

Slopes  = { 15, 12, 4, 15 }
Counts  = {  3,  1, 1,  2 } 
Indexes = {  0,  3, 4,  5 } 

现在,您可以在Indexes中应用二进制搜索来搜索索引,该索引小于或等于您要查找的索引。

现在有了O(log(n))。

,而不是O(n)搜索性能

答案 2 :(得分:1)

您始终可以将现有数组和另一个数组(称为OriginalSlopes)包装到类中。当您添加到Slopes时,您也会像普通数组一样添加OriginalSlopes(即始终追加)。如果您需要i_th斜率,请在OriginalSlopes中查找。 O(1)操作四周。

修改添加示例数据:

Slopes = { 15, 12, 4, 15 }
Counts = {  3,  1, 1,  2 }
OriginalSlopes = { 15, 15, 15, 12, 4, 15, 15 }

答案 3 :(得分:1)

在count对象(或基础中的数组)中,添加一个到目前为止已找到cumulative count的变量。

使用comparator方法进行二元搜索,比较cumulative count,您可以在O(log N)时间内找到斜率。

修改

`Data = 15 15 15 12 4 15 15`
Slopes = { 15, 12, 4, 15 }
Counts = {  3,  1, 1,  2 }
Cumulative count = { 3, 4, 5, 7}

例如,如果您在第6个位置查找元素,当您搜索Cumulative count数据集并找到值5,并且知道下一个值为7时,您可以确定该索引处的元素将具有第六位置元素。

使用二进制搜索在log(N)时间内查找元素。

答案 4 :(得分:0)

编辑:您可以使用字典,其中键是斜率,每个键的值是相应索引和计数的列表。类似的东西:

class IndexCount
{
    public int Index { get; set; }
    public int Count { get; set; }
}

您的收藏声明如下:

var slopes = new Dictionary<double, List<IndexCount>>();

然后,您可以按值查找字典,并从关联的集合中查看每个索引的计数。这可能会使您的代码非常有趣。如果性能不是主要问题,我会采用下面的列表方法。


您可以使用单个列表&lt;&gt;与倾斜和计数相关联的类型,如:

class SlopeCount
{
    public int Slope { get; set; }
    public int Count { get; set; }
}

然后:

var slopeCounts = new List<SlopeCount>();

// fill the list

答案 5 :(得分:0)

为什么不Dictionary<double, double> key为斜率而value为何?

嗯,双倍?现在我需要一杯咖啡......