mirror of
https://github.com/danielstjules/Stringy.git
synced 2025-08-11 15:54:04 +02:00
Added longestCommonSubstring
This commit is contained in:
17
README.md
17
README.md
@@ -37,6 +37,7 @@ Note: The methods listed below are subject to change until we reach a 1.0.0 rele
|
|||||||
* [shuffle](#shuffle)
|
* [shuffle](#shuffle)
|
||||||
* [longestCommonPrefix](#longestcommonprefix)
|
* [longestCommonPrefix](#longestcommonprefix)
|
||||||
* [longestCommonSuffix](#longestcommonsuffix)
|
* [longestCommonSuffix](#longestcommonsuffix)
|
||||||
|
* [longestCommonSubstring](#longestcommonsubstring)
|
||||||
* [Tests](#tests)
|
* [Tests](#tests)
|
||||||
* [License](#license)
|
* [License](#license)
|
||||||
|
|
||||||
@@ -543,9 +544,21 @@ S::create('fòô bàř', 'UTF-8')->longestCommonSuffix('fòr bàř');
|
|||||||
S::longestCommonSuffix('fòô bàř', 'fòr bàř', 'UTF-8'); // ' bàř'
|
S::longestCommonSuffix('fòô bàř', 'fòr bàř', 'UTF-8'); // ' bàř'
|
||||||
```
|
```
|
||||||
|
|
||||||
## TODO
|
##### longestCommonSubstring
|
||||||
|
|
||||||
**longestCommonSubstring**
|
$stringy->longestCommonSubstring(string $otherString)
|
||||||
|
|
||||||
|
S::longestCommonSubstring(string $str, string $otherString [, $encoding ])
|
||||||
|
|
||||||
|
Finds the longest common substring between $str and $otherString. In the
|
||||||
|
case of ties, returns that which occurs first.
|
||||||
|
|
||||||
|
```php
|
||||||
|
S::create('foo bar')->longestCommonSubstring('boo far');
|
||||||
|
S::longestCommonSubstring('foo bar', 'boo far'); // 'oo '
|
||||||
|
```
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
**count** => substr_count
|
**count** => substr_count
|
||||||
|
|
||||||
|
@@ -405,7 +405,7 @@ class StaticStringy
|
|||||||
*
|
*
|
||||||
* @return string The longest common prefix
|
* @return string The longest common prefix
|
||||||
*/
|
*/
|
||||||
public function longestCommonPrefix($str, $otherString, $encoding = null)
|
public static function longestCommonPrefix($str, $otherString, $encoding = null)
|
||||||
{
|
{
|
||||||
return Stringy::create($str, $encoding)
|
return Stringy::create($str, $encoding)
|
||||||
->longestCommonPrefix($otherString)->str;
|
->longestCommonPrefix($otherString)->str;
|
||||||
@@ -416,9 +416,22 @@ class StaticStringy
|
|||||||
*
|
*
|
||||||
* @return string The longest common suffix
|
* @return string The longest common suffix
|
||||||
*/
|
*/
|
||||||
public function longestCommonSuffix($str, $otherString, $encoding = null)
|
public static function longestCommonSuffix($str, $otherString, $encoding = null)
|
||||||
{
|
{
|
||||||
return Stringy::create($str, $encoding)
|
return Stringy::create($str, $encoding)
|
||||||
->longestCommonSuffix($otherString)->str;
|
->longestCommonSuffix($otherString)->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the longest common substring between $str and $otherString. In the
|
||||||
|
* case of ties, returns that which occurs first.
|
||||||
|
*
|
||||||
|
* @return string The longest common substring
|
||||||
|
*/
|
||||||
|
public static function longestCommonSubstring($str, $otherString,
|
||||||
|
$encoding = null)
|
||||||
|
{
|
||||||
|
return Stringy::create($str, $encoding)
|
||||||
|
->longestCommonSubstring($otherString)->str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -677,4 +677,49 @@ class Stringy
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the longest common substring between $str and $otherString. In the
|
||||||
|
* case of ties, returns that which occurs first.
|
||||||
|
*
|
||||||
|
* @return Stringy Object with its $str being the longest common substring
|
||||||
|
*/
|
||||||
|
public function longestCommonSubstring($otherString)
|
||||||
|
{
|
||||||
|
// Uses dynamic programming to solve
|
||||||
|
// http://en.wikipedia.org/wiki/Longest_common_substring_problem
|
||||||
|
$strLength = mb_strlen($this->str, $this->encoding);
|
||||||
|
$otherLength = mb_strlen($otherString, $this->encoding);
|
||||||
|
|
||||||
|
// Return if either string is empty
|
||||||
|
if ($strLength == 0 || $otherLength == 0) {
|
||||||
|
$this->str = '';
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$len = 0;
|
||||||
|
$end = 0;
|
||||||
|
$table = array_fill(0, $strLength + 1, array_fill(0, $otherLength + 1, 0));
|
||||||
|
|
||||||
|
for ($i = 1; $i <= $strLength; $i++){
|
||||||
|
for ($j = 1; $j <= $otherLength; $j++){
|
||||||
|
$strChar = mb_substr($this->str, $i - 1, 1, $this->encoding);
|
||||||
|
$otherChar = mb_substr($otherString, $j - 1, 1, $this->encoding);
|
||||||
|
|
||||||
|
if ($strChar == $otherChar) {
|
||||||
|
$table[$i][$j] = $table[$i - 1][$j - 1] + 1;
|
||||||
|
if ($table[$i][$j] > $len) {
|
||||||
|
$len = $table[$i][$j];
|
||||||
|
$end = $i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$table[$i][$j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->str = mb_substr($this->str, $end - $len, $len, $this->encoding);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -499,6 +499,24 @@ class CommonTest extends PHPUnit_Framework_TestCase
|
|||||||
return $testData;
|
return $testData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function stringsForLongestCommonSubstring()
|
||||||
|
{
|
||||||
|
$testData = array(
|
||||||
|
array('foo', 'foobar', 'foo bar'),
|
||||||
|
array('foo bar', 'foo bar', 'foo bar'),
|
||||||
|
array('oo ', 'foo bar', 'boo far'),
|
||||||
|
array('foo ba', 'foo bad', 'foo bar'),
|
||||||
|
array('', 'foo bar', ''),
|
||||||
|
array('fòô', 'fòôbàř', 'fòô bàř', 'UTF-8'),
|
||||||
|
array('fòô bàř', 'fòô bàř', 'fòô bàř', 'UTF-8'),
|
||||||
|
array(' bàř', 'fòô bàř', 'fòr bàř', 'UTF-8'),
|
||||||
|
array(' ', 'toy car', 'fòô bàř', 'UTF-8'),
|
||||||
|
array('', 'fòô bàř', '', 'UTF-8'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $testData;
|
||||||
|
}
|
||||||
|
|
||||||
// A test is required so as not to throw an error
|
// A test is required so as not to throw an error
|
||||||
// This is a lot cleaner than using PHPUnit's mocks to spy
|
// This is a lot cleaner than using PHPUnit's mocks to spy
|
||||||
public function test() {
|
public function test() {
|
||||||
|
@@ -288,4 +288,14 @@ class StaticStringyTestCase extends CommonTest
|
|||||||
$result = S::longestCommonSuffix($str, $otherString, $encoding);
|
$result = S::longestCommonSuffix($str, $otherString, $encoding);
|
||||||
$this->assertEquals($expected, $result);
|
$this->assertEquals($expected, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider stringsForLongestCommonSubstring
|
||||||
|
*/
|
||||||
|
public function testLongestCommonSubstring($expected, $str, $otherString,
|
||||||
|
$encoding = null)
|
||||||
|
{
|
||||||
|
$result = S::longestCommonSubstring($str, $otherString, $encoding);
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -281,13 +281,13 @@ class StringyTestCase extends CommonTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider stringsForLongestCommonSuffix
|
* @dataProvider stringsForLongestCommonSubstring
|
||||||
*/
|
*/
|
||||||
public function testLongestCommonSuffix($expected, $str, $otherString,
|
public function testLongestCommonSubstring($expected, $str, $otherString,
|
||||||
$encoding = null)
|
$encoding = null)
|
||||||
{
|
{
|
||||||
$result = S::create($str, $encoding)
|
$result = S::create($str, $encoding)
|
||||||
->longestCommonSuffix($otherString);
|
->longestCommonSubstring($otherString);
|
||||||
$this->assertEquals($expected, $result);
|
$this->assertEquals($expected, $result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user