牛骨文教育服务平台(让学习变的简单)
博文笔记

对"对象的多个属性"进行匹配搜索"对象数组"的算法

创建时间:2015-04-25 投稿人: 浏览次数:426

假如一个对象obj有多个属性,然后这里有个数量级为千万的该对象数组,我们需要在其中搜索得到匹配相应属性值的对象数组.

/**
 * 简单的搜索引擎
 * @param $obj:obj数组
 *        $find:搜索字段,e.g."玩具 白 男 "
 * @return $r_obj 筛选得的新obj数组
 */
function getResultByFind($obj, $find)
{
    $r_obj = array ("objs" => array ());
    $n_objs = count ( $obj ["objs"] );

    // 使用 !== 操作符。使用 != 不能像我们期待的那样工作,
    // 假如 " " 的位置是 0。语句 (0 != false) 的结果是 false。
    // 判断搜索字段中是否包含多个关键字
    $arr_find = null;
    if (strpos ( $find, " " ) !== false)
    {
        $t_arr_find = explode ( " ", $find );
        $arr_find = array ();
        // 排除空字段
        foreach ( $t_arr_find as $t )
        {
            if ("" != $t)
            {
                $arr_find [] = $t;
            }
        }
    }
    //如果$arr_find为null,即$find只有一个关键字
    if (null == $arr_find)
    {
        for($i = 0; $i < $n_objs; $i ++)
        {
            //假如obj有两个属性值,就匹配关键字是否存在这两个属性里
            if ((strpos ( $obj ["objs"] [$i]->attribute1, $find ) !== false) || 
                (strpos ( $obj ["objs"] [$i]->attribute2, $find ) !== false))
            {
                // 存在则放进新的数组中
                $r_obj ["objs"] [] = $obj ["objs"] [$i];
            }
        }
    } 
    else
    {
    //搜索方法1,对obj数组进行多级筛选循环
        $r_obj = $obj;
        //$arr_find关键字数组
        foreach ( $arr_find as $t )
        {
            //将筛选过的obj数组进行下一级筛选
            $t_obj = $r_obj;
            $r_obj = array ("objs" => array ());
            //计算新的obj数组的长度
            $n_t_obj = count ( $t_obj ["objs"] );
            for($i = 0; $i < $n_t_obj; $i ++)
            {
                if ((strpos ( $t_obj ["objs"] [$i]->attribute1, $t ) !== false) || 
                    (strpos ( $t_obj ["objs"] [$i]->attribute2, $t ) !== false))
                {
                    // 存在则放进新的数组中
                    $r_obj ["objs"] [] = $t_obj ["objs"] [$i];
                }
            }
        }

    //方法2,在一次obj数组循环中进行关键字循环筛选
        $t_obj = $obj;
        $r_obj = array ("objs" => array ());
        $n_t_obj = count ( $t_obj ["objs"] );
        //计录关键字数组长度
        $n_t_arr_find = count ( $arr_find );
        for($i = 0; $i < $n_t_obj; $i ++)
        {
            //记录匹配到相关属性的次数
            $flag = 0;
            foreach ( $arr_find as $t )
            {
                if ((strpos ( $t_obj ["objs"] [$i]->attribute1, $t ) !== false) || 
                    (strpos ( $t_obj ["objs"] [$i]->attribute2, $t ) !== false))
                {
                    $flag += 1;
                } else
                {
                    //如果匹配不到相应属性,则跳出
                    break;
                }
            }
            //判断是否符合匹配次数
            if ($flag == $n_t_arr_find)
            { 
                // 存在则放进新的数组中
                $r_obj ["objs"] [] = $t_obj ["objs"] [$i];
            }
        }
    }
    return $r_obj;
}

测试出两个方法的效率相同。

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。