1

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 :)

4
  • 1
    "...without using any standard JavaScript methods?" Why such a restriction? Commented May 24, 2016 at 19:46
  • Most likely it's a homework... Commented May 24, 2016 at 19:48
  • I see no benefits of such approach: bad readability, bad flexibility, a lot of code ... perhaps, only testing for loop(just for fun) Commented May 24, 2016 at 19:57
  • yeah.. a homework you can say :) Commented May 25, 2016 at 8:44

6 Answers 6

5

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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'));

1 Comment

length is not a function. Not even a getter. Just a data property. See spec
1

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.

Comments

1

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(''));
    }

Comments

1

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])));

2 Comments

I could only accept one answer. But this implementation is great (y). Thanks again. +1
No worries, I'm just glad you found it interesting. :-)
0

You can do like this

var  substr = "test",
  masterstr = "test1",
checksubstr = (ms,ss) => !!~ms.indexOf(ss);

console.log(checksubstr(masterstr,substr));

1 Comment

requirement - "without using any standard JavaScript methods"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.