数据文件数据存放格式转换实现

来源:互联网 发布:js的 math.hypot方法 编辑:程序博客网 时间:2024/06/05 04:41
      现有一个大数据文件,大概5个G左右,这个文件每一行包括三个字段(整数),是三元组<subject, predicate, object>。inttriple.txt中行的个数就是图中边的个数,最后一个subject或者object的序号就是图中节点的个数。现在需要做的是将这个大文件转化为metis需要的输入,并且运行metis。三元组中subject和object都是图的节点,predicate作为边的权重。我用inttriple.txt的前10行举个例子:
>>
>>1       100     2
>>1       100     3
>>1       100     4
>>5       100     6
>>5       100     7
>>5       100     8
>>9       100     10
>>9       100     11
>>9       100     12
>>9       100     13
>>
>>上面的这个表,需要生成的是
>>
>>13 10 001
>>2 100 3 100 4 100
>>1 100
>>1 100
>>1 100
>>6 100 7 100 8 100
>>5 100
>>5 100
>>5 100
>>10 100 11 100 12 100 13 100
>>9 100
>>9 100
>>9 100
>>9 100
>>

>>其中第一行分别表示 节点数,边数,format,下面的第i行表示第i-1个节点的邻居以及边上的权重

运行环境:centos

基本思路:

用C语言开了一个70000000的大数组list[],inttriple.txt里面每个节点的序号对应数组的一个下标,然后再依次扫描inttriple.txt里面每一行,每一行的两个节点的相应信息存放到相应下标的数组中,比如:
inttriple.txt中前两行
1       100     2
1       100     3
扫描第一行,会在list[1]中存放2   100,在list[2]中存放1   100。
扫描第二行,会在list[1]中追加存放3   100,在list[3]中存放 1    100。
 
最后再按序号直接输出要求的那种格式

代码如下:

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


int main()
{
    int i, total_lines = 0, ic1, ic3;
    char buf[30], *col1, *col2, *col3;
    char *temp;
    char **list = (char **)malloc(sizeof(char *)*70000000);
    int *offset = (int *) malloc(sizeof(int) * 70000000);
    int *size= (int *) malloc(sizeof(int) * 70000000);
    if(list == NULL)
    {
        printf("malloc failed\n");
        return 0;
    }//首先开一个70000000的大数组,用来存放每个节点对应的节点和边权值


    printf("ok\n");
    FILE *in = NULL;
    if((in=fopen("./inttriple.txt", "rb")) == NULL)
    {
        printf("open failed\n");
    }//打开原始数据文件
    memset(buf, 0, sizeof(buf));
    while(fgets(buf, 30, in))//每次读一行到buf里面,一行一行处理
    {
        total_lines++;


        col1 = strtok(buf, "\t");
        col2 = strtok(NULL, "\t");
        col3 = strtok(NULL, "\t\n");
        ic1 = atoi(col1);
        ic3 = atoi(col3);//将buf存放内容分割为一个一个单独字符串,然后转换为整型
        /*if(ic1 == 65583626)
        {
            printf("here\n");
        }*/
        if(list[ic1] == NULL)
        {
            list[ic1] = (char *) malloc(sizeof(char) * 20);
            if(list[ic1] == NULL)
            {
                printf("malloc failed again\n");
                break;
            }
            offset[ic1] = 0;
            size[ic1] = 20;
        }//第一次往list写数据时,先分配空间
        offset[ic1] += sprintf(list[ic1] + offset[ic1], "%s\t%s\t", col3, col2);
        temp = NULL;
        if(offset[ic1] + 20 > size[ic1])
        {
            temp = (char *) realloc(list[ic1],size[ic1] + sizeof(char) * 20);
            if(temp == NULL)

{
                printf("realloc failed\n");
                free(list[ic1]);
                break;
            }
            list[ic1] = temp;
            size[ic1] += 20;
        }//动态自动分配空间
        list[ic1][offset[ic1]] = '\0';



/*以下是处理第三个整数对应的list中存的节点和边权值,实现原理同上*/
        if(list[ic3] == NULL)
        {
            list[ic3] = (char *) malloc(sizeof(char) * 20);
            if(list[ic3] == NULL)
            {
                printf("malloc failed again\n");
                break;
            }
            offset[ic3] = 0;
            size[ic3] = 20;
        }
        offset[ic3] += sprintf(list[ic3] + offset[ic3], "%s\t%s\t", col1, col2);
        temp = NULL;


        if(offset[ic3] + 20 > size[ic3])
        {
            temp = (char *) realloc(list[ic3], size[ic3] + sizeof(char) * 20);
            if(temp == NULL)
            {
                printf("realloc failed\n");
                free(list[ic3]);
                break;
            }
            list[ic3] = temp;
            size[ic3] +=20;
        }
        list[ic3][offset[ic3]] = '\0';

/*每两百万行输出一次,观看进度*/
        if(total_lines % 2000000 == 0){
            printf("%d\n", total_lines);
        }
        memset(buf, 0, sizeof(buf));
    }
    close(in);

/*将所获得的list数组按指定格式写入新的文件中*/
    FILE *out = NULL;
    if((out=fopen("./result", "wb+")) == NULL)
    {
        printf("open failed\n");
    }
    fprintf(out,"nodes\t%d\t001\n" , total_lines);


    for(i = 1; i < 70000000; ++i)

    {
        if(list[i] != NULL)
        {
            fwrite(list[i], strlen(list[i]), 1, out);
            fwrite("\n", 1, 1, out);
        }
    }


    close(out);

/*释放List的空间*/
    for(i = 1; i < 70000000; ++i)
    {
        if(list[i] != NULL)
        {
            free(list[i]);
        }
    }
    free(list);


    return 0;
}