Given a string s, find the length of the longest substring without repeating characters - javascript

Example Input: s = "abcabcbb" Output: 3 Explanation: The answer is "abc", with the length of 3. I tried writing this but if condition is never being exceuted. I am not able to figure out the reason.
var lengthOfLongestSubstring = function(s) {
let set = new Set();
let c =0;
for(let i =0; i< s.length; i++){
if(set.has(s[i])){
set.size =0;
}
else {
console.log(c)
c++;
}
}
return c;
};
console.log(lengthOfLongestSubstring("abcabcbb"))

You can try this:
var lengthOfLongestSubstring = function (s) {
let res = 0;
let set = new Set();
let i = 0;
let j = 0;
while (i < s.length && j < s.length) {
if (!set.has(s[j])) {
set.add(s[j]);
j++;
if (j - i > res) res = j - i;
} else {
set.delete(s[i]);
i++;
}
}
return res;
};

This is the same algorithm as described by danhuong, simply written with a recursive call and no mutable variables.
const longestSubstring = (str, i = 0, j = 0, found = new Set(), res = 0) =>
j >= str.length
? res
: found .has (str [j])
? longestSubstring (str, i + 1, j, found .delete (str [i]) && found, res)
: longestSubstring (str, i, j + 1, found .add (str [j]), Math .max (res, j + 1 - i))
console .log (longestSubstring ("pwwkew"));
console .log (longestSubstring ("abcabcbb"));
console .log (longestSubstring ("abcabcbbvwxyz"));
console .log (longestSubstring ("abaca"));
console .log (longestSubstring ("abacdefg"));

You need to add the actual character.
set.size = 0 does not work. it is a read only property of Set.
Then you need to store the last found longest string and store it too.
Version with Set and without count, because Set has size.
const
longestSubstring = function(s) {
let set = new Set,
longest = 0;
for (const c of s) {
if (set.has(c)) {
if (longest < set.size) longest = set.size;
set = new Set([c]);
} else {
set.add(c);
}
}
if (longest < set.size) longest = set.size;
return longest;
};
console.log(longestSubstring("pwwkew"));
console.log(longestSubstring("abcabcbb"));
console.log(longestSubstring("abcabcbbvwxyz"));
A version with a string only.
const
longestSubstring = function(s) {
let sub = '',
longest = 0;
for (const c of s) {
if (sub.includes(c)) {
if (longest < sub.length) longest = sub.length;
sub = c;
} else {
sub += c;
}
}
if (longest < sub.length) longest = sub.length;
return longest;
};
console.log(longestSubstring("pwwkew"));
console.log(longestSubstring("abcabcbb"));
console.log(longestSubstring("abcabcbbvwxyz"));

Related

I would like to fill an array with numbers using javascript with a for loop

"But I always double the numbers. so [1,1,2,2,3,3 .......] how can you do that? I am looking forward to the answer. "
Continuous with a number, the for loop is good. But how do I do it with double numbers?
To get an array to N, use:
let N = 10;
Array.from(Array(N).keys())
To double each value in any array:
[...yourArray.map(n => [n, n])].flat()
So, your solution:
let n = 10;
const a = [...Array.from(Array(n).keys()).map(k => [k, k])].flat()
console.log(a)
To have it starting from 0, not 1, alter the mapping accordingly:
let n = 10;
const a = [
...Array.from(Array(n).keys())
.map(k => [k + 1, k + 1])
].flat()
console.log(a)
Arguably, the cleanest solution:
function doubleArrayTo(n) {
const a = [];
for (i = 1; i <= n; i++) {
a.push(i, i);
}
return a;
}
console.log(doubleArrayTo(10))
Out of curiosity, I tested their performance. Unsurprisingly, the for loop wins hands down over the spread syntax:
function doubleFor(n) {
const a = [];
for (i = 1; i <= n; i++) {
a.push(i, i);
}
return a;
}
function doubleSpread(n) {
return [
...Array.from(Array(n).keys())
.map(k => [k + 1, k + 1])
].flat()
}
function run_test(fn, value) {
const t0 = performance.now();
fn(value);
return performance.now() - t0;
}
[1e4, 1e5, 1e6, 1e7].map(value => {
console.log(
`(${value}): for => ${
run_test(doubleFor, value)
} | spread => ${
run_test(doubleSpread, value)
}`);
});
follow this code
var array = [];
for(int i = 0;i <= 10;i++) {
array.push(i);
array.push(i);//again
}
var array = [];
for (let i = 0; i <= 10; i++) {
array.push(i,i);
}
console.log(array);
Edit
You can use multi input for array.push(i,i,i,....)

