我想重温这些思维过程,因为我不知道如何改进这一点。我有一个用逗号分隔的字符串,它们有重复出现的子串,我想找到3个最常出现的子字符串。
我在进行爆炸后猜测,我可以快速排序并从那里开始?
这是我到目前为止所尝试的:
$result = findThreeMostOccuringStrings("apple, apple, berry, cherry, cherry, cherry, dog, dog, dog");
var_dump($result);
function findThreeMostOccuringStrings($str){
$first = PHP_INT_MIN;
$second = PHP_INT_MIN;
$third = PHP_INT_MIN;
$arr = explode(",", $str);
for ($i = 0; $i < count($str); $i++){
$arrIdx[] = substr_count($arr[$i]);
}
$first = max($arrIdx);
$arrIdx[$first] = -1;
$second = max($arrIdx);
$arrIdx[$first] = -1;
$third = max($arrIdx);
$arrIdx[$first] = -1;
$threeMostOccuringStrings = array($first, $second, $third);
return $threeMostOccuringStrings;
}
答案 0 :(得分:1)
如果by substring只表示用逗号分隔的字符串而不是这些字符串的子字符串,请在爆炸后使用array_count_values
答案 1 :(得分:0)
如果您正在寻找一种有效的方法来解决子字符串搜索,那么答案就是Trie或前缀树。这基本上减少了搜索子字符串的查找时间,因为它为所有前缀创建了一个确定性路径(即前缀树)。
考虑字符串"A cat does not categorize its food while among other cats."
此处,子字符串categorize
和cats
都共享cat
的相同前缀。因此,如果计算源自根中每个分支的EOW
个节点的数量,那么在前缀树中查找最常用的子字符串很容易。
构建树也很简单。
function insertString($str, $trie) {
$str = strtolower($str); // normalize case
$node = $trie;
foreach(str_split($str) as $letter) {
if (!isset($node->$letter)) {
$node->$letter = new stdClass;
}
$node = $node->$letter;
}
$node->EOW = true; // place EOL node
}
function countNodes($branch) {
$n = 0;
foreach($branch as $e => $node) {
if ($node instanceof stdClass) {
$n += countNodes($node);
} elseif ($e === 'EOW') {
$n++;
}
}
return $n;
}
$trie = new stdClass;
$str = "A cat does not categorize its food while among other cats";
foreach(explode(' ', $str) as $word) {
insertString($word, $trie);
}
$s = [];
foreach($trie as $n => $rootNodes) {
$s[$n] = countNodes($rootNodes);
}
var_dump($s);
哪个应该给你......
array(8) {
["a"]=>
int(2)
["c"]=>
int(3)
["d"]=>
int(1)
["n"]=>
int(1)
["i"]=>
int(1)
["f"]=>
int(1)
["w"]=>
int(1)
["o"]=>
int(1)
}
从那里你可以看到根分支c
具有最多的子串数(如果步行匹配cat
,cats
和categorize
。
答案 2 :(得分:0)
根据您的帖子和评论,您实际上想要在逗号分隔的术语列表中计算术语,然后对它们进行排名,所以:让我们这样做,使用关联数组进行计数和arsort到按值反向排序关联数组(以便最高计数位于数组的开头):
function rank($input) {
$terms = explode(',', $input);
$ranked = array();
foreach($terms as $word) {
$word = trim($word);
if (!isset($ranked[$word])) {
$ranked[$word] = 0;
}
$ranked[$word]++;
}
arsort($ranked);
return $ranked;
}
因此,如果我们通过print_r(rank("apple, apple, berry, cherry, cherry, cherry, dog, dog, dog"))
运行,我们会得到:
Array
(
[dog] => 3
[cherry] => 3
[apple] => 2
[berry] => 1
)
出色。