Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
GordonLesti committed Sep 30, 2019
1 parent 558f52d commit d5f2e0d
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/build/
/vendor/
/composer.lock
22 changes: 22 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
language: php

php:
- '7.0'
- '7.1'
- '7.2'
- '7.3'

install:
- composer install

before_script:
- mkdir -p build/logs

script:
- composer phpcs
- composer phpmd
- composer phpcpd
- composer test

after_script:
- php vendor/bin/coveralls -v
37 changes: 37 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "gordonlesti/longest-common-subsequence",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Gordon Lesti",
"email": "info@gordonlesti.com"
}
],
"require": {
"php": ">=7.0"
},
"autoload": {
"psr-4": {
"GordonLesti\\LongestCommonSubsequence\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"GordonLesti\\LongestCommonSubsequenceTest\\": "tests"
}
},
"require-dev": {
"phpunit/phpunit": "^6.5",
"phpmd/phpmd": "^2.7",
"sebastian/phpcpd": "^3.0",
"squizlabs/php_codesniffer": "^3.5",
"satooshi/php-coveralls": "^2.1"
},
"scripts": {
"test": "php vendor/bin/phpunit",
"phpcs": "php vendor/bin/phpcs",
"phpmd": "php vendor/bin/phpmd src/,tests/ text cleancode,codesize,controversial,design,naming,unusedcode",
"phpcpd": "php vendor/bin/phpcpd src/ tests/"
}
}
8 changes: 8 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<ruleset name="Levenshtein">
<description>The coding standard for LongestCommonSubsequence.</description>
<file>src/</file>
<file>tests/</file>
<arg name="extensions" value="php"/>
<rule ref="PSR2"/>
</ruleset>
28 changes: 28 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="LongestCommonSubseqence Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
<log type="junit" target="build/report.junit.xml"/>
<log type="coverage-html" target="build/coverage" charset="UTF-8" yui="true" highlight="true"/>
<log type="coverage-text" target="build/coverage.txt"/>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
</phpunit>
58 changes: 58 additions & 0 deletions src/LongestCommonSubsequence.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);

namespace GordonLesti\LongestCommonSubsequence;

class LongestCommonSubsequence
{
/**
* Calculates the longest common subsequence of both strings and returns the
* length.
* @see https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
*
* @param string $str1
* @param string $str2
* @return int
*/
public static function lcs(string $str1, string $str2): int
{
$matrix = [];
$str1Array = self::multiByteStringToArray($str1);
$str2Array = self::multiByteStringToArray($str2);
$str1Length = count($str1Array);
$str2Length = count($str2Array);

$matrix[0] = array_fill(0, $str2Length + 1, 0);
for ($i = 0; $i < $str1Length; $i++) {
$row = [0];
for ($j = 0; $j < $str2Length; $j++) {
if ($str1Array[$i] === $str2Array[$j]) {
$row[$j + 1] = $matrix[$i][$j] + 1;
continue;
}
$row[$j + 1] = max(
$matrix[$i][$j + 1],
$row[$j]
);
}
$matrix[$i + 1] = $row;
}
return $matrix[$str1Length][$str2Length];
}

/**
* Splits a multibyte string into an array and returns it.
*
* @param string $str
* @return array
*/
private static function multiByteStringToArray(string $str): array
{
$length = mb_strlen($str);
$array = [];
for ($i = 0; $i < $length; $i++) {
$array[$i] = mb_substr($str, $i, 1);
}
return $array;
}
}
59 changes: 59 additions & 0 deletions tests/LongestCommonSubsequenceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);

namespace GordonLesti\LongestCommonSubsequenceTest;

use GordonLesti\LongestCommonSubsequence\LongestCommonSubsequence;
use PHPUnit\Framework\TestCase;

class LongestCommonSubsequenceTest extends TestCase
{
/**
* @param string $str1
* @param string $str2
* @param int $lcsLength
* @SuppressWarnings(PHPMD.StaticAccess)
* @dataProvider lcsProvider
*/
public function testLcs(string $str1, string $str2, int $lcsLength)
{
$this->assertSame(
$lcsLength,
LongestCommonSubsequence::lcs($str1, $str2)
);
}

/**
* @return array
*/
public function lcsProvider(): array
{
return [
[
'nec3ej77p99owvoyd0izmu3blez1wx1e',
'hst7pmceigql84smrmql9r5vuwilzpqs',
7
],
[
'zjos9xl7z5zs3g0spms3omzc7vtj5rwo',
'ls8f0krkimz419jh',
6
],
[
'ocjxq1za7sa0g6x1',
'',
0
],
[
'',
'qs0z58kvwgrvtpoy',
0
],
[
'ΛΕΡΒΗΔΟΗΜΑΕΞΞΘΒΗ',
'ΗΝΞΛΒΑΚΛ',
3
],
];
}
}

0 comments on commit d5f2e0d

Please sign in to comment.