-1

I searched over the title and found some solutions, but none of them worked for me. I want something like following:

checkRepeat('ccc','cc');  // should give output 2
checkRepeat('cccaacddcccc','cc');  // should give output 5

and so on. Please help me with this.

What I've tried:

function checkRepeat(string, search) {
    if (!search.length) return 0;
    var pattern = new RegExp('(' + search + ')', 'ig'),
        match = string.match(pattern),
        parts = string.split(pattern).slice().filter(function (i) {
            return i.length;
        });
    console.log(match.length);
    console.log(parts.length - 1);
}
5
  • 6
    and where's the code that shows what you've tried? Commented Nov 24, 2014 at 16:36
  • It seems to be that checkRepeat('cccaacddcccc', '') should return 13, since it "occurs" in between each letter. By the way, it's highly unlikely regexp is going to work for this, since you're looking for matches which are overlapping. Your solution is not working how? @Begueradj Downvotes are not unreasonable for "gimme-some-code" questions, not matter what the rep is. Commented Nov 24, 2014 at 16:38
  • 3
    @Begueradj Up/down voting should have nothing to do with one's reputation, but should reflect the quality of the question. Commented Nov 24, 2014 at 16:42
  • Correction: you can use regexp, by resetting 'lastIndex' See the duplicate question. Commented Nov 24, 2014 at 16:43
  • 1
    There's also an answer here which addresses the overlapping case: stackoverflow.com/questions/4009756/…. Commented Nov 24, 2014 at 16:44

3 Answers 3

2

Recursion could suit your needs:

// from http://stackoverflow.com/a/646643/1225328
function startWith(str, sub) {
    return str.slice(0, sub.length) === sub;
}

function checkRepeat(str, sub) {
    // stop recursion when "str" or "sub" is empty
    if (!sub.length || !str.length) {
        return 0;
    }
    // recursion on "str" minus its first char
    return (startWith(str, sub) ? 1 : 0) + checkRepeat(str.slice(1), sub);
}

An iterative solution:

function checkRepeat(str, sub) {
    if (!sub.length) {
        return 0;
    }
    var n = sub.length;
    var count = 0;
    for (var i = 0; i <= str.length - n; i++) {
        if (str.slice(i, i + n) === sub) {
            count++;
        }
    }
    return count;
}
Sign up to request clarification or add additional context in comments.

6 Comments

This would be much more reasonable as a simple loop, not as a recursive method.
Some have said that the optimal implementation of startWith is str.indexOf(sub) === 0. Also, if you want to confuse people, you could remove the ? : 0`, since boolean values cast when added.
Note that while this solution is quite elegant, it's also pretty slow and may blow up your stack for very long strings.
Well, that's not what I read, see stackoverflow.com/a/646643/1225328. Who said that? And I have to admit that I'm not trying to confuse people :)
Sorry, I meant to say str.lastIndexOf(sub, 0) === 0, which BTW is the polyfill given by MDN.
|
1

Try this:

function checkRepeat(f, s, o) {
    return (f.length && s.length) 
           ? f.match(new RegExp((o || (undefined === o)) ? '(?=(' + s + '))' : f, 'g')).length 
           : 0;
}

This solution combine your question and also this comment.

checkRepeat('cccaacddcccc','cc');  // output 5
checkRepeat('cccaacddcccc','cc', false);  // output 1, as overlap is set to false

Comments

1

This should do it with a regex:

function checkRepeat(string, search) {
    if (!search.length) return 0; 
    var myRe = new RegExp(search, 'g');
    var count = 0;
    while (myRe.exec(string) !== null) {
        count++;
        myRe.lastIndex -= search.length-1;
    }
    return count;
}
alert(checkRepeat('ccc', 'cc')); // 2
alert(checkRepeat('cccaacddcccc', 'cc')); // 5

JSFiddle.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.