Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Z algorithm #147

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ Various Math algorithms:
Various String algorithms:

- [Levenshtein Distance](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/string/levenshtein_distance.js)
- [Z-Algorithm](https://github.com/manrajgrover/algorithms-js/blob/master/src/algorithms/string/zalgorithm.js)


#### Geometry
Various Geometry algorithms:
Expand Down
4 changes: 3 additions & 1 deletion src/algorithms/string/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const levenshteindistance = require('./levenshtein_distance');
const zalgorithm = require('./zalgorithm');

module.exports = {
levenshteindistance
levenshteindistance,
zalgorithm
};
51 changes: 51 additions & 0 deletions src/algorithms/string/zalgorithm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* @param {string} text
* @param {string} pattern
* @return {Array.<Number>|null} returns a list of index which is the begginning of the pattern
*/
const zAlgorithm = (text, pattern) => {
if (!text || !pattern) { return null; }

const str = pattern + '$' + text;
const z = new Array(str.length).fill(0);

let l = 0;
let r = 1;
let k = 0;

for (let i = 0; i < z.length; i++) {
if (i > r) {
l = r = i;
while (r < z.length && str[r-l] === str[r]) {
r++;
}
z[i] = r-l;
r--;
}
else {
k = i-l;
if (z[k] < r-i+1) {
z[i] = z[k];
}
else {
l = i;
while (r < z.length && str[r-l] === str[r]) {
r++;
}
z[i] = r-l;
r--;
}
}
}

let ret = [];
for (let i = 0; i < z.length; i++) {
if (z[i] >= pattern.length) {
ret.push(i - pattern.length - 1);
}
}

return ret;
};

module.exports = zAlgorithm;
53 changes: 53 additions & 0 deletions test/algorithms/string/testZAlgorithm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-env mocha */
const zalgorithm = require('../../../src').algorithms.string.zalgorithm;
const assert = require('assert');

describe('Z Algorithm', () => {
it('should return [4]', () => {
const text = 'xaayaab';
const pattern = 'aab';

const result = zalgorithm(text, pattern);
assert.deepEqual(result, [4]);
});

it('should return [0,5,9]', () => {
const text = 'aabxcaabxaabxay';
const pattern = 'aabx';

const result = zalgorithm(text, pattern);
assert.deepEqual(result, [0,5,9]);
});

it('should return [6]', () => {
const text = 'abxabcabcaby';
const pattern = 'abcaby';

const result = zalgorithm(text, pattern);
assert.deepEqual(result, [6]);
});

it('should return null when text or pattern is empty', () => {
const text = '';
const pattern = '';

const result = zalgorithm(text, pattern);
assert.deepEqual(result, null);
});

it('should return [0,54]', () => {
const text = 'Mississippi is a beautiful state with lots of rivers. Mississippi River is the longest river in the United States.';
const pattern = 'Mississippi';

const result = zalgorithm(text, pattern);
assert.deepEqual(result, [0,54]);
});

it('should return [6,194]', () => {
const text = 'Mount Everest, also known as Sagarmatha in Nepal, is the world\'s tallest mountain. It is a part of the Himalayas and has long been a challenge for climbers. The first successful ascent of Mount Everest was in 1953 by Sir Edmund Hillary and Tenzing Norgay.';
const pattern = 'Everest';

const result = zalgorithm(text, pattern);
assert.deepEqual(result, [6,194]);
});
});