问一个排序的问题

yeakon 2013-10-21 04:09:56
有一批数据,格式如下:
1234520000XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\r\n

前十位是数字组成的数据,后面XXXXXX可以是中文或者是英文。长度为100

数据量已经按照前面十位数字的大小排序好了的,数据量大概10W这样。
然后现在要新添加一些数据进去,格式不变,同样需要排序好。

我的想法是这样的,读出前面的数字数据,按二分法,找出新添加的数据的指针位置然后将一整条数据插入在中间。
由于数据时存在文本文件里面的,现在C好像不支持在文本文件中间插入数据
想问下各位,用什么方法最好,我不想用链表的方式将所有的数据再排序一次然后写入文件了。况且是在STM32的机器上面运行的,内存也不够。

...全文
181 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
熊熊大叔 2013-10-21
  • 打赏
  • 举报
回复
也可以在内存中对索引排序, 然后从后到前遍历,计算每一条记录要向后移动多少位置
cqdjyy01234 2013-10-21
  • 打赏
  • 举报
回复
最好使用堆。如果内存不足,考虑使用内存映射文件。(记得保存行号)
cqdjyy01234 2013-10-21
  • 打赏
  • 举报
回复
将数字全部读入内存(数字,原文件中的行号),排好序,然后一个一个写入另一个文件(数字后面的数据根据行号从原文件中读取),结束之后删除原文件。应该可行吧?
赵4老师 2013-10-21
  • 打赏
  • 举报
回复
仅供参考
//输出PROG中有但LIST中没有的文本行,即集合PROG-LIST
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <search.h>
#define MAXCHARS 512
int MAXLINES=10000,MAXLINES2;
char *buf,*buf2;
char PROG[256]="PROG";//程序Program需要的文件列表
char LIST[256]="LIST";//dir /b /s生成的实际文件列表List
FILE *fp,*fl;
int i,c,n,L,hh;
int ignore_case=0;
char ln[MAXCHARS];
int icompare(const void *arg1,const void *arg2) {
   return stricmp((char *)arg1,(char *)arg2);
}
int compare(const void *arg1,const void *arg2) {
   return strcmp((char *)arg1,(char *)arg2);
}
int main(int argc,char **argv) {
    if (argc>1) strcpy(PROG,argv[1]);//命令行参数1覆盖PROG
    if (argc>2) strcpy(LIST,argv[2]);//命令行参数2覆盖LIST
    if (argc>3) ignore_case=1;//若存在命令行参数3,忽略大小写
    if ((fl=fopen(LIST,"rt"))==NULL) {
        fprintf(stderr,"Can not open %s\n",LIST);
        fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);
        return 1;
    }
    if ((fp=fopen(PROG,"rt"))==NULL) {
        fclose(fl);
        fprintf(stderr,"Can not open %s\n",PROG);
        fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);
        return 2;
    }
    buf=(char *)malloc(MAXLINES*MAXCHARS);
    if (NULL==buf) {
        fclose(fl);
        fclose(fp);
        fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);
        return 4;
    }
    n=0;
    hh=0;
    i=0;
    while (1) {
        if (fgets(ln,MAXCHARS,fl)==NULL) break;//
        hh++;
        L=strlen(ln)-1;
        if ('\n'!=ln[L]) {//超长行忽略后面内容
            fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",LIST,hh,MAXCHARS);
            while (1) {
                c=fgetc(fl);
                if ('\n'==c || EOF==c) break;//
            }
        }
        while (1) {//去掉行尾的'\n'和空格
            if ('\n'==ln[L] || ' '==ln[L]) {
                ln[L]=0;
                L--;
                if (L<0) break;//
            } else break;//
        }
        if (L>=0) {
            strcpy(buf+i,ln);i+=MAXCHARS;
            n++;
            if (n>=MAXLINES) {
                MAXLINES2=MAXLINES*2;
                if (MAXLINES2==1280000) MAXLINES2=2500000;
                buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);
                if (NULL==buf2) {
                    free(buf);
                    fclose(fl);
                    fclose(fp);
                    fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);
                    return 5;
                }
                buf=buf2;
                MAXLINES=MAXLINES2;
            }
        }
    }
    fclose(fl);
    if (ignore_case) qsort(buf,n,MAXCHARS,icompare);
    else qsort(buf,n,MAXCHARS,compare);
    hh=0;
    while (1) {
        if (fgets(ln,MAXCHARS,fp)==NULL) break;//
        hh++;
        L=strlen(ln)-1;
        if ('\n'!=ln[L]) {//超长行忽略后面内容
            fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",PROG,hh,MAXCHARS);
            while (1) {
                c=fgetc(fp);
                if ('\n'==c || EOF==c) break;//
            }
        }
        while (1) {//去掉行尾的'\n'和空格
            if ('\n'==ln[L] || ' '==ln[L]) {
                ln[L]=0;
                L--;
                if (L<0) break;//
            } else break;//
        }
        if (L>=0) {
            if (ignore_case) {
                if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);
            } else {
                if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);
            }
        }
    }
    fclose(fp);
    free(buf);
    return 0;
}
做或不做 2013-10-21
  • 打赏
  • 举报
回复
或者你换种方式 你把这个txt文件给它拆分了 你把相应1的索引放在一起 分成一个目录结构在取操作这个目录结构的文件。我感觉大公司也不会都存在1个txt10万条吧 你先对这个10万 通过2分法拆分为100个 之后分别实现这个想法行吧
yeakon 2013-10-21
  • 打赏
  • 举报
回复
引用 1 楼 u011779875 的回复:
二分法 查找快 hash法什么都快吧 你既然都读出前面的数字数据 那么就要在插入的时候 在此读取插入那行 并插入 在保存就完事了呗 始终保存 谁说C语言不能从中间插入了 fseek 这是什么 可以完成的 在优化下算法
fseek定位指针我知道,往里面写数据会把以前的数据替换掉的,可能我fopen打开文件的方式不对我用的是rb+
做或不做 2013-10-21
  • 打赏
  • 举报
回复
二分法 查找快 hash法什么都快吧 你既然都读出前面的数字数据 那么就要在插入的时候 在此读取插入那行 并插入 在保存就完事了呗 始终保存 谁说C语言不能从中间插入了 fseek 这是什么 可以完成的 在优化下算法

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