2015-07-22 83 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 
) 

燦爛。

相關問題