2011-12-20 17 views
5

alt dizeleri tekrarlanan bul dizi bu gibi görünebilir: en ı bir dizi var dizide

$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), 

); 

yüzden her dize dizideki tüm dizeleri arasında tekrarlandı ne sıklıkta diziler bu diziden görebilirsiniz.

herkes yapabilir,

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 
     } 
    } 

} 

Yukarıda benzer bir çözüm denedim ama saniyede 1000 satır etrafında, işleme çok yavaştı ..? Böyle yapmak için tek yol var mı Daha hızlı?

+0

Harita azaldığını bana hatırlatıyor. – Layke

+1

Yalnızca en sık tekrarlanan alt dizeye mi ihtiyacınız var? veya mümkün olan her türlü alt dize için sayıma ihtiyacınız var mı? Bunlar iki farklı soru. –

+0

@BenLee: Gerçekten sadece sık sık tekrarlanan alt dizgiye ihtiyacım var, ancak mümkünse hangisinin bir sonraki olduğunu bilmek istiyorum. – Drahcir

cevap

4

Buna bir çözüm olabilir

Bu O'da çalışmalıdır
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); 
} 
+0

Dizileri '$ index = array(); – netcoder

+0

Gönderiyi okuduğumda bunu kaçırdığımı fark ettim, teşekkürler. – CBusBus

+1

yorumlarla yalnızca çözüm +1 – PiTheNumber

1

"Altyazı" tarafından varsayıldığımı farz edersem, gerçekten de "sözcük sınırları boyunca bölünmüş alt tabaka" anlamına gelir. Bunu düşünmek if (bağları olabileceğinden) yapacak herhangi azami tekrarlanan alt dizeyi varsayarak Bu durumda

, her zaman, maksimum tekrarlanan alt dize olarak sadece tek bir kelime seçebilirsiniz. Herhangi bir "A B" ifadesi için, "A" ve "B" ibareleri, en azından "A B" kadar sık ​​olarak meydana gelmelidir, çünkü her ikisi de "A B" nin her defasında meydana gelir ve diğer zamanlarda ortaya çıkabilir. Bu nedenle, tek bir sözcüğün, en azından bu sözcüğü içeren herhangi bir alt dizeyle bağlanan bir sayımı olması gerekir.

Yani sadece eşsiz kelime grubunun içine tüm ifadeler bölmek gerekir ve daha sonra sadece kelime saymak ve en yüksek sayısı ile kelimelerinden birini döndürür. Bu, her olası alt dizgiyi gerçekten saymadan daha hızlı çalışacaktır.

+0

Cevabınız için teşekkürler, mantıklı. Bir alt dizenin minimum kelime uzunluğu 2 ise, o zaman dizeleri mümkün olan tüm 2 word minimum dizeleriyle ayırmalı mıyım? – Drahcir

+0

@RichardLivingston, evet Bu karşılaştırmayı kullanmak için 2 kelimelik tüm dizelere bölünmeniz gerektiğini düşünüyorum. Bunun için kolay bir yol düşünemiyorum. –

+0

@richard, neden "minimum" demeye devam ediyorsun?En iyi 3 kelime öbeğinin en iyi 2 kelime öbeğinden daha sık meydana geleceği bir zaman asla yoktur ve nedenini açıkladı. – goat

0

(n) zamanında

$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); 
0

bu daha yüksek bir çalışma zamanını sahip olsa da, bunun bir uygulama perspektifinden daha basit olduğunu düşünüyorum:

$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);