我有一个数组:
$myArray=array(
'hello my name is richard',
'hello my name is paul',
'hello my name is simon',
'hello it doesn\'t matter what my name is'
);
我需要找到最常重复的子字符串(最少2个字),也许是数组格式,所以我的返回数组看起来像这样:
$return=array(
array('hello my', 3),
array('hello my name', 3),
array('hello my name is', 3),
array('my name', 4),
array('my name is', 4),
array('name is', 4),
);
所以我可以从这个数组中看到每个字符串在数组中所有字符串中重复的频率。
是这样做的唯一方法吗?..
function repeatedSubStrings($array){
foreach($array as $string){
$phrases=//Split each string into maximum number of sub strings
foreach($phrases as $phrase){
//Then count the $phrases that are in the strings
}
}
}
我尝试过类似上面的解决方案,但速度太慢,每秒处理大约1000行,有人能更快地完成吗?
答案 0 :(得分:4)
对此的解决方案可能是
function getHighestRecurrence($strs){
/*Storage for individual words*/
$words = Array();
/*Process multiple strings*/
if(is_array($strs))
foreach($strs as $str)
$words = array_merge($words, explode(" ", $str));
/*Prepare single string*/
else
$words = explode(" ",$strs);
/*Array for word counters*/
$index = Array();
/*Aggregate word counters*/
foreach($words as $word)
/*Increment count or create if it doesn't exist*/
(isset($index[$word]))? $index[$word]++ : $index[$word] = 1;
/*Sort array hy highest value and */
arsort($index);
/*Return the word*/
return key($index);
}
答案 1 :(得分:1)
我假设“substring”你的意思是“子字符串沿着字界划分”,因为这就是你的例子所示。
在这种情况下,假设任何最大重复子字符串都会这样做(因为可能存在联系),如果你考虑它,你总是可以只选择一个单词作为最大重复子字符串。对于任何短语“A B”,短语“A”和“B”必须至少与“A B”一样频繁出现,因为它们都在“A B”每次出现时发生,并且它们可能在其他时间出现。因此,单个单词必须具有至少与包含该单词的任何子字符串绑定的计数。
所以你只需要将所有短语分成一组独特的单词,然后只计算单词并返回一个具有最高计数的单词。这将比实际计算每个可能的子字符串更快运行。
答案 2 :(得分:1)
虽然这有更高的运行时间,但我认为从实现的角度来看它更简单:
$substrings = array();
foreach ($myArray as $str)
{
$subArr = explode(" ", $str);
for ($i=0;$i<count($subArr);$i++)
{
$substring = "";
for ($j=$i;$j<count($subArr);$j++)
{
if ($i==0 && ($j==count($subArr)-1))
break;
$substring = trim($substring . " " . $subArr[$j]);
if (str_word_count($substring, 0) > 1)
{
if (array_key_exists($substring, $substrings))
$substrings[$substring]++;
else
$substrings[$substring] = 1;
}
}
}
}
arsort($substrings);
print_r($substrings);
答案 3 :(得分:0)
这应该在O(n)时间内运行
$twoWordPhrases = function($str) {
$words = preg_split('#\s+#', $str, -1, PREG_SPLIT_NO_EMPTY);
$phrases = array();
foreach (range(0, count($words) - 2) as $offset) {
$phrases[] = array_slice($words, $offset, 2);
}
return $phrases;
};
$frequencies = array();
foreach ($myArray as $str) {
$phrases = $twoWordPhrases($str);
foreach ($phrases as $phrase) {
$key = join('/', $phrase);
if (!isset($frequencies[$key])) {
$frequencies[$key] = 0;
}
$frequencies[$key]++;
}
}
print_r($frequencies);