2015-07-22 41 views
2

因为我不确定如何改进这一点,所以我想回顾一下这些思想过程。我有一个由逗号分隔的字符串,他们有重复出现的子字符串,我想找到3个最出现的子字符串。在PHP中查找字符串中发生的3个子字符串

  • 我打算用逗号将字符串分解为数组。
  • 在原始字符串中为数组中的每个元素执行substr_count并将其存储在单独的数组中以存储计数? (不知道如何改进这个,因为这会为同一子字符串创建重复计数)
  • 在数组上执行一个最大值来查找第一个,第二个和第三个最出现的子字符串。
  • 返回一个数组,其中第一个,第二个和第三个出现的子字符串。

我猜我执行爆炸后,我可以做一个快速排序,并从那里?

这是我到目前为止已经试过:

$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

如果你添加你已经试过的代码会更好。 – Sujay

+0

你能解释一下你对“子串”的看法吗?如果我们有一个输入字符串“cat,dog,cow”,那么字符串“t,d”就是一个子字符串。术语“猫”,“狗”和“牛”在技术上是子串,但如果这就是你的意思,那么你真正的意思是“这个字符串代表一个逗号分开的术语列表”,所以'首先爆炸()'字符串,那么谈谈数组中的单个元素? –

+0

@Mike'Pomax'Kamermans,通过子串我的意思是在字符串中被逗号分隔的字符串被传递给函数。 – imparante

回答

1

如果串你的意思是只能用逗号分隔字符串,而不是这些字符串,使用array_count_values爆炸

0

后,如果您正在寻找为了有效地解决子串搜索,答案是Trie前缀树。这基本上减少了查找子字符串的查找时间,因为它为所有前缀创建确定性路径(即前缀树)。

考虑串"A cat does not categorize its food while among other cats."这里的子categorizecats所有份额的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有子的最高号(如果走匹配catcatscategorize

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 
) 

灿烂。

相关问题