怎么匹配出字符在文章里匹配次数最高的地方啊? 本帖最后由 mithetwo 于 2012-06-19 02:55:03 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 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 次 1,扫一遍找出所有的关键字。2,再扫一遍,计算出每个end_index位置之前的关键字总数,同时计算180个字符之前的beg_index位置的关键字个数差值。3,对关键字差值最大的180长度的段,strrstr,strstr分别头尾找到一个关键字,把多余的部分切掉,这样可以让字符再少一点。 <?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个字符出现所有关键字,并且出现总次数最大。 额,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);?> 还行, 效率因为字符串匹配有下降, 整体就是就是O(n)+O(len*num),n是content长度,num是关键字个数,len是最长关键字个数。 但灵活性足够大了, 编码灵活, 关键字可以随便填,再说你用的是接口,实现可以不管。C语言出身,不太喜欢用PHP的思维思考,喜欢自己写。 [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编码? 接口给你提供encoding了,你看你数据编码是啥就啥呗。 有关SENDMAIL的配置问题!!弄了两天了!!到现在没弄好! 调用JS文件不能运行了 MYSQL的编码问题 联动问题,急 哪里有PHP的函数大全下载? 请问,怎样在PHP里面利用已经有的SESSION? 请教 关于文件打开 PHP调试失败 帮忙啊~~~~~~~~~~~~~~ Exceed PHP被PHP.net 收录。散分 求助:session时效问题 判断QQ号和手机哪种方法更好 curl模拟访问页面-像cnzz第三方统计不到?
$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,再扫一遍,计算出每个end_index位置之前的关键字总数,同时计算180个字符之前的beg_index位置的关键字个数差值。
3,对关键字差值最大的180长度的段,strrstr,strstr分别头尾找到一个关键字,把多余的部分切掉,这样可以让字符再少一点。
$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个字符出现所有关键字,并且出现总次数最大。
[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);
?>
还行, 效率因为字符串匹配有下降, 整体就是就是O(n)+O(len*num),n是content长度,num是关键字个数,len是最长关键字个数。 但灵活性足够大了, 编码灵活, 关键字可以随便填,再说你用的是接口,实现可以不管。C语言出身,不太喜欢用PHP的思维思考,喜欢自己写。
德国和丹麦都在第一场比赛1-0获胜,在次轮比赛中,德国2-1击败荷兰,两场小组赛战罢,德国队虽然拿到了6分,但依然未能保证出线,最后一场如果输给丹麦仍然有出局可能。丹麦上一场在0-2落后的情况下连追两球,但最后还是2-3输给葡萄牙,将小组次席拱手让给葡萄牙。丹麦想要出线[User:root Time:05:19:13 Path:/home/liangdong/php]$ 有的,你确定你也是utf8编码?
接口给你提供encoding了,你看你数据编码是啥就啥呗。