从N个数中选取最大的前10个[php版]

原创
2016-06-13 10:53:58 1066浏览

题目:

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

N最大可能达到1000亿

每个数范围是0 - 2147483647

author: goosman.lei

mail: lgg860911@yahoo.com.cn

blog: http://blog.csdn.net/lgg201

php版测试结果:

输入100万条

总计[1000000]个输入

总计比较[2001653]次

总计写内存[552]次

总计耗时[1.742764s]

php版解决方案:

[php]

define('DEBUG', FALSE);

define('INFO', TRUE);

$stderr = fopen('php://stderr', 'w+');

$stdout = fopen('php://stdout', 'w+');

$stdin = fopen('php://stdin', 'r+');

class PQueue {

public $data;

public $next = NULL;

public function __construct($data) {

$this->data = $data;

}

public static function factory($data, $n) {

$i = -1;

$head = NULL;

$prev = NULL;

while ( ++ $i

$node = new PQueue($data);

if ( is_null($head) )

$head = $node;

if ( !is_null($prev) )

$prev->next = $node;

$prev = $node;

}

return $head;

}

public static function dump($node, $n) {

global $stderr, $stdout;

while ( !is_null($node) ) {

fprintf($n ? $stderr : $stdout, "%d\n", $node->data);

$node = $node->next;

}

if ( $n ) fprintf($n ? $stderr : $stdout, "\n");

}

}

function generate_test_data($n) {

global $stderr, $stdout;

srand(time());

for ( $i = 0; $i

$r = rand(0, 2147483647);

fprintf($stdout, "%d\n", $r);

fprintf($stderr, "%s", pack('l', $r));

}

}

function main($argc, $argv) {

global $stderr, $stdout, $stdin;

if ( $argc

printf("usage: \n\t1. 生成测试数据: %s /* 标准错误以二进制方式输出测试数据, 标准输出以文本方式输出测试数据用于脚本校验 */\n\t2. 执行Top 10查找: %s /* 标准输出输出前10个最大数据(倒序), 开启INFO时在标准错误输出统计信息, 开启DEBUG时在标准错误输出调试信息\n",

$argv[0], $argv[0]);

exit(0);

}

if ( strcmp($argv[1], "exec") != 0 ) {

/* 不考虑数字输入的容错了 */

generate_test_data($argv[1]);

exit(0);

}

$sbuff = NULL;

$rbuff = PQueue::factory(-1, 10);

if ( DEBUG ) {

PQueue::dump($rbuff, 1);

}

if ( INFO ) {

$s_0 = 0;

$s_1 = 0;

$s_2 = 0;

$begin = microtime(TRUE);

}

while ( FALSE != ($sbuff = fread($stdin, 1024 * 1024 * 4)) ) {

$sbuff = unpack('l*', $sbuff);

if ( INFO ) {

$s_2 += count($sbuff);

}

foreach ( $sbuff as $d ) {

if ( INFO ) {

$s_0 ++;

}

if ( DEBUG )

fprintf($stderr, "processing %d\n", $d);

$tmp = &$rbuff;

while ( $tmp != NULL && $d >= $tmp->data ) {

$tmp = &$tmp->next;

if ( INFO ) {

$s_0 += 2;

}

}

if ( INFO ) {

$s_0 ++;

}

if ( $tmp === $rbuff )

continue;

if ( DEBUG )

fprintf($stderr, "tmp %d, rbuff %d\n", is_null($tmp) ? -1 : $tmp->data, $rbuff->data);

if ( INFO ) {

$s_0 ++;

$s_1 ++;

}

$rbuff->data = $d;

if ( $tmp != $rbuff->next ) {

$t = $rbuff;

$rbuff = $rbuff->next;

$t->next = is_null($tmp) ? NULL : $tmp;

$tmp = $t;

if ( INFO ) {

$s_1 += 4;

$s_0 ++;

}

}

}

if ( DEBUG )

PQueue::dump($rbuff, 1);

}

if ( INFO ) {

$end = microtime(TRUE);

}

PQueue::dump($rbuff, 0);

if ( INFO ) {

fprintf($stderr, "总计[%d]个输入\n总计比较[%d]次\n总计写内存[%d]次\n总计耗时[%0.6fs]\n",

$s_2, $s_0, $s_1, $end - $begin);

}

}

main($argc, $argv);

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。