一个大文件查找缺失用户ID问题
问题描述:
有一堆文件,都是一堆ID,以前有些号码跳过了,没有使用,现在要挑出没有使用过的号码,ID大概有8亿多个,10亿开始,到21亿结尾。 从数据库读出数据存储时已按哈稀规则(id%257)存文件,每个文件大概有300万个。
很庆幸,21亿左右是32位机能处理的最大值。所以下面就径直使用mod和/了。如果超过32位,PHP还提供了BC Math系统函数,可以对任意长度数字的做四则运算。
string bcmod ( string $left_operand , string $modulus )
echo bcmod('4', '2'); // 0
echo bcmod('2', '4'); // 2
最后看这个问题解决的代码:
<?php
$mod = 0; //模:脚本中唯一变化参数
$array = array(); //实始化数组
//所有ID的最大值和最小值
$max_num = 2100000000;
$min_num = 1000000000;
$idea_max = $max_num;//初始化理想最大值
$idea_min = $min_num;//初始化理想最小值
//获取实际最大值
for ($i = $max_num; $i > $max_num-257; --$i) {
if($mod == $i % 257)
$idea_max = $i;
}
//获取实际最小值
for ($i = $min_num; $i < $min_num+257; ++$i) {
if($mod == $i % 257)
$idea_min = $i;
}
//打开文件,逐行读取
$handle = fopen("./auth".$mod.".txt", "r");
if ($handle) {
$curr = $idea_min;//当前值设为理想最小值
while (!feof($handle)) {
//逐行读取
$next = (int) fgets($handle, 4096);
if($next < $min_num || $next < $idea_min) {
//如果ID不在要求范围内,不做任何操作
;
} else if ($next >= $idea_min && $next <= $idea_max) {
//如果ID符合要求,继续循环判断:如果$next值大于$curr值
while($next > $curr) {
$array[] = $curr;
$curr = $curr+257;
}
$curr = $next;
} else {
//其他情况一律不考虑
;
}
}
fclose($handle);
}
write_num($array);
function write_num ($uid){
global $mod;
$fp = fopen('c'.$mod.'.txt','a');
foreach($uid as $values) {
fwrite($fp, $values."\r\n");
}
fclose($fp);
}