Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 无需重复创建二维阵列的最佳方法_C_Arrays_Optimization_Bit Manipulation - Fatal编程技术网

C 无需重复创建二维阵列的最佳方法

C 无需重复创建二维阵列的最佳方法,c,arrays,optimization,bit-manipulation,C,Arrays,Optimization,Bit Manipulation,我正在尝试创建一些代码,从大约20万到100万条记录的列表中找出记录。显然,我希望这个过程尽可能快。其基本思想如下:大列表中的记录是要保存在一起的数字的组合。例如: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,400076,400097,800076,800097 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,200032,200078,500032,500078 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,300043,300083,6

我正在尝试创建一些代码,从大约20万到100万条记录的列表中找出记录。显然,我希望这个过程尽可能快。其基本思想如下:大列表中的记录是要保存在一起的数字的组合。例如:

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,400076,400097,800076,800097
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,200032,200078,500032,500078
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,300043,300083,600043,600083
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,600026,600077,900026,900077
0,0,0,0,0,0,0,0,0,0,0,0,0,0,100008,100028,400028,400056,600008,600056
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,400042,400098,500042,500098
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,86,500015,500086
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,400013,400076,800013,800076
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,700024,700083,900024,900083
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100003,100047,800003,800047
记录的最大长度为20,这就是为什么会增加0。让我们暂时不要担心这些。所以,我想“搜索”出一些记录,这样就不会出现重复。如果有一次重复,我可以丢弃那张唱片,不再进一步看它。因此,我必须编制一份如下所示的清单:

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,400076,400097,800076,800097
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,200032,200078,500032,500078
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,300043,300083,600043,600083
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,600026,600077,900026,900077
0,0,0,0,0,0,0,0,0,0,0,0,0,0,100008,100028,400028,400056,600008,600056
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,400042,400098,500042,500098
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,86,500015,500086
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,700024,700083,900024,900083
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100003,100047,800003,800047
请注意,在上面的列表中,8号记录是如何丢失的,因为数字400076已经存在于以前的记录中

我使用的代码如下所示:

