C-过滤整数数组的最有效方法
我已经在C语言中成功地实现了Eratosthenes对素数的筛选(我知道有更快的方法来查找素数,这只是一个学习练习),但是我还没有找到一种令人满意的方法来过滤返回的素数数组中的零。举例说明,当run my程序返回以下内容时: 美元/元 输入搜索限制>100 0 0 2 3 0 5 0 7 0 0 0 0 11 0 13 0 0 0 17 0 19 0 0 0 0 0 0 23 0 0 0 0 0 0 0 0 0 29 0 31 0 0 0 0 0 0 0 0 0 0 0 0 0 37 0 0 0 0 0 41 0 0 0 0 43 0 0 0 0 0 0 47 0 0 0 0 0 0 0 0 0 0 0 0 53 0 0 0 0 0 0 0 0 0 0 0 0 0 0 59 0 0 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 $ 我需要一些过滤零点的方法。我假设有一种算法比仅仅在返回数组上迭代并在打印答案之前将非零元素复制到第二个数组更有效,但我自己还没有找到一个或想出一个算法。顺便说一下,整数数组在堆上是malloc'd 这是密码 编辑:最后一段代码,粘贴时实现了zero_filter()方法。 Edit2:完全忘记了筛子只需要搜索到sqrt(n)。。。在下面的代码中修复C-过滤整数数组的最有效方法,c,arrays,C,Arrays,我已经在C语言中成功地实现了Eratosthenes对素数的筛选(我知道有更快的方法来查找素数,这只是一个学习练习),但是我还没有找到一种令人满意的方法来过滤返回的素数数组中的零。举例说明,当run my程序返回以下内容时: 美元/元 输入搜索限制>100 0 0 2 3 0 5 0 7 0 0 0 0 11 0 13 0 0 0 17 0 19 0 0 0 0 0 0 23 0 0 0 0 0 0 0 0 0 29 0 31 0 0 0 0 0 0 0 0 0 0 0 0 0 37 0 0 0
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "dbg.h"
void init_array(int sieve[], int size) {
int i;
for(i = 0; i < size; i++) {
sieve[i] = i;
}
sieve[1] = 0;
}
int prime_filter(int sieve[], int size, int root) {
int i, j;
int zero_count = 2;
for(i = 2; i < root; i++) {
if(sieve[i] != 0) {
for(j = 2 * i; j < size; j += i) {
if(sieve[j] != 0) {
sieve[j] = 0;
zero_count++;
}
}
}
}
return zero_count;
}
void zero_filter(int sieve[], int final_array[], int size) {
int i;
int j = 0;
for(i = 0; i < size; i++) {
if(sieve[i] != 0) {
final_array[j] = sieve[i];
j++;
}
}
}
void print_array(int final_array[], int size) {
int i;
for(i = 0; i < size; i++) {
printf("%d ", final_array[i]);
}
}
void destroy_arrays(int *sieve, int *final_array) {
if(sieve) {
free(sieve);
}
if(final_array){
free(final_array);
}
}
int main(int argc, char *argv[]) {
check(argc == 1, "No input required");
int size, root, rv; // upper limit on search, return value
printf("Input search limit > ");
rv = scanf("%d", &size);
check(rv != EOF, "Input error on scanf().");
check(rv != 0, "Input error, expected integer");
root = (int) sqrt(size) + 1;
int *sieve, *final_array;
int zero_count, new_size;
sieve = malloc(sizeof(int) * size);
check(sieve != NULL, "Memory allocation error");
init_array(sieve, size);
zero_count = prime_filter(sieve, size, root);
new_size = size - zero_count;
final_array = malloc(sizeof(int) * (new_size));
check(final_array != NULL, "Memory allocation error");
zero_filter(sieve, final_array, size);
print_array(final_array, new_size);
destroy_arrays(sieve, final_array);
printf("\n");
return 0;
error:
return -1;
}
#包括
#包括
#包括
#包括
#包括“dbg.h”
void init_数组(int sieve[],int size){
int i;
对于(i=0;i”);
rv=扫描频率(“%d”和尺寸);
检查(rv!=EOF,“scanf()上的输入错误”);
检查(rv!=0,“输入错误,预期整数”);
根=(int)sqrt(size)+1;
int*sieve,*最终_数组;
int零_计数,新_大小;
筛=malloc(sizeof(int)*尺寸);
检查(sieve!=NULL,“内存分配错误”);
初始数组(筛,大小);
零计数=基本过滤器(筛、尺寸、根);
新大小=大小-零计数;
最终_数组=malloc(sizeof(int)*(新_大小));
检查(final_array!=NULL,“内存分配错误”);
零_过滤器(筛、最终_阵列、尺寸);
打印_数组(最终_数组,新_大小);
销毁_阵列(筛、最终_阵列);
printf(“\n”);
返回0;
错误:
返回-1;
}
<代码> > p>我认为你需要函数如<代码>:在C++中删除< /COD>。它会“删除”原位的元素。看看:
如果你不熟悉C++和模板,这里采用的代码是:
int *remove(int *first, int *last, int val)
{
int *result = first;
while (first!=last) {
if (!(*first == val)) {
*result = *first;
++result;
}
++first;
}
return result;
}
您可以使用以下代码调用它:
int array[n];
int *end = remove(array, array + n, 0);
size_t not_removed_size = end - array; // values in range [array[0], ... array[not_removed_size]) are non-zeros.
我认为你需要函数如<代码> STD::在C++中删除。它会“删除”原位的元素。看看:
如果你不熟悉C++和模板,这里采用的代码是:
int *remove(int *first, int *last, int val)
{
int *result = first;
while (first!=last) {
if (!(*first == val)) {
*result = *first;
++result;
}
++first;
}
return result;
}
您可以使用以下代码调用它:
int array[n];
int *end = remove(array, array + n, 0);
size_t not_removed_size = end - array; // values in range [array[0], ... array[not_removed_size]) are non-zeros.
您可以就地变换数组以压缩前端的所有非零项。类似这样的东西,它返回找到的非零元素的数量(在我的头顶上-没有完全测试,但应该说明这个想法-特别是,size
应该被验证为正常):
int压缩(int数组[],int大小)
{int current=0,nextpos=0;
while(当前<大小)
{if(数组[当前])
{int tmp=array[nextpos];//或使用正确定义的swap()
array[nextpos]=array[current];//但这将同样快。。。
阵列[当前]=tmp;
++nextpos;
}
++电流;
}
返回nextpos;
}
您可以就地变换阵列,以压缩前端的所有非零项。类似这样的东西,它返回找到的非零元素的数量(在我的头顶上-没有完全测试,但应该说明这个想法-特别是,size
应该被验证为正常):
int压缩(int数组[],int大小)
{int current=0,nextpos=0;
while(当前<大小)
{if(数组[当前])
{int tmp=array[nextpos];//或使用正确定义的swap()
array[nextpos]=array[current];//但这将同样快。。。
阵列[当前]=tmp;
++nextpos;
}
++电流;
}
返回nextpos;
}
迭代,然后将qointer设置为第一个非零项是好的,尽管您确实不需要检查ptr!=释放前为空<代码>malloc()
对筛选进行排序也是多余的-因为你不从任何函数返回它,你应该使用一个自动数组:int sieve[size]
。哦,是的,这个程序可能会搜索100000以上。另外,malloc()将数组传递到堆并向辅助函数传递指针不是比将整个数组传递给它们更有效吗?为什么您认为过滤掉零的方法比单步遍历数组并复制掉非零的方法更快?(如果需要,您可以将非零复制到源数组的“底部”,以节省分配新数组的需要,然后realloc
完成后将数组调整为新大小。)鉴于这种结构,您的过滤速度不可能比检查每个元素更快。但您可以将过滤器和打印组合成一个单独的