本帖最后由 mithetwo 于 2012-06-19 02:55:03 编辑

解决方案 »

  1.   

    for($j=0; $j<count($ar)-1; $j++) {
      $t = $ar[$j][1];
      $r[$t] = 0;
      for($i=$j; $i<count($ar); $i++) {
        if($ar[$i][0] == '德国' || $ar[$i][0] == '丹麦') {
          if($ar[$i][1]+strlen($ar[$i][0]) - $t < 180) $r[$t]++;
          else $r[$t=$ar[$i][1]] = 0;
        }
      }
    }arsort($r);
    print_r($r);Array
    (
        [0] => 6
        [6] => 5
        [157] => 5
        [4] => 5
        [137] => 5
        [249] => 5
        [253] => 4
        [332] => 4
        [141] => 4
        [471] => 4
        [389] => 4
        [299] => 4
        [273] => 4
        [47] => 4
        [10] => 4
        [161] => 4
        [80] => 4
        [336] => 3
        [303] => 3
        [500] => 3
        [277] => 3
        [475] => 3
        [51] => 3
        [876] => 3
        [84] => 3
        [393] => 3
        [880] => 2
        [504] => 2
        [964] => 2
        [586] => 2
        [701] => 2
        [516] => 2
        [914] => 2
        [1135] => 2
        [1190] => 1
        [1139] => 1
        [968] => 1
        [918] => 1
        [705] => 1
        [520] => 1
        [590] => 1
    )结果数组的含义是:键:原串的偏移 值:关键自出现的次数
    即 701 => 2 表示从第 701 开始的 180 字节中,关键字出现了 2 次
      

  2.   

    1,扫一遍找出所有的关键字。
    2,再扫一遍,计算出每个end_index位置之前的关键字总数,同时计算180个字符之前的beg_index位置的关键字个数差值。
    3,对关键字差值最大的180长度的段,strrstr,strstr分别头尾找到一个关键字,把多余的部分切掉,这样可以让字符再少一点。
      

  3.   

    <?php
    $content = <<<EOF
    德国和丹麦都在第一场比赛1-0获胜,在次轮比赛中,德国2-1击败荷兰,两场小组赛战罢,德国队虽然拿到了6分,但依然未能保证出线,最后一场如果输给丹麦仍然有出局可能。丹麦上一场在0-2落后的情况下连追两球,但最后还是2-3输给葡萄牙,将小组次席拱手让给葡萄牙。丹麦想要出线必须力争击败德国,好在他们也不缺乏击败德国的感觉。在两队最近3场交手中,丹麦令人吃惊地2胜1平占据上风,最近一次交手是在2010年8月,丹麦在落后两球情况下扳平比分。两队上一次在欧洲杯交手则是1992年欧洲杯决赛,当时正是丹麦童话的巅峰,北欧人2-0击败德国夺冠。在德国队前两场比赛中,戈麦斯成为最大的亮点。超级马里奥连续两场比赛包揽了德国3粒进球,恐怖的是他进3球居然只花了6脚射门。戈麦斯目前以3球排名射手榜首位,自从1976年欧洲杯穆勒单届射进4球以来,德国队此后36年还没有任何球员欧洲杯单届进球超过3个。左边锋波多尔斯基在此前两场小组赛均打满全场,国家队出场次数达到99场,本场有望实现百场。双方都没有对首发阵容进行大的调整,德国队只是因为博阿滕停赛而派上了本德,丹麦也只换上鲍尔森,队内元老罗梅达尔因伤缺席。本场德国前锋波多尔斯基迎来国家队第100场比赛,小将本德则是首次在国家队首发。第2分钟,赫迪拉禁区前沿左侧传中,中路无人拿到皮球,后点穆勒胸部停球后左脚抽射稍稍高出。第5分钟,丹麦左侧角球,本特纳远点头球攻门被诺伊尔拿到。1分钟后,德国迅速反击,厄齐尔左侧直塞,波多尔斯基传中,克亚尔解围不力,穆勒门前3米处射门被安德森神奇化解。第12分钟,戈麦斯禁区外围左脚远射高出。
    EOF;
    $keywords = array('德国', '丹麦');function get_summary($content, $keywords, $encoding) {
            $ndx = 0;
            $res = array();
            $end_ndx = mb_strlen($content, $encoding); // utf-8 file-encoding in my linux
            while ($ndx < $end_ndx) {
                    $is_found = 0;
                    foreach ($keywords as $keyword) {
                            $len = mb_strlen($keyword, $encoding);
                            if ($ndx + $len <= $end_ndx) {
                                    $word = mb_substr($content, $ndx, $len, $encoding);
                                    if ($word == $keyword) {
                                            $is_found = 1;
                                            break;
                                    }
                            }
                    }
                    if ($is_found) {
                            $res[$ndx + $len - 1] = array('length' => $len, 'keyword' => $word); //details
                            $ndx += $len;
                    } else {
                            $ndx += 1;
                    }
            }
            if (count($res) == 0) {
                    return false; // no keywords found at all
            }
            $ndx = 0;
            $total = 0;
            $max_times = -1;
            $max_beg = 0;
            $max_end = 0;
            $key_count = array();
            foreach ($keywords as $key) {
                    $key_count[$key] = 0;
            }
            $count[-1] = array('times' => 0, 'key_count' => $key_count);
            for ($i = 0; $i != $end_ndx; ++ $i) {
                    if (isset($res[$i])) {
                            $key_count[$res[$i]['keyword']] += 1;
                            $total += 1;
                    }
                    $count[$i] = array('times' => $total, 'key_count' => $key_count);
                    if ($i - 180 >= -1) {
                            foreach ($keywords as $word) {
                                    $cnt = $count[$i]['key_count'][$word] - $count[$i - 180 + 1]['key_count'][$word];
                                    if ($cnt == 0) {
                                            continue; // dosen't include all keywords
                                    }
                            }
                            $times = $count[$i]['times'] - $count[$i - 180]['times'];
                    } else {
                            $times = $count[$i]['times'];
                    }
                    if ($times > $max_times) {
                            $max_times = $times;
                            $max_beg = ($i - 180 + 1) < 0 ? 0 : ($i - 180 + 1);
                            $max_end = $i;
                    }
            }
            if ($max_times != -1) {
                    return mb_substr($content, $max_beg, $max_end - $max_beg + 1, $encoding);
            }
            return false;
    }$result = get_summary($content, $keywords, "utf8");
    print_r($result);
    //print_r($result);
    ?>[User:root Time:00:35:17 Path:/home/liangdong/php]$ php preg.php 
    德国和丹麦都在第一场比赛1-0获胜,在次轮比赛中,德国2-1击败荷兰,两场小组赛战罢,德国队虽然拿到了6分,但依然未能保证出线,最后一场如果输给丹麦仍然有出局可能。丹麦上一场在0-2落后的情况下连追两球,但最后还是2-3输给葡萄牙,将小组次席拱手让给葡萄牙。丹麦想要出线必须力争击败德国,好在他们也不缺乏击败德国的感觉。在两队最近3场交手中,丹麦不知道对不对啊,保证180个字符出现所有关键字,并且出现总次数最大。
      

  4.   

    额,continue用在foreach里了,误会,改了如下:[User:root Time:02:19:04 Path:/home/liangdong/php]$ php preg.php 
    [User:root Time:02:19:05 Path:/home/liangdong/php]$ cat preg.php 
    <?php
    $content = <<<EOF
    德国和丹麦都在第一场比赛1-0获胜,在次轮比赛中,德国2-1击败荷兰,两场小组赛战罢,德国队虽然拿到了6分,但依然未能保证出线,最后一场如果输给丹麦仍然有出局可能。丹麦上一场在0-2落后的情况下连追两球,但最后还是2-3输给葡萄牙,将小组次席拱手让给葡萄牙。丹麦想要出线必须力争击败德国,好在他们也不缺乏击败德国的感觉。在两队最近3场交手中,丹麦令人吃惊地2胜1平占据上风,最近一次交手是在2010年8月,丹麦在落后两球情况下扳平比分。两队上一次在欧洲杯交手则是1992年欧洲杯决赛,当时正是丹麦童话的巅峰,北欧人2-0击败德国夺冠。在德国队前两场比赛中,戈麦斯成为最大的亮点。超级马里奥连续两场比赛包揽了德国3粒进球,恐怖的是他进3球居然只花了6脚射门。戈麦斯目前以3球排名射手榜首位,自从1976年欧洲杯穆勒单届射进4球以来,德国队此后36年还没有任何球员欧洲杯单届进球超过3个。左边锋波多尔斯基在此前两场小组赛均打满全场,国家队出场次数达到99场,本场有望实现百场。双方都没有对首发阵容进行大的调整,德国队只是因为博阿滕停赛而派上了本德,丹麦也只换上鲍尔森,队内元老罗梅达尔因伤缺席。本场德国前锋波多尔斯基迎来国家队第100场比赛,小将本德则是首次在国家队首发。第2分钟,赫迪拉禁区前沿左侧传中,中路无人拿到皮球,后点穆勒胸部停球后左脚抽射稍稍高出。第5分钟,丹麦左侧角球,本特纳远点头球攻门被诺伊尔拿到。1分钟后,德国迅速反击,厄齐尔左侧直塞,波多尔斯基传中,克亚尔解围不力,穆勒门前3米处射门被安德森神奇化解。第12分钟,戈麦斯禁区外围左脚远射高出。
    EOF;
    $keywords = array('德国', '丹麦', "注定不存在的单词");function get_summary($content, $keywords, $encoding) {
            $ndx = 0;
            $res = array();
            $end_ndx = mb_strlen($content, $encoding); // utf-8 file-encoding in my linux
            while ($ndx < $end_ndx) {
                    $is_found = 0;
                    foreach ($keywords as $keyword) {
                            $len = mb_strlen($keyword, $encoding);
                            if ($ndx + $len <= $end_ndx) {
                                    $word = mb_substr($content, $ndx, $len, $encoding);
                                    if ($word == $keyword) {
                                            $is_found = 1;
                                            break;
                                    }
                            }
                    }
                    if ($is_found) {
                            $res[$ndx + $len - 1] = array('length' => $len, 'keyword' => $word); //details
                            $ndx += $len;
                    } else {
                            $ndx += 1;
                    }
            }
            if (count($res) == 0) {
                    return false; // no keywords found at all
            }
            $ndx = 0;
            $total = 0;
            $max_times = -1;
            $max_beg = 0;
            $max_end = 0;
            $key_count = array();
            foreach ($keywords as $key) {
                    $key_count[$key] = 0;
            }
            $count[-1] = array('times' => 0, 'key_count' => $key_count);
            for ($i = 0; $i != $end_ndx; ++ $i) {
                    if (isset($res[$i])) {
                            $key_count[$res[$i]['keyword']] += 1;
                            $total += 1;
                    }
                    $count[$i] = array('times' => $total, 'key_count' => $key_count);
                    if ($i - 180 >= -1) {
                            foreach ($keywords as $word) {
                                    $cnt = $count[$i]['key_count'][$word] - $count[$i - 180 + 1]['key_count'][$word];
                                    if ($cnt == 0) {
                                            break; // dosen't include all keywords
                                    }
                            }
                            if ($cnt == 0) {
                                    continue;
                            }
                            $times = $count[$i]['times'] - $count[$i - 180]['times'];
                    } else {
                            foreach ($keywords as $word) {
                                    $cnt = $count[$i]['key_count'][$word];
                                    if ($cnt == 0) {
                                            break; // same as the above
                                    }
                            }
                            if ($cnt == 0) {
                                    continue;
                            }
                            $times = $count[$i]['times'];
                    }
                    if ($times > $max_times) {
                            $max_times = $times;
                            $max_beg = ($i - 180 + 1) < 0 ? 0 : ($i - 180 + 1);
                            $max_end = $i;
                    }
            }
            if ($max_times != -1) {
                    return mb_substr($content, $max_beg, $max_end - $max_beg + 1, $encoding);
            }
            return false;
    }$result = get_summary($content, $keywords, "utf8");
    print_r($result);
    ?>
      

  5.   


    还行, 效率因为字符串匹配有下降, 整体就是就是O(n)+O(len*num),n是content长度,num是关键字个数,len是最长关键字个数。 但灵活性足够大了, 编码灵活, 关键字可以随便填,再说你用的是接口,实现可以不管。C语言出身,不太喜欢用PHP的思维思考,喜欢自己写。
      

  6.   

    [User:root Time:05:19:12 Path:/home/liangdong/php]$ php preg.php 
    德国和丹麦都在第一场比赛1-0获胜,在次轮比赛中,德国2-1击败荷兰,两场小组赛战罢,德国队虽然拿到了6分,但依然未能保证出线,最后一场如果输给丹麦仍然有出局可能。丹麦上一场在0-2落后的情况下连追两球,但最后还是2-3输给葡萄牙,将小组次席拱手让给葡萄牙。丹麦想要出线[User:root Time:05:19:13 Path:/home/liangdong/php]$ 有的,你确定你也是utf8编码?
      

  7.   


    接口给你提供encoding了,你看你数据编码是啥就啥呗。