void Make_List(ConfigList *pathgroups, ConfigList *configlist)
{
int i,j,k,l,flag,pg_num=0,len,p_num=0;
for(i = 0;i<configlist->num_total;i++)
{
    flag = 0;
    for(j = configlist->configsize-1;j>=0;j--)
    {   
        if(configlist->pathid[i][j])
        {
            for(k = 0;k<pg_num;k++)
            {
                for(l = pathgroups->configsize-1;l>=0;l--)
                {
                    if(pathgroups->pathid[k][l])
                    {
                        if(configlist->pathid[i][j]==pathgroups->pathid[k][l])
                        {
                            flag++;
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                if(flag)
                {
                    break;
                }
            }
        }
        else
        {
            break;
        }
        if(flag)
        {
            break;
        }
    }
    if(!flag)
    {
        len = 0;
        for(j = configlist->configsize-1;j>=0;j--)
        {
            pathgroups->pathid[pg_num][j]=configlist->pathid[i][j];
            if(configlist->pathid[i][j])
            {
                len++;
            }
        }
        pg_num++;
        p_num+=len;
        if(p_num>=totpaths)
        {
            break;
        }
    }   
}
Print_ConfigList(stderr,pathgroups);
}
void Make_列表(配置列表*路径组,配置列表*配置列表)
{
int i,j,k,l,flag,pg_num=0,len,p_num=0;
对于(i=0;总计为单位;i++)
{
flag=0;
对于(j=configlist->configsize-1;j>=0;j--)
{   
if(configlist->pathid[i][j])
{
对于(k=0;kconfigsize-1;l>=0;l--)
{
if(路径组->路径ID[k][l])
{
if(configlist->pathid[i][j]==pathgroups->pathid[k][l])
{
flag++;
打破
}
}
其他的
{
打破
}
}
国际单项体育联合会(旗)
{
打破
}
}
}
其他的
{
打破
}
国际单项体育联合会(旗)
{
打破
}
}
如果(!标志)
{
len=0;
对于(j=configlist->configsize-1;j>=0;j--)
{
pathgroups->pathid[pg_num][j]=configlist->pathid[i][j];
if(configlist->pathid[i][j])
{
len++;
}
}
pg_num++;
p_num+=len;
如果(p_num>=totpaths)
{
打破
}
}   
}
打印配置列表(stderr、路径组);
}
结构ConfigList基本上存储2D数组以及程序不同部分中使用的其他内容

num\u total
告诉我们数组中的行数,而
configsize
告诉我们数组中的列数


totpaths
是一个断点,在分配完全完成的情况下,它会提前终止循环。

检查每个元素是否对每个分析的新元素重复,计算成本为
O(N^2)
,考虑到您的大输入集,这太高了

基本上,您需要的是一个快速访问数据结构,在该结构中,您可以记录记录出现的次数或至少一个布尔标志

最简单的方法是使用一个数组,其中位置表示每个可能的值,数组值表示位置值出现的次数(或其存在的布尔值)。但是,如果数据范围太大,则可以这样做,因为用于存储阵列的内存与范围大小成比例

避免这种情况的另一种方法是使用哈希表或集合

正如您在上面的评论中所确定的,您的整数范围是
[09999999]
,因此,如果您想使用向量来跟踪每个值的存在与否,您需要大约
96 MB
将其存储在内存中

这是一个使用字节数组的示例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_IN_RANGE 99999999

int main()
{

    char * isInInput = (char*)malloc(MAX_IN_RANGE+1);
    memset(isInInput,0,MAX_IN_RANGE+1);
    size_t i;
    int inputExample[] = {1,3,5,2,1,5};


    for(i = 0; i < 6; i++)
    {
        int value = inputExample[i];
        printf("%d\n",value);
        if(!isInInput[value])
        {
            printf("Add value %d to your collection\n", value);
            isInInput[value] = 1;
        }
        else
        {
            printf("%d is repeated\n", value);
        }
    }
    free(isInInput);
}
#包括
#包括
#包括
#定义范围9999999中的最大值
int main()
{
char*isInInput=(char*)malloc(最大值在\u范围+1);
memset(isInInput,0,最大输入范围+1);
尺寸i;
int inputExample[]={1,3,5,2,1,5};
对于(i=0;i<6;i++)
{
int值=输入示例[i];
printf(“%d\n”,值);
如果(!isInInput[value])
{
printf(“将值%d添加到集合\n”,值);
isInInput[值]=1;
}
其他的
{
printf(“%d重复\n”,值);
}
}
自由(输入);
}

要使用哈希表,您可以依赖库,例如,以避免实现您自己的哈希表。

@MBaas抱歉,我应该提到。我用的是C我看到的最大数字是900083。允许的最大数字是多少?@user3386109 9999999是允许的最大数字。巴勃罗比我快。创建一个100000000字节的数组。使用
memset
将数组清除为0。在处理记录时,设置每个数字对应的字节。这样很容易检查哪些数字已经被使用。@user3386109我没有完全理解你所说的。数字不多,所以我很乐意这样做。大约有900个唯一的数字,但它们的范围从1到9000999。我不想使用哈希表,因为这会使事情复杂化,因为我不知道如何使用哈希表。我不介意一次array@AdityaSomani如果你能负担得起95-96MB的内存,你可以避免使用哈希表。问题是,为了访问O(1)中的值计数,需要将该值作为数组索引,因此需要保留100000000个数组位置(范围中的每个值对应一个)。是的,您只有900个唯一的数字,但您最初不知道它们是范围内的哪些数字。非常重要:
if(!isInInput[value])isInInput[value]=1在500K记录上使用此技术应该可以将速度提高大约一百万倍。那很好,我说:)