1
0
mirror of https://github.com/danielstjules/Stringy.git synced 2025-08-11 15:54:04 +02:00

Added longestCommonSubstring

This commit is contained in:
Daniel St. Jules
2013-07-27 02:47:58 -04:00
parent aeef5493c0
commit 332ceb4224
6 changed files with 107 additions and 8 deletions

View File

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

View File

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

View File

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

View File

@@ -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() {

View File

@@ -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);
}
} }

View File

@@ -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);
} }
} }