什么是过滤数组的有效方法

时间:2012-03-07 09:14:25

标签: c linux algorithm

我在linux上编程c并且我有一个大整数数组,如何过滤它,比如找到适合某些条件的值,例如:值> 1789&&价值< 2031.有效的方法是什么,我需要先对这个数组进行排序吗?

我已经阅读了答案,谢谢大家,但我需要在这个大阵列上多次进行这样的过滤操作,而不仅仅是一次。那么每次最好的方式一个一个地迭代它吗?

6 个答案:

答案 0 :(得分:2)

如果你想要对数组做的唯一事情就是获得符合这个条件的值,那么迭代数组并检查条件的每个值会更快(O(n) vs. { {1}})。但是,如果你打算对这个数组执行多个操作,那么最好对它进行排序。

答案 1 :(得分:1)

您可以使用max heap实现为与源数组大小相同的数组。用min-1值初始化它,并在数字进入时将值插入max-heap。第一个检查是查看要插入的数字是否大于第一个元素,如果不是,则丢弃它,如果它更大,则将其插入数组中。要获取数字列表,请读取新数组中的所有数字,直到min-1

答案 2 :(得分:1)

首先对数组进行排序。然后在每个查询上进行2次二进制搜索。我假设查询会像 -

Find integers x such that a < x < b

第一个二进制搜索会找到元素的索引i,以便Array[i-1] <= a < Array[i]和第二个二进制搜索找到索引j,使得Array[j] < b <= Array[j+1]。那么你想要的范围是[i, j]

如果您想迭代所有元素并且每个查询O(NlogN),如果您只想计算过滤元素的数量,则此算法的复杂度在预处理中为O(N),在每个查询中为O(logN)

如果您需要帮助在C中实现二进制搜索,请告诉我。在C中有一个名为binary_search()的库函数,在C ++ STL中有lower_bound()upper_bound()

答案 3 :(得分:0)

要过滤数组,您必须查看每个元素一次。没有必要再查看任何元素 more 了,因此对符合条件的项目进行简单的线性数组搜索将会获得尽可能高效的效果。

对数组进行排序最终会不止一次地查看某些元素,这对您的目的来说并不是必需的。

答案 4 :(得分:0)

如果你可以节省更多内存,那么你可以扫描一次数组,得到匹配值的索引并将其存储在另一个数组中。这个新数组将明显缩短,因为它只有与特定模式匹配的值索引!像这样的东西

int original_array[SOME_SIZE];
int new_array[LESS_THAN_SOME__SIZE];

for ( int i=0,j=0; i<SOME_SIZE; i++)
{
    if ( original_array[i]> LOWER_LIMIT && original_array[i]< HIGHER_LIMIT )
    {
        new_array[j++] = i;
    }
}

您需要执行以上操作并立即开始,

for ( int i=0; i< LESS_THAN_SOME_SIZE; i++ )
{
    if ( original_array[new_array[i]]> LOWER_LIMIT && original_array[new_array[i]]< HIGHER_LIMIT )
    {
        printf("Success! Found Value %d\n", original_array[new_array[i]] )
    }
}

因此,以一些记忆为代价,您可以节省大量时间。即使您在排序上投入了一些时间,也必须每次都解析排序后的数组。这种方法最小化了数组长度以及排序时间(当然是以额外内存为代价:))

答案 5 :(得分:-1)

试试此库:http://code.google.com/p/boolinq/

它是基于迭代器的,并且尽可能快,没有任何开销。但它需要C ++ 11标准。您的代码将以声明方式编写:

int arr[] = {1,2,3,4,5,6,7,8,9};

auto items = boolinq::from(arr).where([](int a){return a>3 && a<6;});
while (!items.empty())
{
    int item = items.front();
    ...
}

比基于迭代器的扫描更快只能进行多线程扫描......