Longest Common Prefix in Javascript

I am trying to solve the Leet Code challenge 14. Longest Common Prefix:
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string "".
Example 1:
Input: strs = ["flower","flow","flight"]
Output: "fl"
Example 2:
Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
Constraints:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] consists of only lower-case English letters.
My solution:
let strs = ["flower", "flow", "flight"];
var longestCommonPrefix = function (strs) {
for (let i = 0; i < strs.length; i++) {
for (let j = 0; j < strs[i].length; j++) {
// console.log(strs[i+2][j]);
if (strs[i][j] == strs[i + 1][j] && strs[i + 1][j] ==strs[i + 2][j]) {
return (strs[i][j]);
} else {
return "0";
}
}
}
};
console.log(longestCommonPrefix(strs));
Output: f
How can I iterate over every character and check if it is same and then go for next and if it fails then the longest common prefix will be returned?
As the longest common prefix must occur in every string of the array you can jus iterate over the length and check if all words have the same char at that index until you find a difference
function prefix(words){
// check border cases size 1 array and empty first word)
if (!words[0] || words.length == 1) return words[0] || "";
let i = 0;
// while all words have the same character at position i, increment i
while(words[0][i] && words.every(w => w[i] === words[0][i]))
i++;
// prefix is the substring from the beginning to the last successfully checked i
return words[0].substr(0, i);
}
console.log(1, prefix([]));
console.log(2, prefix([""]));
console.log(3, prefix(["abc"]));
console.log(4, prefix(["abcdefgh", "abcde", "abe"]));
console.log(5, prefix(["abc", "abc", "abc"]));
console.log(6, prefix(["abc", "abcde", "xyz"]));
Some of the issues:
Your inner loop will encounter a return on its first iteration. This means your loops will never repeat, and the return value will always be one character.
It is wrong to address strs[i+1] and strs[i+2] in your loop, as those indexes will go out of bounds (>= strs.length)
Instead of performing character by character comparison, you could use substring (prefix) comparison (in one operation): this may seem a waste, but as such comparison happens "below" JavaScript code, it is very fast (and as string size limit is 200 characters, this is fine).
The algorithm could start by selecting an existing string as prefix and then shorten it every time there is a string in the input that doesn't have it as prefix. At the end you will be left with the common prefix.
It is good to start with the shortest string as the initial prefix candidate, as the common prefix can certainly not be longer than that.
var longestCommonPrefix = function(strs) {
let prefix = strs.reduce((acc, str) => str.length < acc.length ? str : acc);
for (let str of strs) {
while (str.slice(0, prefix.length) != prefix) {
prefix = prefix.slice(0, -1);
}
}
return prefix;
};
let res = longestCommonPrefix(["flower","flow","flight"]);
console.log(res);
An approach based on sorting by word length, and for the shortest word, for exiting early, an entirely Array.every-based prefix-validation and -aggregation ...
function longestCommonPrefix(arr) {
const charList = [];
const [shortestWord, ...wordList] =
// sort shallow copy by item `length` first.
[...arr].sort((a, b) => a.length - b.length);
shortestWord
.split('')
.every((char, idx) => {
const isValidChar = wordList.every(word =>
word.charAt(idx) === char
);
if (isValidChar) {
charList.push(char);
}
return isValidChar;
});
return charList.join('');
}
console.log(
longestCommonPrefix(["flower","flow","flight"])
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
not the best solution but this should work
function longestPrefix(strs){
if(strs.length <1){
return "";
}
const sharedPrefix=function(str1,str2){
let i=0;
for(;i<Math.min(str1.length,str2.length) /*todo optimize*/;++i){
if(str1[i] !== str2[i]){
break;
}
}
return str1.substr(0,i);
};
let curr = strs[0];
for(let i=1;i<strs.length;++i){
curr=sharedPrefix(curr,strs[i]);
if(curr.length < 1){
// no shared prefix
return "";
}
}
return curr;
}
this:
strs[i][j] == strs[i + 1][j] ==strs[i + 2][j]
makes no sense in JS... or at least, makes no sense in what you are doing... to do this you should use a && operator, like this:
strs[i][j] == strs[i + 1][j] && strs[i + 1][j] ==strs[i + 2][j]
Otherwise JS will evaluate the first condition, and then will evaluate the result of that operation (either true or false) with the third value
In addition to this, consider that you are looping with i over the array, and so i will also be str.length - 1 but in the condition you are referencing strs[i + 2][j] that will be in that case strs[str.length + 1][j] that in your case, makes no sense.
About the solution:
You should consider that the prefix is common to all the values in the array, so you can take in consideration one value, and just check if all the other are equals... the most obvious is the first one, and you will end up with something like this:
let strs = ["flower", "flow", "flight", "dix"];
function longestCommonPrefix (strs) {
// loop over the characters of the first element
for (let j = 0; j < strs[0].length; j++) {
// ignore the first elements since is obvious that is equal to itself
for (let i = 1; i < strs.length; i++) {
/* in case you have like
[
'banana',
'bana'
]
the longest prefix is the second element
*/
if(j >= strs[i].length){
return strs[i]
}
// different i-th element
if(strs[0][j] != strs[i][j]){
return strs[0].substr(0, j)
}
}
}
// all good, then the first element is common to all the other elements
return strs[0]
};
console.log(longestCommonPrefix(strs));
you can do it like this, it works fast enough ~ 110ms
function longestCommonPrefix(strs){
if (strs.length === 0) {
return ''
}
const first = strs[0];
let response = '';
let prefix = '';
for (let i = 0; i < first.length; i++) {
prefix += first[i];
let find = strs.filter(s => s.startsWith(prefix));
if (find.length === strs.length) {
response = prefix;
}
}
return response;
};
let strs = ["flower", "flow", "flight"];
var longestCommonPrefix = function (strs) {
for (let i = 0; i < strs.length; i++) {
for (let j = 0; j < strs[i].length; j++) {
console.log(strs[i+2][j]);
if (strs[i][j] == strs[i + 1][j] && strs[i][j] ==strs[i + 2][j]) {
return (strs[i][j]);
} else {
return "0";
}
}
}
};
console.log(longestCommonPrefix(strs));
This **return ** f
Increase the index while the letter is the same at that index for all words in the list. Then slice on it.
function prefix(words) {
if (words.length === 0) { return '' }
let index = 0;
while (allSameAtIndex(words, index)) {
index++;
}
return words[0].slice(0, index);
}
function allSameAtIndex(words, index) {
let last;
for (const word of words) {
if (last !== undefined && word[index] !== last[index]) {
return false;
}
last = word;
}
return true;
}
I assume you are here for Leetcode problem solution.
var longestCommonPrefix = function(strs) {
let arr = strs.concat().sort();
const a1 = arr[0];
const a2 = arr[arr.length -1];
const length = a1.length;
let i=0;
while(i<length && a1.charAt(i) == a2.charAt(i)) i++;
return a1.substring(0,i);
};
function prefixLen(s1, s2) {
let i = 0;
while (i <= s1.length && s1[i] === s2[i]) i++;
return i;
}
function commonPrefix(arr) {
let k = prefixLen(arr[0], arr[1]);
for (let i = 2; i < arr.length; i++) {
k = Math.min(k, prefixLen(arr[0], arr[i]));
}
return arr[0].slice(0, k);
}
console.log(commonPrefix(['pirate', 'pizza', 'pilates'])) // -> "pi"
var longestCommonPrefix = function(strs) {
let prefix = "";
for(let i = 0; i < strs[0].length; i++) {
for(let j = 1; j < strs.length; j++) {
if(strs[j][i] !== strs[0][i]) return prefix;
}
prefix = prefix + strs[0][i];
}
return prefix;
};
console.log(longestCommonPrefix);
It is as simple as one loop and compare each element of the strings
const longestPrefix = (strs) => {
[word1, word2, word3] = strs;
let prefix = [];
if(strs === null || strs.length <= 2 || strs.length > 3) return 'please
insert 3 elements'
for (let i=0; i < word1.length; i++){
if(word1[i] === word2[i] && word1[i] === word3[i]){
prefix.push(word1[i])
}
}
return prefix.join('')
}
I read in another answer: 'Increase the index while the letter is the same at that index for all words in the list. Then slice on it.'
that's how I came up with this:
const findPrefix = (strs) => {
let i = 0;
while (strs.every((item) => strs[0][i] === item[i])) {
i++;
}
return strs[0].slice(0, i);
};
console.log(findPrefix(["flo", "flow", "flomingo"]));
const findPrefix = (strs) => {
let broke = false;
return strs[0].split("").reduce(
(acc, curr, index) =>
broke || !strs.every((word) => word[index] === curr)
? (broke = true && acc)
: (acc += curr),
""
);
};
console.log(findPrefix(["flower", "flow", "flamingo"]));
Here is my solution, Today I had an interview and the dev asked me the same question, I think I failed because I got stuck hahaha kinda nervous when someone is watching me 😂, anyway I decided to figure it out after the interview is done and this is my answer (without google it I swear) and for those who don't feel comfortable with the common "for loop"
const arr = ["absence", "absolute", "absolutely", "absorb"]
function getPrefix(arr) {
if (arr.length === 0 || arr.some(s => !s)) return null //if it's an empty array or one of its values is null or '', return null
const first = arr[0].split("") // turns the first position of the array, into an array
const res = arr.map(w => {
// mapping the original array
const compare = w.split("") // every item of the array will be converted in another array of its characters
return first.map((l, idx) => (compare[idx] === l ? l : "")).join("") // loop through the "first" array and compare each character
})
const prefix = first.join("").startsWith(res[res.length - 1]) // compare if the first letter starts with the last item of the returned array
? res[res.length - 1] // if true, return the final response which is the prefix
: null // else, return null, which means there is no common prefix
console.log("prefix: ", prefix)
return prefix
}
getPrefix(arr)
let arr = ["flower", "flow", "flight"]
function checkPrefix(array) {
let index = []
for (let i = 0; i <= array[0].length; i++) {
if (check(array[0][i], i, array)) {
index.push(i)
} else {
break;
}
}
console.log(array[0].substring(index[0], index[index.length - 1] + 1));
}
const check = (str, index, stringArr) => {
debugger
let status = true
stringArr.map(ele => {
debugger
if (ele[index] != str) {
status = false
}
})
return status
}
checkPrefix(arr)
/**
* #param {string[]} strs
* #return {string}
*/
var longestCommonPrefix = function(strs) {
let compare = strs[0];
let str = "";
for (let i = 1; i < strs.length; i++) {
let j = 0;
while(compare[j] != undefined && strs[i][j] != undefined) {
if(strs[i][j] == compare[j]) {
str += strs[i][j];
}
else break;
j++;
}
compare = str;
str = "";
}
return compare;
};
Longest common prefix in Javascript (All test case accepted. Asked by many company interviews.)
var longestCommonPrefix = function (strs) {
let string = '';
if (strs.length > 1) {
for (let i = 0; i < strs[0].length; i++) {
let str = strs[0].charAt(i);
for (let s = 0; s < strs.length - 1; s++) {
if (!(strs[s + 1].charAt(i) && strs[s].charAt(i) && strs[s + 1].charAt(i) == strs[s].charAt(i))) {
str = '';
}
}
if (!str) {
break;
}
string += str;
}
return string;
} else {
return strs[0];
}
};
longestCommonPrefix(["flower","flow","flight"]);
Code to find longest prefix
var longestCommonPrefix = function(strs) {
let match = false;
let len = strs[0].length ;
let ans = "";
let prev_ans ="";
if(strs.length ==1){
return strs[0];
}
for (let i = 1; i < strs.length; i++){
if( strs[i-1].length > strs[i].length){
len = strs[i].length;
}
}
for (let i = 1; i < strs.length; i++){
for (let j = 0; j < len; j++){
if(strs[i-1].charAt(j) == strs[i].charAt(j)){
ans += strs[i-1].charAt(j);
match = true;
}
else{
break;
}
}
if(prev_ans != "" && prev_ans !=ans){
if(prev_ans.length > ans.length){
return ans;
}else{
return prev_ans;
}
}
prev_ans = ans;
ans = "";
if (match == false){
return "";
}
}
return prev_ans;
};
console.log(longestCommonPrefix(["flow","fly","flu"]));
My solution:
function longestCommonPrefix(...words) {
words.sort(); // shortest string will be first and the longest last
return (
words[0].split('') // converts shortest word to an array of chars
.map((char, idx) => words[words.length - 1][idx] === char ? char : '\0') // replaces non-matching chars with NULL char
.join('') // converts back to a string
.split('\0') // splits the string by NULL characters
.at(0) // returns the first part
);
}
Usage example:
longestCommonPrefix('abca', 'abda', 'abea'); // 'ab'
let testcases = [
["flower", "flow"], //should return "flow"
["flower", "flow", "flight"], //should return "fl"
["flower", "flow", "fight"], //should return "f"
["flower", "flow", "floor"], //should return "flo"
["flower"], //should return "flower"
]
var longestCommonPrefix = function(strs) {
for(var i=0; i<strs.length; i++){
for(var j=0; j<strs[i].length; j++){
if(strs[i][j] + strs[i][j+1] === strs[i+1][j]+strs[i+1][j+1]){
return strs[i][j]+strs[i][j+1];
}
else {
return "";
}
}
}
};
for (let strs of testcases)
console.log(longestCommonPrefix(strs));

Permutation: Push function not working, JavaScript O(n*n!) runtime

The problem at hand is :
Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order.
I have this code with an ok run time but it seems that the push function is not working, I am not sure why bc it all makes sense in general
Example 1:
Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
Constraints:
1 <= nums.length <= 6
-10 <= nums[i] <= 10
All the integers of nums are unique.
var permute = function(nums) {
if (nums == null) {
return []
}
return getPermutations(nums);
};
function getPermutations(arr) {
var set = {}
var size = factorial(arr.length)
var result = []
while (Object.keys(set).length < size) {
for (var i = 0; i < arr.length && result.length < size; i++) {
for (var j = arr.length - 1; j >= 0 && result.length < size; j--) {
if (!set[arr]) {
set[arr] = 1
console.log(arr) //clearly see the permutations printed
result.push(arr) //why is this not working...
}
arr = swap(arr,i,j)
}
}
}
return result
}
function swap(arr,i,j) {
var tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
return arr
}
function factorial(n) {
if (n == 0 || n == 1) {
return 1
}
return n*factorial(n-1)
}
You're pushing the same array multiple times into the result array.
You can fix this by creating a copy of the arr array before pushing it.
(So the code after it can't mutate the array again)
So instead of result.push(arr) you could use one of those examples:
// using splash operator
result.push([...arr]);
// Array#slice()
result.push(arr.slice());
// Array.from()
result.push(Array.from(arr));
// etc...
Working Example:
var permute = function(nums) {
if (nums == null) {
return []
}
return getPermutations(nums);
};
function getPermutations(arr) {
var set = {}
var size = factorial(arr.length)
var result = []
while (Object.keys(set).length < size) {
for (var i = 0; i < arr.length && result.length < size; i++) {
for (var j = arr.length - 1; j >= 0 && result.length < size; j--) {
if (!set[arr]) {
set[arr] = 1
console.log(arr) //clearly see the permutations printed
result.push([...arr]) //why is this not working...
}
arr = swap(arr,i,j)
}
}
}
return result
}
function swap(arr,i,j) {
var tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
return arr
}
function factorial(n) {
if (n == 0 || n == 1) {
return 1
}
return n*factorial(n-1)
}
console.log(permute([1,2,3]));
This question could also be a good read, it contains a lot of examples for how to efficiently calculate permutations in javascript.

Write function strLetterCount and return new string with the characters followed by the count

I need to write a function strLetterCount(word) that takes the string input, and returns a string followed by the count of occurrences.
Ex:
strLetterCount("coconut"); // "c2o2n1u1t1"
Here is what I have so far:
function strLetterCount (word){
let results = ""
for(let i = 0; i < word.length; i++) {
let charAt = word.charAt(i)
let count = 0
results += charAt
for (let j = 0; j < word.length ; j++)
{
if(word.charAt(j) === charAt)
{
count++
}
}
results += count
}
return results;
}
But the issue is that it returns c2o2c2o2n1u1t1 instead of c2o2n1u1t1. I'm not sure how to get rid of the duplicates
function strLetterCount (word){
let results = ""
for(let i = 0; i < word.length; i++) {
let charAt = word.charAt(i)
if (!results.includes(charAt)) // <----------------------
{
let count = 0
results += charAt
for (let j = 0; j < word.length ; j++)
{
if(word.charAt(j) === charAt)
{
count++
}
}
results += count
}
}
return results;
}
console.log(strLetterCount("coconut"));
Using String.prototype.split function, you can convert string into char array.
Based on that char array, using Array.prototype.reduce, you can get the duplicated char info.
With that duplicated info, can get the string linked using Array.prototype.map.
console.log(strLetterCount("coconut")); // "c2o2n1u1t1"
function strLetterCount(word) {
const wordArr = word.split('');
const duplicates = wordArr.reduce((acc, cur) => {
acc[cur] ? acc[cur] ++ : acc[cur] = 1;
return acc;
}, {});
return Object.entries(duplicates).map(([key, value]) => key + value).join('');
}
function strLetterCount(word) {
let results = {};
for (let i = 0; i < word.length; i++) {
let c = word.charAt(i)
results[c] = (results[c] || 0) + 1;
}
let r = '';
for (let c in results)
r += c + results[c];
return r;
}
console.log(strLetterCount("coconut")); // "c2o2n1u1t1"
Using the String split method, a Set, the Array map method and the Array join method you can do it in a single line of code
const strLetterCount = word => [...new Set(word.split(''))].map(l => `${l}${word.split(l).length - 1}`).join('');
console.log(strLetterCount('coconut'));

Check if string contains substring without using any standard JavaScript methods?

So I need to implement a javascript method which will return true or false depending on if the masterString contains a subString.
I did something like following but not sure if this is the right approach :
function contains(masterString, subString) {
if(subString.length > masterString.length){
return false;
}
for(var i=subString.length-1; i<masterString.length; i++){
if(concatString(i - subString.length-1, i, masterString) === subString){
return true;
}
}
return false;
}
function concatString(index1, index2, string){
var conString = '';
console.log(index1, index2-1, string);
for(var i=index1; i<index2-1; i++){
conString += string[i];
}
console.log(conString);
return conString;
}
contains('abcd', 'bc');
It isn't working fine though.
Can we implement it? Thanks :)
For each possible index, test if subString is on that index of masterString.
var indexOf = function(masterString,subString){
for(var i = 0 ; i < masterString.length - subString.length + 1; i++){
var match = true;
for(var j = 0; j < subString.length; j++){
if(masterString[i + j] !== subString[j]){
match = false;
break;
}
}
if(match)
return i;
}
return -1;
}
var contains = function(master,sub){
return indexOf(master,sub) !== -1;
}
Note: There are faster algorithms to achieve that like Knuth–Morris–Pratt.
You have a good solution. But I think mine is easier.
By the way: I think .length is a javascript funciton too.
function length(string){
var count = 0;
while(string[count] != undefined)
count++;
return count;
}
function contains(masterString, subString) {
var masterStringLength = length(masterString);
var subStringLength = length(subString);
for(var i = 0; i <= masterStringLength - subStringLength; i++)
{
var count = 0;
for(var k = 0; k < subStringLength; k++)
{
if(masterString[i + k] == subString[k])
count++;
else
break;
}
if(count == subStringLength)
return true;
}
return false;
}
console.log(contains('abcdefgh', 'bcde'));
console.log(contains('abcdefgh', 'ab'));
console.log(contains('abcdefgh', 'fgh'));
You can use a nested loop:
function contains(masterString, subString) {
outerloop:
for(var i=0; i <= masterString.length-subString.length; ++i) {
for(var j=0; j<subString.length; ++j)
if(masterString[i + j] !== subString[j]) continue outerloop;
return true;
}
return false;
}
Of course, using native methods you could achieve better performance.
This is similar to longest common subsequence See this.
this code solves your issue.
function contains(masterString, subString) {
if (findCommonSubsequence(masterString, subString) == subString)
alert(true);
else
alert(false);
}
function findCommonSubsequence(a, b) {
var table = [],
aLen = a.length,
bLen = b.length;
squareLen = Math.max(aLen, bLen);
// Initialize a table of zeros
for (var i = 0; i <= squareLen ; i++) {
table.push([]);
for (var j = 0; j <= squareLen; j++) {
table[i][j] = 0;
}
}
// Create a table of counts
for (var i = 1; i <= aLen; i++) {
for (var j = 1; j <= bLen; j++) {
if (a[i - 1] == b[j - 1]) {
table[i][j] = table[i - 1][j - 1] + 1;
} else {
table[i][j] = Math.max(table[i - 1][j], table[i][j - 1]);
}
}
}
// Move backwards along the table
i = aLen, j = bLen, LCS = [];
while (i > 0 && j > 0) {
if (a[i - 1] == b[j - 1]) {
LCS.push(a[i - 1]);
i -= 1;
j -= 1;
} else {
if (table[i][j - 1] >= table[i - 1][j]) {
j -= 1;
} else {
i -= 1;
}
}
}
return(LCS.reverse().join(''));
}
Your question doesn't have enough odd constraints, so let's do it
without for-loops as well, with some help from ES6.
// Cf. Array.prototype.some
const any = (f, [x,...xs]) =>
x === undefined ? false : f(x) || any(f,xs);
// Return true if the first iterable is a prefix of the second.
const isprefix = ([x,...xs], [y,...ys]) =>
x === undefined ? true : x == y && isprefix(xs,ys);
// tails('abc') --> [['a','b','c'], ['b','c'], ['c']]
const tails = ([x,...xs]) =>
x === undefined ? [] : [[x,...xs],...tails(xs)];
// If needle is empty, or is a prefix of any of tails(haystack), return true.
const contains = (haystack, needle) =>
needle.length ? any(bale => isprefix(needle, bale), tails(haystack)) : true;
const tests = [
['aaafoobar', 'foo'],
['foo', 'foo'],
['fo', 'foo'],
['', 'f'],
['f', ''],
['', '']
];
tests.forEach(test => console.log(JSON.stringify(test), contains(test[0], test[1])));
You can do like this
var substr = "test",
masterstr = "test1",
checksubstr = (ms,ss) => !!~ms.indexOf(ss);
console.log(checksubstr(masterstr,substr));

Categories