$keyword = 'football';
usort($things, function($a, $b) use ($keyword) {
$x = strpos($a, $keyword) === false;
$y = strpos($b, $keyword) === false;
if ($x && !$y) return 1;
if ($y && !$x) return -1;
// use this if you want to sort alphabetically after the keyword sort:
return strcmp($a, $b);
// or if you only want to sort by whether or not the keyword was found:
return 0;
});
$keyword = 'football';
usort($things, function($a, $b) use ($keyword) {
// prioritize exact matches first
if ($a == $keyword) return -1;
if ($b == $keyword) return 1;
// prioritize terms containing the keyword next
$x = strpos($a, $keyword);
$y = strpos($b, $keyword);
if ($x !== false && $y === false) return -1;
if ($y !== false && $x === false) return 1;
if ($x !== false && $y !== false) { // both terms contain the keyword, so...
if ($x != $y) { // prioritize matches closer to the beginning of the term
return $x > $y ? 1 : -1;
}
// both terms contain the keyword at the same position, so...
$al = strlen($a);
$bl = strlen($b);
if ($al != $bl) { // prioritize terms with fewer characters other than the keyword
return $al > $bl ? 1 : -1;
}
// both terms contain the same number of additional characters
return 0;
// or sort alphabetically with strcmp($a, $b);
// or do additional checks...
}
// neither terms contain the keyword
// check the character similarity...
$ac = levenshtein($keyword, $a);
$bc = levenshtein($keyword, $b);
if ($ac != $bc) {
return $ac > $bc ? 1 : -1;
}
return 0;
// or sort alphabetically with strcmp($a, $b);
// or do additional checks, similar_text, etc.
});
<?php
$abc =["ball","football","volleyball","football player", "football league", "tennis"];
$word ="football";
$final = array();
// collect complete match
foreach($abc as $key=>$value){
if($value==$word){
$final[] = $value;
unset($abc[$key]);
}
}
//collect if word found in another string
foreach($abc as $key=>$value){
if(strpos($value,$word)!==false){
$final[] = $value;
unset($abc[$key]);
}
}
// collect if another string have some part of word
foreach($abc as $key=>$value){
if(strpos($word,$value)!==false){
$final[] = $value;
unset($abc[$key]);
}
}
// collect rest of the elements
$final = array_merge($final,$abc);
print_r($final);
?>
输出是
Array
(
[0] => football
[1] => football player
[2] => football league
[3] => ball
[4] => volleyball
[5] => tennis
)
//an associative array to save the scores
// $wordsMeta[$word] = array(lengthOfCommonSubstring, percentageOfWordMatched)
$wordsMeta = array();
//go through each word and assign a score
foreach($words as $word) {
$lcs = longestCommonSubstring($keyword, $word);
if (count($lcs) ==0 ) {
$wordPercentage = 0;
$wordLength = 0;
} else {
$wordLength = strlen($lcs[0]);
$wordPercentage = $wordLength/strlen($word);
}
$wordsMeta[$word] = array(
"percentageOfWordMatched" => $wordPercentage,
"lengthOfCommonSubstring" => $wordLength
);
}
现在我们只需要一个排序函数,它首先查看长度,如果它们相等,它将查看百分比并返回一个适当的整数。
//our special sorting function
//checks length, if that is equal, then it checks percentage of word matched
//if both are eqaul, then those two elements are considered equal
$sort = function($a, $b) {
$ans = $a["lengthOfCommonSubstring"] - $b["lengthOfCommonSubstring"];
if ($ans == 0) {
$ans = $a["percentageOfWordMatched"] - $b["percentageOfWordMatched"];
}
if ($ans < 0) {
$ans = -1;
} elseif ($ans > 0){
$ans = 1;
} else {
$ans = 0;
}
//higher number = lower sort order
$ans *= -1;
return $ans;
};
4条答案
按热度按时间fnvucqvd1#
您需要创建一个自定义排序函数,然后将其与
usort.
一起使用回应:
bvpmtnay2#
如果你想根据关键字是否在单词中的任何地方而不是仅仅在开头进行排序,你可以在比较函数中使用
strpos
。如果你有一个更一般的目标,根据它的术语与关键字的“接近度”对数组进行排序,比较必须变得更加复杂,并且应该采取的方式实际上取决于“接近度”的哪些方面对你来说最重要。这里有一个更复杂的排序的例子,可能不完全是你想要的,但只是为了说明我对确定“接近度”的可能复杂性的看法:
093gszye3#
我试着理解你的问题,并试着这样解决
输出是
点击这里:https://eval.in/593747
kmpatx3s4#
这是一个有趣的小问题,你需要给你的干草堆(单词数组)的每个元素分配某种分数。我认为给每个元素打分的最好方法是基于一个经典的动态编程问题“最长公共子串”。此子字符串越长,排序得分越高。
既然函数已经写好了,我们就需要使用它。
好吧,这是所有和好,但只是使用功能只是一半的战斗,现在我们需要应用一些逻辑的结果。让我们将结果保存在一个数组中,并给予每个单词一个分数。一个好的分数是最长子串的长度。
football
会比ball
更好,因为它有一个更长的共同字符串。但是football
和football player
呢,它们都有相同长度的最长公共子串?为了解决这个问题,我们可以使用长度作为总单词长度的百分比。结合这两个概念,最长子串长度和百分比,我们得到下面的代码。现在我们只需要一个排序函数,它首先查看长度,如果它们相等,它将查看百分比并返回一个适当的整数。
现在简单的部分:
uasort($wordsMeta)
和$answer= array_keys($wordsMeta)
小心恶魔-这个算法很慢。非常慢。
lcs
是O(n*m)
,我们称之为count($words)
倍。进行评分过程O(n*m*x)
,其中:n
是strlen($keyword)
m
是strlen($word)
x
是count($words)
此外,我们正在排序,即
O(n * log(n))
。因此,总的来说,这个算法是O(n*m*x + n*log(n))
,这是不好的。保持单词列表短,单词列表中的单词短,关键字短将保持速度下降。