从N个数中选取最大的前10个[C语言版]

来源:互联网 发布:橙子网络 编辑:程序博客网 时间:2024/06/06 19:39

题目:

从N个数中选取最大的前10个, 有序输出.

N最大可能达到1000亿

每个数范围是0 - 2147483647


C语言版测试结果:

输入100万条

总计[1000000]个输入
总计比较[2001654]次
总计写内存[552]次
总计耗时[0.014687s]


C语言版本解决方案

#include <stdio.h>#include <time.h>#include <stdlib.h>#include <unistd.h>#include <strings.h>/*  * author: goosman.lei * mail: lgg860911@yahoo.com.cn * blog: http://blog.csdn.net/lgg201 */#define BUFF_LEN(4096)/* #define DEBUG */#define INFOtypedef struct queue_squeue_t;struct queue_s {intdata;queue_t*next;};static void generate_test_data(long n) {longi;intr;intl;l= sizeof(int);srand(time(NULL));for ( i = 0; i < n; i ++ ) {r= rand();fprintf(stdout, "%d\n", r);write(STDERR_FILENO, &r, l);}}static int read_input(int fd, void *buff, int buff_len) {inti, ret;for ( i = 0; i < buff_len; ) {ret = read(fd, buff, BUFF_LEN);if ( -1 == ret ) {perror("read error\n");exit(0);} else if ( 0 == ret ) {break;} else {buff+= ret;i+= ret;}}return i;}static void dump_link(queue_t *q, int n) {for ( ; q != NULL; q = q->next )fprintf(n ? stderr : stdout, "%d\n", q->data);if ( n ) printf("\n");}int main(int argc, char *argv[]) {int*sbuff;inti, j, n;queue_t*rbuff, **tmp, *t;#ifdef INFOints_0, s_1, s_2;struct timevalbegin, end;#endifif ( argc < 2 ) {printf("usage: \n\t1. 生成测试数据: %s <number> /* 标准错误以二进制方式输出测试数据, 标准输出以文本方式输出测试数据用于脚本校验 */\n\t2. 执行Top 10查找: %s <exec> /* 标准输出输出前10个最大数据(倒序), 开启INFO时在标准错误输出统计信息, 开启DEBUG时在标准错误输出调试信息\n", argv[0], argv[0]);return (0);}if ( strcmp(argv[1], "exec") != 0 ) {/* 不考虑数字输入的容错了 */generate_test_data(atoi(argv[1]));return 0;}sbuff= malloc(1024 * 1024 * 4);rbuff= malloc(sizeof(queue_t) * 10);/* 缓冲区初始化 */bzero(rbuff, sizeof(queue_t) * 10);for ( i = 0; i < 9; i ++ ) {(rbuff + i)->next= (rbuff + i + 1);(rbuff + i)->data= -1;}(rbuff + 9)->data= -1;(rbuff + 9)->next= NULL;#ifdef DEBUGdump_link(rbuff, 1);#endif#ifdef INFOs_0= 0;s_1= 0;s_2= 0;gettimeofday(&begin, NULL);#endifwhile ( 0 != (n = read_input(STDIN_FILENO, sbuff, 1024 * 1024 * 4)) ) {#ifdef INFOs_0 ++;#endifj= n / 4;#ifdef INFOs_2+= j;#endiffor ( i = 0; i < j; i ++ ) {#ifdef INFOs_0 ++;#endif#ifdef DEBUGfprintf(stderr, "processing %d\n", *(sbuff + i));#endiffor ( tmp = &rbuff; *tmp != NULL && *(sbuff + i) >= (*tmp)->data; ) {tmp = &((*tmp)->next);#ifdef INFOs_0 += 2;#endif}#ifdef INFOs_0++;#endifif ( *tmp == rbuff ) {continue;}#ifdef DEBUGfprintf(stderr, "tmp %d %p, rbuff %d %p\n", (*tmp) == NULL ? -1 : (*tmp)->data, *tmp, rbuff->data, rbuff);#endifrbuff->data= *(sbuff + i);#ifdef INFOs_1++;s_0 ++;#endifif ( *tmp != rbuff->next ) {t= rbuff;rbuff= rbuff->next;t->next= NULL == *tmp ? NULL : *tmp;*tmp= t;#ifdef INFOs_1 += 4;s_0 ++;#endif}#ifdef DEBUGdump_link(rbuff, 1);#endif}}#ifdef INFOgettimeofday(&end, NULL);#endifdump_link(rbuff, 0);#ifdef INFOfprintf(stderr, "总计[%d]个输入\n总计比较[%d]次\n总计写内存[%d]次\n总计耗时[%0.6fs]\n", s_2, s_0, s_1, (end.tv_sec * 1000000 + end.tv_usec - begin.tv_sec * 1000000 - begin.tv_usec) / 1000000.0);#endifreturn 0;}


原创粉丝点击