Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>** <strong>EDIT</strong> ** : slightly better implementation, now also returns frequences and has a better sequence filter.</p> <pre><code>function getFrequences($input, $minimalSequenceSize = 2) { $sequences = array(); $frequences = array(); $len = count($input); for ($i=0; $i&lt;$len; $i++) { $offset = $i; for ($j=$i+$minimalSequenceSize; $j&lt;$len; $j++) { if ($input[$offset] == $input[$j]) { $sequenceSize = 1; $sequence = array($input[$offset]); while (($offset + $sequenceSize &lt; $j) &amp;&amp; ($input[$offset+$sequenceSize] == $input[$j+$sequenceSize])) { if (false !== ($seqIndex = array_search($sequence, $frequences))) { // we already have this sequence, since we found a bigger one, remove the old one array_splice($sequences, $seqIndex, 1); array_splice($frequences, $seqIndex, 1); } $sequence[] = $input[$offset+$sequenceSize]; $sequenceSize++; } if ($sequenceSize &gt;= $minimalSequenceSize) { if (false !== ($seqIndex = array_search($sequence, $sequences))) { $frequences[$seqIndex]++; } else { $sequences[] = $sequence; $frequences[] = 2; // we have two occurances already } // $i += $sequenceSize; // move $i so we don't reuse the same sub-sequence break; } } } } // remove sequences that are sub-sequence of another frequence // ** comment this to keep all sequences regardless ** $len = count($sequences); for ($i=0; $i&lt;$len; $i++) { $freq_i = $sequences[$i]; for ($j=$i+1; $j&lt;$len; $j++) { $freq_j = $sequences[$j]; $freq_inter = array_intersect($freq_i, $freq_j); if (count($freq_inter) != 0) { $len--; if (count($freq_i) &gt; count($freq_j)) { array_splice($sequences, $j, 1); array_splice($frequences, $j, 1); $j--; } else { array_splice($sequences, $i, 1); array_splice($frequences, $i, 1); $i--; break; } } } } return array($sequences, $frequences); }; </code></pre> <p>Test case</p> <pre><code>header('Content-type: text/plain'); $input = array(3, 5, 1, 3, 5, 48, 4, 7, 13, 55, 3, 5, 65, 4, 7, 13, 32, 5, 48, 4, 7, 13); list($sequences, $frequences) = getFrequences($input); foreach ($sequences as $i =&gt; $s) { echo "(" . implode(',', $s) . ') f=' . $frequences[$i] . "\n"; } </code></pre> <p>** <strong>EDIT</strong> ** : here's an update to the function. It was almost completely rewritten... tell me if this is what you were looking for. I also added a redundancy check to prevent counting the same sequence, or subsequence, twice.</p> <pre><code>function getFrequences2($input, $minSequenceSize = 2) { $sequences = array(); $last_offset = 0; $last_offset_len = 0; $len = count($input); for ($i=0; $i&lt;$len; $i++) { for ($j=$i+$minSequenceSize; $j&lt;$len; $j++) { if ($input[$i] == $input[$j]) { $offset = 1; $sub = array($input[$i]); while ($i + $offset &lt; $j &amp;&amp; $j + $offset &lt; $len) { if ($input[$i + $offset] == $input[$j + $offset]) { array_push($sub, $input[$i + $offset]); } else { break; } $offset++; } $sub_len = count($sub); if ($sub_len &gt;= $minSequenceSize) { // $sub must contain more elements than the last sequence found // otherwise we will count the same sequence twice if ($last_offset + $last_offset_len &gt;= $i + $sub_len) { // we already saw this sequence... ignore continue; } else { // save offset and sub_len for future check $last_offset = $i; $last_offset_len = $sub_len; } foreach ($sequences as &amp; $sequence) { $sequence_len = count($sequence['values']); if ($sequence_len == $sub_len &amp;&amp; $sequence['values'] == $sub) { //echo "Found add-full ".var_export($sub, true)." at $i and $j...\n"; $sequence['frequence']++; break 2; } else { if ($sequence_len &gt; $sub_len) { $end = $sequence_len - $sub_len; $values = $sequence['values']; $slice_len = $sub_len; $test = $sub; } else { $end = $sub_len - $sequence_len; $values = $sub; $slice_len = $sequence_len; $test = $sequence['values']; } for ($k=0; $k&lt;=$end; $k++) { if (array_slice($values, $k, $slice_len) == $test) { //echo "Found add-part ".implode(',',$sub)." which is part of ".implode(',',$values)." at $i and $j...\n"; $sequence['values'] = $values; $sequence['frequence']++; break 3; } } } } //echo "Found new ".implode(',',$sub)." at $i and $j...\n"; array_push($sequences, array('values' =&gt; $sub, 'frequence' =&gt; 2)); break; } } } } return $sequences; }; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload