有两个有上百万数据的数组,要取到两个数组之间相似的数据,要怎么取才能取得出来,我生成新的数组和文件,用dos执行php也取不出来,因为有嵌套循环,效率就低。
我试了,如果数据量不怎么大的话,可以取出来生成,完全是我想要的结果,没问题。但是数据量达到200万的时候,即每个数组都有100万数据,dos执行的窗口就一直那样,没反应,也没生成新的文件,4核的cpu用了27%,内存一直在长,直到我关闭dos窗口,cpu和内存才缓过来。
有办法不用嵌套循环吗,就用一个循环搞定的话,估计是可以的,因为嵌套循环的话,100万乘以100万,要执行一亿次啊,但是将两个数组合并到一个数组里面的话,也还是不能用一个循环完成啊。
因为,比如:$arr1 = array(1,2,,3,4,5,6,7,8,9)  和$arr2 = array(a,b,c,d,e,f,g,h,i)$arr1中的每一个值都要和$arr2中的每一个值比较,判断相似度,一个循环不行的,哎!我测试了,几千上十万数据处理的时候还是没问题的。
下面是我的部分代码:
$count_arr1 = count($arr1);
$count_arr2 = count($arr2);
$new_arr = array();
for($i=0 ; $i < $count_arr1 ;$i++){
for($j=$i ; $j<$count_arr2 ; $j++){
similar_text($arr1[$i] , $arr2[$j][1] , $percent) ;
if( $percent > 70) {
if(!in_array($arr1[$i] ,$new_arr)){
$new_arr[] = $arr1[$i] ;
}
if(!array_multi_search($arr2[$i][1], $new_arr)){
$new_arr[] = $arr2[$i];
}
}

}
}
数据不怎么多的时候,还挺快的。帮忙啊,高手们。

解决方案 »

  1.   

    就是两个数组
    $arr1 = array(1,2,,3,4,5,6,7,8,9) 和$arr2 = array(a,b,c,d,e,f,g,h,i)$arr1中的每一个值都要和$arr2中的每一个值比较,判断相似度similar_text的函数
    similar_text($arr1[$i] , $arr2[$j][1] , $percent) ;
    $percent高于70就算相似的。
    合并不行,还是一样,因为是要取出相似的。
      

  2.   

    其实就相当于取交集:array_intersect — 计算数组的交集说明
    array array_intersect ( array $array1 , array $array2 [, array $ ... ] )
    array_intersect() 返回一个数组,该数组包含了所有在 array1 中也同时出现在所有其它参数数组中的值。注意键名保留不变。 
    Example #1 array_intersect() 例子<?php
    $array1 = array("a" => "green", "red", "blue");
    $array2 = array("b" => "green", "yellow", "red");
    $result = array_intersect($array1, $array2);
    ?> 
    这使得 $result 成为: Array
    (
        [a] => green
        [0] => red
    )Note: 两个单元仅在 (string) $elem1 === (string) $elem2 时被认为是相同的。也就是说,当字符串的表达是一样的时候。 
      

  3.   

    不是取得相同的数据啊   取得相同的很容易  是取得相似的  根据相似度判断是否相似  similar_text($arr1[$i] , $arr2[$j][1] , $percent) ;
    $percent高于70就算相似的。
      

  4.   

    给个建议,不知道全文检索能不能满足要求
    MATCH (
    col
    )
    AGAINST (
    'string'
    )
    你可以试试,不过要检索的数组如果太大,估计也有很多问题。
      

  5.   


    $arr1=
    Array
    (
      0 => Array("ADV_SITE" => "http://hao.360.cn","COUNT_NUM" => "1224"),
      1 => Array("ADV_SITE" => "http://news.baidu.com","COUNT_NUM" => "24"),
      2 => Array("ADV_SITE" => "http://www.test.com","COUNT_NUM" => "9"),
      3 => Array("ADV_SITE" => "http://www.sys.net","COUNT_NUM" => "100")
    ) ; 
    $arr2=Array
    (
      0 => Array("ADV_SITE" => "http://www.baidu.com", "COUNT_NUM" => "6168"),
      1 => Array("ADV_SITE" => "http://www.test.com","COUNT_NUM" => "1923"),
      2 => Array("ADV_SITE" => "http://www.google.com","COUNT_NUM" => "137")
    );
    echo "<pre/>";$i=0;$num1=0;
    $num1=count($arr1)>count($arr2)?count($arr1):count($arr2);
    while($i<$num1)
    {
        if($arr1[$i]['ADV_SITE'])
        {
            $n[$arr1[$i]['ADV_SITE']]=$arr1[$i]['COUNT_NUM'];
        }
        if($arr2[$i]['ADV_SITE'])
        {
            $n1[$arr2[$i]['ADV_SITE']]=$arr2[$i]['COUNT_NUM'];
        }
        $i++;
    }$rst = array_merge($n,$n1);
    foreach($rst as $rkey=>$rval){
        $vaule1 = empty($n[$rkey])? "0" : $n[$rkey];
        $vaule2 = empty($n1[$rkey])? "0" : $n1[$rkey];
        echo $rkey."      ".$vaule1."      ".$vaule2."<br/>";
    }
      

  6.   

    取交集,计算交集count,然后除以基准数组的count至于时间吗?没有更好算法前,只能如此了
      

  7.   

    如果你用 array_uintersect 函数,可能效果会好些没有可供测试的数据,无法写出可用的代码
      

  8.   

    O(N*M) 算法,貌似没法减少循环次数了。。
    不过你那个in_array可以不用,直接构建hash
    $new_arr[$arr1[$i]] = $arr1[$i] ; 
    不用每次判断if(!in_array(...))
      

  9.   

    回14楼 function get_result($v1,$v2){
    similar_text($v1 , $v2 , $percent) ;
    if ($percent > 70 && $percent <100){
    return 0;
    }
    return 1;
    }
    $a1=array("a"=>"Cat12","b"=>"Dog","c"=>"Horse");
    $a2=array(1=>"Cat",2=>"Dog25",3=>"Fish");
    print_r(array_uintersect($a1,$a2,"get_result"));
    理想中的结果应该是 "a"=>"Cat12" "b"=>"Dog" 1=>"Cat" 2=>"Dog25"
    这些应该是相似的结果  但是 这个的执行结果是
    Array ( [a] => Cat12 [b] => Dog )  就是只保留了 arr1 中的数据   ,有办法保留arr2中的数据吗 
    额  效率还是很低   
      

  10.   


    题目没看。。array_intersect_uassoc在回调函数里比较相似度http://www.w3school.com.cn/php/func_array_intersect_uassoc.asp
      

  11.   

    array_intersect_uassoc
    array_uintersect  都只能保留返回第一个数组中的数据啊    有办法也保留返回其他数组中的数据吗   
    高手们
      

  12.   

    楼主你的意思是想取得两个数组的交集吧?
         $arr_1 = array();
         $arr_2 = array();
         $res = array();
         array_push($arr_1,$arr_2);
         @reset($arr_1);
         for($i=0;$i<count($arr_1);$i++){
            $res[] = key($arr_1); 
            next($arr_1);
         }由于随手写的所以还没验证~