How do I check if a string is entirely made of the same substring? Unicorn Meta Zoo #1: Why...

Check if a string is entirely made of the same substring

Book with legacy programming code on a space ship that the main character hacks to escape

How to get even lighting when using flash for group photos near wall?

Would reducing the reference voltage of an ADC have any effect on accuracy?

A strange hotel

Multiple options vs single option UI

Multiple fireplaces in an apartment building?

Seek and ye shall find

My bank got bought out, am I now going to have to start filing tax returns in a different state?

Does Feeblemind produce an ongoing magical effect that can be dispelled?

Additive group of local rings

Could moose/elk survive in the Amazon forest?

Why did C use the -> operator instead of reusing the . operator?

c++ diamond problem - How to call base method only once

Is Bran literally the world's memory?

"Rubric" as meaning "signature" or "personal mark" -- is this accepted usage?

What is ls Largest Number Formed by only moving two sticks in 508?

What is the best way to deal with NPC-NPC combat?

As an international instructor, should I openly talk about my accent?

All ASCII characters with a given bit count

Did the Roman Empire have penal colonies?

How would I use different systems of magic when they are capable of the same effects?

What's the difference between using dependency injection with a container and using a service locator?

Are all CP/M-80 implementations binary compatible?



How do I check if a string is entirely made of the same substring?



Unicorn Meta Zoo #1: Why another podcast?
Announcing the arrival of Valued Associate #679: Cesar Manara
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!How to check empty/undefined/null string in JavaScript?How do I check if an element is hidden in jQuery?How do I check if an array includes an object in JavaScript?How to check if a string “StartsWith” another string?How do I make the first letter of a string uppercase in JavaScript?How to replace all occurrences of a string in JavaScriptHow to check whether a string contains a substring in JavaScript?How to check for “undefined” in JavaScript?Check if a variable is a string in JavaScriptHow to check if an object is an array?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







27















I have to create a function which takes a string, and it should return true or false based on whether the input consists of a repeated character sequence. The length of given string is always greater than 1 and the character sequence must have at least one repetition.



"aa" // true(entirely contains two strings "a")
"aaa" //true(entirely contains three string "a")
"abcabcabc" //true(entirely containas three strings "abc")

"aba" //false(At least there should be two same substrings and nothing more)
"ababa" //false("ab" exists twice but "a" is extra so false)


I have created a function, but it's:






function check(str){
if(!(str.length && str.length - 1)) return false;
let temp = '';
for(let i = 0;i<=str.length/2;i++){
temp += str[i]
//console.log(str.replace(new RegExp(temp,"g"),''))
if(!str.replace(new RegExp(temp,"g"),'')) return true;
}
return false;
}

console.log(check('aa')) //true
console.log(check('aaa')) //true
console.log(check('abcabcabc')) //true
console.log(check('aba')) //false
console.log(check('ababa')) //false





Checking of this is part of the real problem. I can't afford a non-efficient solution like this. First of all it's looping through half of the string.



The second problem is that its using replace() in each loop which makes it slow. Is there a better solution regarding performance?










share|improve this question




















  • 6





    This link may be useful to you. I always find geekforgeeks as a good source for algorithm problems - geeksforgeeks.org/…

    – Leron
    19 hours ago











  • I think its a problem of checking whether a common substring occurs throughout uniformly

    – Kunal Mukherjee
    18 hours ago






  • 1





    Do you mind if I borrow this and make it a coding challenge on the Programming Golf exchange site?

    – ouflak
    10 hours ago











  • @ouflak you can do that.

    – Maheer Ali
    10 hours ago











  • In case your curious, codegolf.stackexchange.com/questions/184682/…

    – ouflak
    10 hours ago


















27















I have to create a function which takes a string, and it should return true or false based on whether the input consists of a repeated character sequence. The length of given string is always greater than 1 and the character sequence must have at least one repetition.



"aa" // true(entirely contains two strings "a")
"aaa" //true(entirely contains three string "a")
"abcabcabc" //true(entirely containas three strings "abc")

"aba" //false(At least there should be two same substrings and nothing more)
"ababa" //false("ab" exists twice but "a" is extra so false)


I have created a function, but it's:






function check(str){
if(!(str.length && str.length - 1)) return false;
let temp = '';
for(let i = 0;i<=str.length/2;i++){
temp += str[i]
//console.log(str.replace(new RegExp(temp,"g"),''))
if(!str.replace(new RegExp(temp,"g"),'')) return true;
}
return false;
}

console.log(check('aa')) //true
console.log(check('aaa')) //true
console.log(check('abcabcabc')) //true
console.log(check('aba')) //false
console.log(check('ababa')) //false





Checking of this is part of the real problem. I can't afford a non-efficient solution like this. First of all it's looping through half of the string.



The second problem is that its using replace() in each loop which makes it slow. Is there a better solution regarding performance?










share|improve this question




















  • 6





    This link may be useful to you. I always find geekforgeeks as a good source for algorithm problems - geeksforgeeks.org/…

    – Leron
    19 hours ago











  • I think its a problem of checking whether a common substring occurs throughout uniformly

    – Kunal Mukherjee
    18 hours ago






  • 1





    Do you mind if I borrow this and make it a coding challenge on the Programming Golf exchange site?

    – ouflak
    10 hours ago











  • @ouflak you can do that.

    – Maheer Ali
    10 hours ago











  • In case your curious, codegolf.stackexchange.com/questions/184682/…

    – ouflak
    10 hours ago














27












27








27


4






I have to create a function which takes a string, and it should return true or false based on whether the input consists of a repeated character sequence. The length of given string is always greater than 1 and the character sequence must have at least one repetition.



"aa" // true(entirely contains two strings "a")
"aaa" //true(entirely contains three string "a")
"abcabcabc" //true(entirely containas three strings "abc")

"aba" //false(At least there should be two same substrings and nothing more)
"ababa" //false("ab" exists twice but "a" is extra so false)


I have created a function, but it's:






function check(str){
if(!(str.length && str.length - 1)) return false;
let temp = '';
for(let i = 0;i<=str.length/2;i++){
temp += str[i]
//console.log(str.replace(new RegExp(temp,"g"),''))
if(!str.replace(new RegExp(temp,"g"),'')) return true;
}
return false;
}

console.log(check('aa')) //true
console.log(check('aaa')) //true
console.log(check('abcabcabc')) //true
console.log(check('aba')) //false
console.log(check('ababa')) //false





Checking of this is part of the real problem. I can't afford a non-efficient solution like this. First of all it's looping through half of the string.



The second problem is that its using replace() in each loop which makes it slow. Is there a better solution regarding performance?










share|improve this question
















I have to create a function which takes a string, and it should return true or false based on whether the input consists of a repeated character sequence. The length of given string is always greater than 1 and the character sequence must have at least one repetition.



"aa" // true(entirely contains two strings "a")
"aaa" //true(entirely contains three string "a")
"abcabcabc" //true(entirely containas three strings "abc")

"aba" //false(At least there should be two same substrings and nothing more)
"ababa" //false("ab" exists twice but "a" is extra so false)


I have created a function, but it's:






function check(str){
if(!(str.length && str.length - 1)) return false;
let temp = '';
for(let i = 0;i<=str.length/2;i++){
temp += str[i]
//console.log(str.replace(new RegExp(temp,"g"),''))
if(!str.replace(new RegExp(temp,"g"),'')) return true;
}
return false;
}

console.log(check('aa')) //true
console.log(check('aaa')) //true
console.log(check('abcabcabc')) //true
console.log(check('aba')) //false
console.log(check('ababa')) //false





Checking of this is part of the real problem. I can't afford a non-efficient solution like this. First of all it's looping through half of the string.



The second problem is that its using replace() in each loop which makes it slow. Is there a better solution regarding performance?






function check(str){
if(!(str.length && str.length - 1)) return false;
let temp = '';
for(let i = 0;i<=str.length/2;i++){
temp += str[i]
//console.log(str.replace(new RegExp(temp,"g"),''))
if(!str.replace(new RegExp(temp,"g"),'')) return true;
}
return false;
}

console.log(check('aa')) //true
console.log(check('aaa')) //true
console.log(check('abcabcabc')) //true
console.log(check('aba')) //false
console.log(check('ababa')) //false





function check(str){
if(!(str.length && str.length - 1)) return false;
let temp = '';
for(let i = 0;i<=str.length/2;i++){
temp += str[i]
//console.log(str.replace(new RegExp(temp,"g"),''))
if(!str.replace(new RegExp(temp,"g"),'')) return true;
}
return false;
}

console.log(check('aa')) //true
console.log(check('aaa')) //true
console.log(check('abcabcabc')) //true
console.log(check('aba')) //false
console.log(check('ababa')) //false






javascript algorithm






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 14 hours ago









Peter Mortensen

14k1987114




14k1987114










asked 19 hours ago









Maheer AliMaheer Ali

12.7k1230




12.7k1230








  • 6





    This link may be useful to you. I always find geekforgeeks as a good source for algorithm problems - geeksforgeeks.org/…

    – Leron
    19 hours ago











  • I think its a problem of checking whether a common substring occurs throughout uniformly

    – Kunal Mukherjee
    18 hours ago






  • 1





    Do you mind if I borrow this and make it a coding challenge on the Programming Golf exchange site?

    – ouflak
    10 hours ago











  • @ouflak you can do that.

    – Maheer Ali
    10 hours ago











  • In case your curious, codegolf.stackexchange.com/questions/184682/…

    – ouflak
    10 hours ago














  • 6





    This link may be useful to you. I always find geekforgeeks as a good source for algorithm problems - geeksforgeeks.org/…

    – Leron
    19 hours ago











  • I think its a problem of checking whether a common substring occurs throughout uniformly

    – Kunal Mukherjee
    18 hours ago






  • 1





    Do you mind if I borrow this and make it a coding challenge on the Programming Golf exchange site?

    – ouflak
    10 hours ago











  • @ouflak you can do that.

    – Maheer Ali
    10 hours ago











  • In case your curious, codegolf.stackexchange.com/questions/184682/…

    – ouflak
    10 hours ago








6




6





This link may be useful to you. I always find geekforgeeks as a good source for algorithm problems - geeksforgeeks.org/…

– Leron
19 hours ago





This link may be useful to you. I always find geekforgeeks as a good source for algorithm problems - geeksforgeeks.org/…

– Leron
19 hours ago













I think its a problem of checking whether a common substring occurs throughout uniformly

– Kunal Mukherjee
18 hours ago





I think its a problem of checking whether a common substring occurs throughout uniformly

– Kunal Mukherjee
18 hours ago




1




1





Do you mind if I borrow this and make it a coding challenge on the Programming Golf exchange site?

– ouflak
10 hours ago





Do you mind if I borrow this and make it a coding challenge on the Programming Golf exchange site?

– ouflak
10 hours ago













@ouflak you can do that.

– Maheer Ali
10 hours ago





@ouflak you can do that.

– Maheer Ali
10 hours ago













In case your curious, codegolf.stackexchange.com/questions/184682/…

– ouflak
10 hours ago





In case your curious, codegolf.stackexchange.com/questions/184682/…

– ouflak
10 hours ago












8 Answers
8






active

oldest

votes


















36














You can do it by a capturing group and backreference. Just check it's the repetition of the first captured value.






function check(str) {
return /^(.+)1+$/.test(str)
}

console.log(check('aa')) //true
console.log(check('aaa')) //true
console.log(check('abcabcabc')) //true
console.log(check('aba')) //false
console.log(check('ababa')) //false





In the above RegExp:





  1. ^ and $ stands for start and end anchors to predict the position.


  2. (.+) captures any pattern and captures the value(except n).


  3. 1 is backreference of first captured value and 1+ would check for repetition of captured value.


Regex explanation here



For RegExp debugging use: https://regex101.com/r/pqlAuP/1/debugger





Performance : https://jsperf.com/regex-and-loop/1






share|improve this answer


























  • Can you explain to us what this line is doing return /^(.+)1+$/.test(str)

    – Thanveer Shah
    19 hours ago






  • 15





    Also what is the complexity of this solution? I'm not absolutely sure but it doesn't seem to be much faster than the one the OP has.

    – Leron
    19 hours ago






  • 3





    @PranavCBalan I'm not good at algorithms, that's why I write in the comments section. However I have several things to mention - the OP already has a working solution so he is asking for one that will give him better performance and you haven't explained how your solution will outperform his. Shorter doesn't mean faster. Also, from the link you gave: If you use normal (TCS:no backreference, concatenation,alternation,Kleene star) regexp and regexp is already compiled then it's O(n). but as you wrote you are using backreference so is it still O(n)?

    – Leron
    18 hours ago











  • @PranavCBalan Its showing both are fastest.

    – Maheer Ali
    18 hours ago






  • 1





    You can use [sS] instead of . if you need to match newline characters in the same way as other characters. The dot character doesn't match on newlines; the alternative searches for all white-space and non-whitespace characters, which means that newlines are included in the match. (Note that this is faster than the more intuitive (.|[rn]).) However, if the string definitely doesn't contain newlines, then the simple . will be fastest. Note this will be a lot simpler if the dotall flag is implemented.

    – HappyDog
    16 hours ago





















19














Perhaps the fastest algorithmic approach is building a Z-function in linear time:




The Z-function for this string is an array of length n where the i-th
element is equal to the greatest number of characters starting from
the position i that coincide with the first characters of s.



In other words, z[i] is the length of the longest common prefix
between s and the suffix of s starting at i.




C++ implementation for reference:



vector<int> z_function(string s) {
int n = (int) s.length();
vector<int> z(n);
for (int i = 1, l = 0, r = 0; i < n; ++i) {
if (i <= r)
z[i] = min (r - i + 1, z[i - l]);
while (i + z[i] < n && s[z[i]] == s[i + z[i]])
++z[i];
if (i + z[i] - 1 > r)
l = i, r = i + z[i] - 1;
}
return z;
}


JavaScript implementation:






function z_function(s) {
var n = s.length;
var z = Array(n).fill(0);
var i, l, r;
for (i = 1, l = 0, r = 0; i < n; ++i) {
if (i <= r)
z[i] = Math.min(r - i + 1, z[i - l]);
while (i + z[i] < n && s[z[i]] == s[i + z[i]])
++z[i];

//we can check condition and return here
// if (z[i] + i === n && n % i === 0) return true;

if (i + z[i] - 1 > r)
l = i, r = i + z[i] - 1;
}
return z.some((zi, i) => (i + zi) === n && n % i === 0);
}
console.log(z_function("abacabacabac"));
console.log(z_function("abcab"));





Then you need to check indexes i that divide n. If you find such i that i+z[i]=n then the string s can be compressed to the length i and you can return true.



For example, for



string s= 'abacabacabac'  with length n=12`


z-array is



(0, 0, 1, 0, 8, 0, 1, 0, 4, 0, 1, 0)


and we can find that for



i=4
i+z[i] = 4 + 8 = 12 = n
and
n % i = 12 % 4 = 0`


so s might be represented as substring of length 4 repeated three times.






share|improve this answer





















  • 2





    return z.some((zi, i) => (i + zi) === n && n % i === 0)

    – Pranav C Balan
    12 hours ago








  • 2





    Thanks for adding JavaScript stuff to Salman A and Pranav C Balan

    – MBo
    7 hours ago






  • 1





    Alternate approach by avoiding an additional iteration const check = (s) => { let n = s.length; let z = Array(n).fill(0); for (let i = 1, l = 0, r = 0; i < n; ++i) { if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]); while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i]; // check condition here and return if (z[i] + i === n && n % i === 0) return true; if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; } // or return false return false; }

    – Pranav C Balan
    7 hours ago





















5














Assume the string S has length N and is made of duplicates of the substring s, then the length of s divides N. For example, if S has length 15, then the substring has length 1, 3, or 5.



Let S be made of (p*q) copies of s. Then S is also made of p copies of (s, repeated q times). We have therefore two cases: If N is prime or 1, then S can only be made of copies of the substring of length 1. If N is composite, then we only need to check substrings s of length N / p for primes p dividing the length of S.



So determine N = the length of S, then find all its prime factors in time O (sqrt (N)). If there is only one factor N, check if S is the same string repeated N times, otherwise for each prime factor p, check if S consists of p repeations of the first N / p characters.






share|improve this answer
























  • I haven't checked the other solutions, but this seems very fast. You can leave out the "If there is only one factor N, check ..., otherwise" part for simplicity, as this is not a special case. Would be nice to see a Javascript implementation that can be run in jsPerf next to the other implementations.

    – user42723
    8 hours ago











  • I've now implemented this in my answer

    – user42723
    4 mins ago



















2














I think a recursive function might be very fast as well. The first observation is that the maximum repeated pattern length is half as long as the total string. And we could just test all possible repeated pattern lengths: 1, 2, 3, ..., str.length/2



The recursive function isRepeating(p,str) tests if this pattern is repeated in str.



If str is longer than the pattern, the recursion requires the first part (same length as p) to be a repetition as well as the remainder of str. So str is effectively broken up into pieces of length p.length.



If the tested pattern and str are of equal size, recursion ends here, successfully.



If the length is different (happens for "aba" and pattern "ab") or if the pieces are different, then false is returned, propagating up the recursion.






function check(str)
{
if( str.length==1 ) return true; // trivial case
for( var i=1;i<=str.length/2;i++ ) { // biggest possible repeated pattern has length/2 characters

if( str.length%i!=0 ) continue; // pattern of size i doesn't fit

var p = str.substring(0, i);
if( isRepeating(p,str) ) return true;
}
return false;
}


function isRepeating(p, str)
{
if( str.length>p.length ) { // maybe more than 2 occurences

var left = str.substring(0,p.length);
var right = str.substring(p.length, str.length);
return left===p && isRepeating(p,right);
}
return str===p;
}

console.log(check('aa')) //true
console.log(check('aaa')) //true
console.log(check('abcabcabc')) //true
console.log(check('aba')) //false
console.log(check('ababa')) //false





Performance: https://jsperf.com/reegx-and-loop/13






share|improve this answer





















  • 1





    Would it be faster to check if( str===p.repeat(str.length/i) ) return true; instead of using a recursive function?

    – Chronocidal
    10 hours ago






  • 1





    Don't put console.logs in jsperf tests, prepare the functions inside the globals section, also prepare the test strings in the globals section (sorry, cannot edit the jsperf)

    – Salman A
    9 hours ago











  • @Salman - good point. I just modified the jsperf from my predecessor (Pranav C), first time I used jsperf, cool tool.

    – Axel Podehl
    9 hours ago











  • @SalmanA : updated : jsperf.com/regex-and-loop/1 ... thanks for the info... even I'm not familiar with it(Jsperf) ... thanks for the information

    – Pranav C Balan
    9 hours ago











  • Hi Salman, thanks a lot for jsperf.com/reegx-and-loop/10 - yes, that new perf test makes much more sense. The setup of functions should go into the preparation code.

    – Axel Podehl
    9 hours ago



















1














My approach is similar to gnasher729, in that it uses the potential length of the substring as the main focus, but it is less math-y and process intensive:



L: Length of original string



S: Potential lengths of valid sub-strings



Loop S from (integer part of) L/2 to 1. If L/S is an integer check your original string against the fist S characters of the original string repeated L/S times.



The reason for looping from L/2 backwards and not from 1 onwards is to get the largest possible substring. If you want the smallest possible substring loop from 1 to L/2. Example: "abababab" has both "ab" and "abab" as possible substrings. Which of the two would be faster if you only care about a true/false result depends on the type of strings/substrings this will be applied to.






share|improve this answer

































    0














    I read the answer of gnasher729 and implemented it.
    The idea is that if there are any repetitions, then there must be (also) a prime number of repetitions. If you want performance, this is what you want.



    function* primeFactors (n) {
    for (var k = 2; k*k <= n; k++) {
    if (n % k == 0) {
    yield k
    do {n /= k} while (n % k == 0)
    }
    }
    if (n > 1) yield n
    }

    function check (str) {
    var n = str.length
    primeloop:
    for (p of primeFactors(n)) {
    var l = n/p
    var s = str.substring(0, l)
    for (var j=1; j<p; j++) {
    if (s != str.substring(l*j, l*(j+1))) continue primeloop
    }
    return true
    }
    return false
    }


    I've updated the jsPerf page that contains the algorithms used on this page.






    share|improve this answer































      -2














      I'm not familiar with JavaScript, so I don't know how fast this is going to be, but here is a linear time solution (assuming reasonable builtin implementation) using only builtins. I'll describe the algorithm in pseudocode.



      function check(str) {
      t = str + str;
      find all overlapping occurrences of str in t;
      for each occurrence at position i
      if (i > 0 && i < str.length && str.length % i == 0)
      return true; // str is a repetition of its first i characters
      return false;
      }


      The idea is similar to MBo's answer. For each i that divides the length, str is a repetition of its first i characters if and only if it remains the same after shifting for i characters.



      It comes to my mind that such a builtin may be unavailable or inefficient. In this case, it is always possible to implement the KMP algorithm manually, which takes about the same amount of code as the algorithm in MBo's answer.






      share|improve this answer


























      • The OP wants to know whether repetition exists. The second line of (the body of) your function counts the number of repetitions - that's the bit that needs to be explained. E.g. "abcabcabc" has 3 repetitions of "abc", but how did your second line work out whether it had any repetitions?

        – Lawrence
        13 hours ago











      • @Lawrence I don't understand your question. This algorithm is based on the idea that the string is a repetition of its substring if and only if for some divisor of its length i, s[0:n-i] == s[i:n], or equivalently, s == s[i:n] + s[0:i]. Why does the second line need to work out whether it had any repetitions?

        – infmagic2047
        57 mins ago



















      -7














      One of the simple ideas is to replace the string with the substring of "" and if any text exist then it is false, else it is true.






      'ababababa'.replace(/ab/gi,'')
      "a" // return false
      'abababab'.replace(/ab/gi,'')
      ""// return true








      share|improve this answer





















      • 4





        What about abcabcabc or unicornunicorn?

        – adiga
        19 hours ago











      • yes, for abc or unicorn wouldn't user will check with /abc/ or /unicorn/ , sorry if i am missing your context

        – Vinod kumar G
        17 hours ago






      • 1





        The question could be clearer, but what it's asking for is a way of deciding whether the string is completely made up of 2 or more repetitions of any other string. It is not searching for a specific substring.

        – HappyDog
        16 hours ago






      • 1





        I've added some clarification to the question, which should make it clearer now.

        – HappyDog
        15 hours ago











      • @Vinod if you are already going to use regex you should anchor your match and use test. No reason to modify the string just to validate some condition.

        – Marie
        13 hours ago












      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55823298%2fhow-do-i-check-if-a-string-is-entirely-made-of-the-same-substring%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      8 Answers
      8






      active

      oldest

      votes








      8 Answers
      8






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      36














      You can do it by a capturing group and backreference. Just check it's the repetition of the first captured value.






      function check(str) {
      return /^(.+)1+$/.test(str)
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      In the above RegExp:





      1. ^ and $ stands for start and end anchors to predict the position.


      2. (.+) captures any pattern and captures the value(except n).


      3. 1 is backreference of first captured value and 1+ would check for repetition of captured value.


      Regex explanation here



      For RegExp debugging use: https://regex101.com/r/pqlAuP/1/debugger





      Performance : https://jsperf.com/regex-and-loop/1






      share|improve this answer


























      • Can you explain to us what this line is doing return /^(.+)1+$/.test(str)

        – Thanveer Shah
        19 hours ago






      • 15





        Also what is the complexity of this solution? I'm not absolutely sure but it doesn't seem to be much faster than the one the OP has.

        – Leron
        19 hours ago






      • 3





        @PranavCBalan I'm not good at algorithms, that's why I write in the comments section. However I have several things to mention - the OP already has a working solution so he is asking for one that will give him better performance and you haven't explained how your solution will outperform his. Shorter doesn't mean faster. Also, from the link you gave: If you use normal (TCS:no backreference, concatenation,alternation,Kleene star) regexp and regexp is already compiled then it's O(n). but as you wrote you are using backreference so is it still O(n)?

        – Leron
        18 hours ago











      • @PranavCBalan Its showing both are fastest.

        – Maheer Ali
        18 hours ago






      • 1





        You can use [sS] instead of . if you need to match newline characters in the same way as other characters. The dot character doesn't match on newlines; the alternative searches for all white-space and non-whitespace characters, which means that newlines are included in the match. (Note that this is faster than the more intuitive (.|[rn]).) However, if the string definitely doesn't contain newlines, then the simple . will be fastest. Note this will be a lot simpler if the dotall flag is implemented.

        – HappyDog
        16 hours ago


















      36














      You can do it by a capturing group and backreference. Just check it's the repetition of the first captured value.






      function check(str) {
      return /^(.+)1+$/.test(str)
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      In the above RegExp:





      1. ^ and $ stands for start and end anchors to predict the position.


      2. (.+) captures any pattern and captures the value(except n).


      3. 1 is backreference of first captured value and 1+ would check for repetition of captured value.


      Regex explanation here



      For RegExp debugging use: https://regex101.com/r/pqlAuP/1/debugger





      Performance : https://jsperf.com/regex-and-loop/1






      share|improve this answer


























      • Can you explain to us what this line is doing return /^(.+)1+$/.test(str)

        – Thanveer Shah
        19 hours ago






      • 15





        Also what is the complexity of this solution? I'm not absolutely sure but it doesn't seem to be much faster than the one the OP has.

        – Leron
        19 hours ago






      • 3





        @PranavCBalan I'm not good at algorithms, that's why I write in the comments section. However I have several things to mention - the OP already has a working solution so he is asking for one that will give him better performance and you haven't explained how your solution will outperform his. Shorter doesn't mean faster. Also, from the link you gave: If you use normal (TCS:no backreference, concatenation,alternation,Kleene star) regexp and regexp is already compiled then it's O(n). but as you wrote you are using backreference so is it still O(n)?

        – Leron
        18 hours ago











      • @PranavCBalan Its showing both are fastest.

        – Maheer Ali
        18 hours ago






      • 1





        You can use [sS] instead of . if you need to match newline characters in the same way as other characters. The dot character doesn't match on newlines; the alternative searches for all white-space and non-whitespace characters, which means that newlines are included in the match. (Note that this is faster than the more intuitive (.|[rn]).) However, if the string definitely doesn't contain newlines, then the simple . will be fastest. Note this will be a lot simpler if the dotall flag is implemented.

        – HappyDog
        16 hours ago
















      36












      36








      36







      You can do it by a capturing group and backreference. Just check it's the repetition of the first captured value.






      function check(str) {
      return /^(.+)1+$/.test(str)
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      In the above RegExp:





      1. ^ and $ stands for start and end anchors to predict the position.


      2. (.+) captures any pattern and captures the value(except n).


      3. 1 is backreference of first captured value and 1+ would check for repetition of captured value.


      Regex explanation here



      For RegExp debugging use: https://regex101.com/r/pqlAuP/1/debugger





      Performance : https://jsperf.com/regex-and-loop/1






      share|improve this answer















      You can do it by a capturing group and backreference. Just check it's the repetition of the first captured value.






      function check(str) {
      return /^(.+)1+$/.test(str)
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      In the above RegExp:





      1. ^ and $ stands for start and end anchors to predict the position.


      2. (.+) captures any pattern and captures the value(except n).


      3. 1 is backreference of first captured value and 1+ would check for repetition of captured value.


      Regex explanation here



      For RegExp debugging use: https://regex101.com/r/pqlAuP/1/debugger





      Performance : https://jsperf.com/regex-and-loop/1






      function check(str) {
      return /^(.+)1+$/.test(str)
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      function check(str) {
      return /^(.+)1+$/.test(str)
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 7 hours ago









      John Kugelman

      250k54407460




      250k54407460










      answered 19 hours ago









      Pranav C BalanPranav C Balan

      91.1k1492119




      91.1k1492119













      • Can you explain to us what this line is doing return /^(.+)1+$/.test(str)

        – Thanveer Shah
        19 hours ago






      • 15





        Also what is the complexity of this solution? I'm not absolutely sure but it doesn't seem to be much faster than the one the OP has.

        – Leron
        19 hours ago






      • 3





        @PranavCBalan I'm not good at algorithms, that's why I write in the comments section. However I have several things to mention - the OP already has a working solution so he is asking for one that will give him better performance and you haven't explained how your solution will outperform his. Shorter doesn't mean faster. Also, from the link you gave: If you use normal (TCS:no backreference, concatenation,alternation,Kleene star) regexp and regexp is already compiled then it's O(n). but as you wrote you are using backreference so is it still O(n)?

        – Leron
        18 hours ago











      • @PranavCBalan Its showing both are fastest.

        – Maheer Ali
        18 hours ago






      • 1





        You can use [sS] instead of . if you need to match newline characters in the same way as other characters. The dot character doesn't match on newlines; the alternative searches for all white-space and non-whitespace characters, which means that newlines are included in the match. (Note that this is faster than the more intuitive (.|[rn]).) However, if the string definitely doesn't contain newlines, then the simple . will be fastest. Note this will be a lot simpler if the dotall flag is implemented.

        – HappyDog
        16 hours ago





















      • Can you explain to us what this line is doing return /^(.+)1+$/.test(str)

        – Thanveer Shah
        19 hours ago






      • 15





        Also what is the complexity of this solution? I'm not absolutely sure but it doesn't seem to be much faster than the one the OP has.

        – Leron
        19 hours ago






      • 3





        @PranavCBalan I'm not good at algorithms, that's why I write in the comments section. However I have several things to mention - the OP already has a working solution so he is asking for one that will give him better performance and you haven't explained how your solution will outperform his. Shorter doesn't mean faster. Also, from the link you gave: If you use normal (TCS:no backreference, concatenation,alternation,Kleene star) regexp and regexp is already compiled then it's O(n). but as you wrote you are using backreference so is it still O(n)?

        – Leron
        18 hours ago











      • @PranavCBalan Its showing both are fastest.

        – Maheer Ali
        18 hours ago






      • 1





        You can use [sS] instead of . if you need to match newline characters in the same way as other characters. The dot character doesn't match on newlines; the alternative searches for all white-space and non-whitespace characters, which means that newlines are included in the match. (Note that this is faster than the more intuitive (.|[rn]).) However, if the string definitely doesn't contain newlines, then the simple . will be fastest. Note this will be a lot simpler if the dotall flag is implemented.

        – HappyDog
        16 hours ago



















      Can you explain to us what this line is doing return /^(.+)1+$/.test(str)

      – Thanveer Shah
      19 hours ago





      Can you explain to us what this line is doing return /^(.+)1+$/.test(str)

      – Thanveer Shah
      19 hours ago




      15




      15





      Also what is the complexity of this solution? I'm not absolutely sure but it doesn't seem to be much faster than the one the OP has.

      – Leron
      19 hours ago





      Also what is the complexity of this solution? I'm not absolutely sure but it doesn't seem to be much faster than the one the OP has.

      – Leron
      19 hours ago




      3




      3





      @PranavCBalan I'm not good at algorithms, that's why I write in the comments section. However I have several things to mention - the OP already has a working solution so he is asking for one that will give him better performance and you haven't explained how your solution will outperform his. Shorter doesn't mean faster. Also, from the link you gave: If you use normal (TCS:no backreference, concatenation,alternation,Kleene star) regexp and regexp is already compiled then it's O(n). but as you wrote you are using backreference so is it still O(n)?

      – Leron
      18 hours ago





      @PranavCBalan I'm not good at algorithms, that's why I write in the comments section. However I have several things to mention - the OP already has a working solution so he is asking for one that will give him better performance and you haven't explained how your solution will outperform his. Shorter doesn't mean faster. Also, from the link you gave: If you use normal (TCS:no backreference, concatenation,alternation,Kleene star) regexp and regexp is already compiled then it's O(n). but as you wrote you are using backreference so is it still O(n)?

      – Leron
      18 hours ago













      @PranavCBalan Its showing both are fastest.

      – Maheer Ali
      18 hours ago





      @PranavCBalan Its showing both are fastest.

      – Maheer Ali
      18 hours ago




      1




      1





      You can use [sS] instead of . if you need to match newline characters in the same way as other characters. The dot character doesn't match on newlines; the alternative searches for all white-space and non-whitespace characters, which means that newlines are included in the match. (Note that this is faster than the more intuitive (.|[rn]).) However, if the string definitely doesn't contain newlines, then the simple . will be fastest. Note this will be a lot simpler if the dotall flag is implemented.

      – HappyDog
      16 hours ago







      You can use [sS] instead of . if you need to match newline characters in the same way as other characters. The dot character doesn't match on newlines; the alternative searches for all white-space and non-whitespace characters, which means that newlines are included in the match. (Note that this is faster than the more intuitive (.|[rn]).) However, if the string definitely doesn't contain newlines, then the simple . will be fastest. Note this will be a lot simpler if the dotall flag is implemented.

      – HappyDog
      16 hours ago















      19














      Perhaps the fastest algorithmic approach is building a Z-function in linear time:




      The Z-function for this string is an array of length n where the i-th
      element is equal to the greatest number of characters starting from
      the position i that coincide with the first characters of s.



      In other words, z[i] is the length of the longest common prefix
      between s and the suffix of s starting at i.




      C++ implementation for reference:



      vector<int> z_function(string s) {
      int n = (int) s.length();
      vector<int> z(n);
      for (int i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = min (r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];
      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z;
      }


      JavaScript implementation:






      function z_function(s) {
      var n = s.length;
      var z = Array(n).fill(0);
      var i, l, r;
      for (i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = Math.min(r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];

      //we can check condition and return here
      // if (z[i] + i === n && n % i === 0) return true;

      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z.some((zi, i) => (i + zi) === n && n % i === 0);
      }
      console.log(z_function("abacabacabac"));
      console.log(z_function("abcab"));





      Then you need to check indexes i that divide n. If you find such i that i+z[i]=n then the string s can be compressed to the length i and you can return true.



      For example, for



      string s= 'abacabacabac'  with length n=12`


      z-array is



      (0, 0, 1, 0, 8, 0, 1, 0, 4, 0, 1, 0)


      and we can find that for



      i=4
      i+z[i] = 4 + 8 = 12 = n
      and
      n % i = 12 % 4 = 0`


      so s might be represented as substring of length 4 repeated three times.






      share|improve this answer





















      • 2





        return z.some((zi, i) => (i + zi) === n && n % i === 0)

        – Pranav C Balan
        12 hours ago








      • 2





        Thanks for adding JavaScript stuff to Salman A and Pranav C Balan

        – MBo
        7 hours ago






      • 1





        Alternate approach by avoiding an additional iteration const check = (s) => { let n = s.length; let z = Array(n).fill(0); for (let i = 1, l = 0, r = 0; i < n; ++i) { if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]); while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i]; // check condition here and return if (z[i] + i === n && n % i === 0) return true; if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; } // or return false return false; }

        – Pranav C Balan
        7 hours ago


















      19














      Perhaps the fastest algorithmic approach is building a Z-function in linear time:




      The Z-function for this string is an array of length n where the i-th
      element is equal to the greatest number of characters starting from
      the position i that coincide with the first characters of s.



      In other words, z[i] is the length of the longest common prefix
      between s and the suffix of s starting at i.




      C++ implementation for reference:



      vector<int> z_function(string s) {
      int n = (int) s.length();
      vector<int> z(n);
      for (int i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = min (r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];
      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z;
      }


      JavaScript implementation:






      function z_function(s) {
      var n = s.length;
      var z = Array(n).fill(0);
      var i, l, r;
      for (i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = Math.min(r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];

      //we can check condition and return here
      // if (z[i] + i === n && n % i === 0) return true;

      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z.some((zi, i) => (i + zi) === n && n % i === 0);
      }
      console.log(z_function("abacabacabac"));
      console.log(z_function("abcab"));





      Then you need to check indexes i that divide n. If you find such i that i+z[i]=n then the string s can be compressed to the length i and you can return true.



      For example, for



      string s= 'abacabacabac'  with length n=12`


      z-array is



      (0, 0, 1, 0, 8, 0, 1, 0, 4, 0, 1, 0)


      and we can find that for



      i=4
      i+z[i] = 4 + 8 = 12 = n
      and
      n % i = 12 % 4 = 0`


      so s might be represented as substring of length 4 repeated three times.






      share|improve this answer





















      • 2





        return z.some((zi, i) => (i + zi) === n && n % i === 0)

        – Pranav C Balan
        12 hours ago








      • 2





        Thanks for adding JavaScript stuff to Salman A and Pranav C Balan

        – MBo
        7 hours ago






      • 1





        Alternate approach by avoiding an additional iteration const check = (s) => { let n = s.length; let z = Array(n).fill(0); for (let i = 1, l = 0, r = 0; i < n; ++i) { if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]); while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i]; // check condition here and return if (z[i] + i === n && n % i === 0) return true; if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; } // or return false return false; }

        – Pranav C Balan
        7 hours ago
















      19












      19








      19







      Perhaps the fastest algorithmic approach is building a Z-function in linear time:




      The Z-function for this string is an array of length n where the i-th
      element is equal to the greatest number of characters starting from
      the position i that coincide with the first characters of s.



      In other words, z[i] is the length of the longest common prefix
      between s and the suffix of s starting at i.




      C++ implementation for reference:



      vector<int> z_function(string s) {
      int n = (int) s.length();
      vector<int> z(n);
      for (int i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = min (r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];
      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z;
      }


      JavaScript implementation:






      function z_function(s) {
      var n = s.length;
      var z = Array(n).fill(0);
      var i, l, r;
      for (i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = Math.min(r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];

      //we can check condition and return here
      // if (z[i] + i === n && n % i === 0) return true;

      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z.some((zi, i) => (i + zi) === n && n % i === 0);
      }
      console.log(z_function("abacabacabac"));
      console.log(z_function("abcab"));





      Then you need to check indexes i that divide n. If you find such i that i+z[i]=n then the string s can be compressed to the length i and you can return true.



      For example, for



      string s= 'abacabacabac'  with length n=12`


      z-array is



      (0, 0, 1, 0, 8, 0, 1, 0, 4, 0, 1, 0)


      and we can find that for



      i=4
      i+z[i] = 4 + 8 = 12 = n
      and
      n % i = 12 % 4 = 0`


      so s might be represented as substring of length 4 repeated three times.






      share|improve this answer















      Perhaps the fastest algorithmic approach is building a Z-function in linear time:




      The Z-function for this string is an array of length n where the i-th
      element is equal to the greatest number of characters starting from
      the position i that coincide with the first characters of s.



      In other words, z[i] is the length of the longest common prefix
      between s and the suffix of s starting at i.




      C++ implementation for reference:



      vector<int> z_function(string s) {
      int n = (int) s.length();
      vector<int> z(n);
      for (int i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = min (r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];
      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z;
      }


      JavaScript implementation:






      function z_function(s) {
      var n = s.length;
      var z = Array(n).fill(0);
      var i, l, r;
      for (i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = Math.min(r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];

      //we can check condition and return here
      // if (z[i] + i === n && n % i === 0) return true;

      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z.some((zi, i) => (i + zi) === n && n % i === 0);
      }
      console.log(z_function("abacabacabac"));
      console.log(z_function("abcab"));





      Then you need to check indexes i that divide n. If you find such i that i+z[i]=n then the string s can be compressed to the length i and you can return true.



      For example, for



      string s= 'abacabacabac'  with length n=12`


      z-array is



      (0, 0, 1, 0, 8, 0, 1, 0, 4, 0, 1, 0)


      and we can find that for



      i=4
      i+z[i] = 4 + 8 = 12 = n
      and
      n % i = 12 % 4 = 0`


      so s might be represented as substring of length 4 repeated three times.






      function z_function(s) {
      var n = s.length;
      var z = Array(n).fill(0);
      var i, l, r;
      for (i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = Math.min(r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];

      //we can check condition and return here
      // if (z[i] + i === n && n % i === 0) return true;

      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z.some((zi, i) => (i + zi) === n && n % i === 0);
      }
      console.log(z_function("abacabacabac"));
      console.log(z_function("abcab"));





      function z_function(s) {
      var n = s.length;
      var z = Array(n).fill(0);
      var i, l, r;
      for (i = 1, l = 0, r = 0; i < n; ++i) {
      if (i <= r)
      z[i] = Math.min(r - i + 1, z[i - l]);
      while (i + z[i] < n && s[z[i]] == s[i + z[i]])
      ++z[i];

      //we can check condition and return here
      // if (z[i] + i === n && n % i === 0) return true;

      if (i + z[i] - 1 > r)
      l = i, r = i + z[i] - 1;
      }
      return z.some((zi, i) => (i + zi) === n && n % i === 0);
      }
      console.log(z_function("abacabacabac"));
      console.log(z_function("abcab"));






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 6 hours ago

























      answered 18 hours ago









      MBoMBo

      50.8k23153




      50.8k23153








      • 2





        return z.some((zi, i) => (i + zi) === n && n % i === 0)

        – Pranav C Balan
        12 hours ago








      • 2





        Thanks for adding JavaScript stuff to Salman A and Pranav C Balan

        – MBo
        7 hours ago






      • 1





        Alternate approach by avoiding an additional iteration const check = (s) => { let n = s.length; let z = Array(n).fill(0); for (let i = 1, l = 0, r = 0; i < n; ++i) { if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]); while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i]; // check condition here and return if (z[i] + i === n && n % i === 0) return true; if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; } // or return false return false; }

        – Pranav C Balan
        7 hours ago
















      • 2





        return z.some((zi, i) => (i + zi) === n && n % i === 0)

        – Pranav C Balan
        12 hours ago








      • 2





        Thanks for adding JavaScript stuff to Salman A and Pranav C Balan

        – MBo
        7 hours ago






      • 1





        Alternate approach by avoiding an additional iteration const check = (s) => { let n = s.length; let z = Array(n).fill(0); for (let i = 1, l = 0, r = 0; i < n; ++i) { if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]); while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i]; // check condition here and return if (z[i] + i === n && n % i === 0) return true; if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; } // or return false return false; }

        – Pranav C Balan
        7 hours ago










      2




      2





      return z.some((zi, i) => (i + zi) === n && n % i === 0)

      – Pranav C Balan
      12 hours ago







      return z.some((zi, i) => (i + zi) === n && n % i === 0)

      – Pranav C Balan
      12 hours ago






      2




      2





      Thanks for adding JavaScript stuff to Salman A and Pranav C Balan

      – MBo
      7 hours ago





      Thanks for adding JavaScript stuff to Salman A and Pranav C Balan

      – MBo
      7 hours ago




      1




      1





      Alternate approach by avoiding an additional iteration const check = (s) => { let n = s.length; let z = Array(n).fill(0); for (let i = 1, l = 0, r = 0; i < n; ++i) { if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]); while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i]; // check condition here and return if (z[i] + i === n && n % i === 0) return true; if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; } // or return false return false; }

      – Pranav C Balan
      7 hours ago







      Alternate approach by avoiding an additional iteration const check = (s) => { let n = s.length; let z = Array(n).fill(0); for (let i = 1, l = 0, r = 0; i < n; ++i) { if (i <= r) z[i] = Math.min(r - i + 1, z[i - l]); while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i]; // check condition here and return if (z[i] + i === n && n % i === 0) return true; if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1; } // or return false return false; }

      – Pranav C Balan
      7 hours ago













      5














      Assume the string S has length N and is made of duplicates of the substring s, then the length of s divides N. For example, if S has length 15, then the substring has length 1, 3, or 5.



      Let S be made of (p*q) copies of s. Then S is also made of p copies of (s, repeated q times). We have therefore two cases: If N is prime or 1, then S can only be made of copies of the substring of length 1. If N is composite, then we only need to check substrings s of length N / p for primes p dividing the length of S.



      So determine N = the length of S, then find all its prime factors in time O (sqrt (N)). If there is only one factor N, check if S is the same string repeated N times, otherwise for each prime factor p, check if S consists of p repeations of the first N / p characters.






      share|improve this answer
























      • I haven't checked the other solutions, but this seems very fast. You can leave out the "If there is only one factor N, check ..., otherwise" part for simplicity, as this is not a special case. Would be nice to see a Javascript implementation that can be run in jsPerf next to the other implementations.

        – user42723
        8 hours ago











      • I've now implemented this in my answer

        – user42723
        4 mins ago
















      5














      Assume the string S has length N and is made of duplicates of the substring s, then the length of s divides N. For example, if S has length 15, then the substring has length 1, 3, or 5.



      Let S be made of (p*q) copies of s. Then S is also made of p copies of (s, repeated q times). We have therefore two cases: If N is prime or 1, then S can only be made of copies of the substring of length 1. If N is composite, then we only need to check substrings s of length N / p for primes p dividing the length of S.



      So determine N = the length of S, then find all its prime factors in time O (sqrt (N)). If there is only one factor N, check if S is the same string repeated N times, otherwise for each prime factor p, check if S consists of p repeations of the first N / p characters.






      share|improve this answer
























      • I haven't checked the other solutions, but this seems very fast. You can leave out the "If there is only one factor N, check ..., otherwise" part for simplicity, as this is not a special case. Would be nice to see a Javascript implementation that can be run in jsPerf next to the other implementations.

        – user42723
        8 hours ago











      • I've now implemented this in my answer

        – user42723
        4 mins ago














      5












      5








      5







      Assume the string S has length N and is made of duplicates of the substring s, then the length of s divides N. For example, if S has length 15, then the substring has length 1, 3, or 5.



      Let S be made of (p*q) copies of s. Then S is also made of p copies of (s, repeated q times). We have therefore two cases: If N is prime or 1, then S can only be made of copies of the substring of length 1. If N is composite, then we only need to check substrings s of length N / p for primes p dividing the length of S.



      So determine N = the length of S, then find all its prime factors in time O (sqrt (N)). If there is only one factor N, check if S is the same string repeated N times, otherwise for each prime factor p, check if S consists of p repeations of the first N / p characters.






      share|improve this answer













      Assume the string S has length N and is made of duplicates of the substring s, then the length of s divides N. For example, if S has length 15, then the substring has length 1, 3, or 5.



      Let S be made of (p*q) copies of s. Then S is also made of p copies of (s, repeated q times). We have therefore two cases: If N is prime or 1, then S can only be made of copies of the substring of length 1. If N is composite, then we only need to check substrings s of length N / p for primes p dividing the length of S.



      So determine N = the length of S, then find all its prime factors in time O (sqrt (N)). If there is only one factor N, check if S is the same string repeated N times, otherwise for each prime factor p, check if S consists of p repeations of the first N / p characters.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 10 hours ago









      gnasher729gnasher729

      42.2k44979




      42.2k44979













      • I haven't checked the other solutions, but this seems very fast. You can leave out the "If there is only one factor N, check ..., otherwise" part for simplicity, as this is not a special case. Would be nice to see a Javascript implementation that can be run in jsPerf next to the other implementations.

        – user42723
        8 hours ago











      • I've now implemented this in my answer

        – user42723
        4 mins ago



















      • I haven't checked the other solutions, but this seems very fast. You can leave out the "If there is only one factor N, check ..., otherwise" part for simplicity, as this is not a special case. Would be nice to see a Javascript implementation that can be run in jsPerf next to the other implementations.

        – user42723
        8 hours ago











      • I've now implemented this in my answer

        – user42723
        4 mins ago

















      I haven't checked the other solutions, but this seems very fast. You can leave out the "If there is only one factor N, check ..., otherwise" part for simplicity, as this is not a special case. Would be nice to see a Javascript implementation that can be run in jsPerf next to the other implementations.

      – user42723
      8 hours ago





      I haven't checked the other solutions, but this seems very fast. You can leave out the "If there is only one factor N, check ..., otherwise" part for simplicity, as this is not a special case. Would be nice to see a Javascript implementation that can be run in jsPerf next to the other implementations.

      – user42723
      8 hours ago













      I've now implemented this in my answer

      – user42723
      4 mins ago





      I've now implemented this in my answer

      – user42723
      4 mins ago











      2














      I think a recursive function might be very fast as well. The first observation is that the maximum repeated pattern length is half as long as the total string. And we could just test all possible repeated pattern lengths: 1, 2, 3, ..., str.length/2



      The recursive function isRepeating(p,str) tests if this pattern is repeated in str.



      If str is longer than the pattern, the recursion requires the first part (same length as p) to be a repetition as well as the remainder of str. So str is effectively broken up into pieces of length p.length.



      If the tested pattern and str are of equal size, recursion ends here, successfully.



      If the length is different (happens for "aba" and pattern "ab") or if the pieces are different, then false is returned, propagating up the recursion.






      function check(str)
      {
      if( str.length==1 ) return true; // trivial case
      for( var i=1;i<=str.length/2;i++ ) { // biggest possible repeated pattern has length/2 characters

      if( str.length%i!=0 ) continue; // pattern of size i doesn't fit

      var p = str.substring(0, i);
      if( isRepeating(p,str) ) return true;
      }
      return false;
      }


      function isRepeating(p, str)
      {
      if( str.length>p.length ) { // maybe more than 2 occurences

      var left = str.substring(0,p.length);
      var right = str.substring(p.length, str.length);
      return left===p && isRepeating(p,right);
      }
      return str===p;
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      Performance: https://jsperf.com/reegx-and-loop/13






      share|improve this answer





















      • 1





        Would it be faster to check if( str===p.repeat(str.length/i) ) return true; instead of using a recursive function?

        – Chronocidal
        10 hours ago






      • 1





        Don't put console.logs in jsperf tests, prepare the functions inside the globals section, also prepare the test strings in the globals section (sorry, cannot edit the jsperf)

        – Salman A
        9 hours ago











      • @Salman - good point. I just modified the jsperf from my predecessor (Pranav C), first time I used jsperf, cool tool.

        – Axel Podehl
        9 hours ago











      • @SalmanA : updated : jsperf.com/regex-and-loop/1 ... thanks for the info... even I'm not familiar with it(Jsperf) ... thanks for the information

        – Pranav C Balan
        9 hours ago











      • Hi Salman, thanks a lot for jsperf.com/reegx-and-loop/10 - yes, that new perf test makes much more sense. The setup of functions should go into the preparation code.

        – Axel Podehl
        9 hours ago
















      2














      I think a recursive function might be very fast as well. The first observation is that the maximum repeated pattern length is half as long as the total string. And we could just test all possible repeated pattern lengths: 1, 2, 3, ..., str.length/2



      The recursive function isRepeating(p,str) tests if this pattern is repeated in str.



      If str is longer than the pattern, the recursion requires the first part (same length as p) to be a repetition as well as the remainder of str. So str is effectively broken up into pieces of length p.length.



      If the tested pattern and str are of equal size, recursion ends here, successfully.



      If the length is different (happens for "aba" and pattern "ab") or if the pieces are different, then false is returned, propagating up the recursion.






      function check(str)
      {
      if( str.length==1 ) return true; // trivial case
      for( var i=1;i<=str.length/2;i++ ) { // biggest possible repeated pattern has length/2 characters

      if( str.length%i!=0 ) continue; // pattern of size i doesn't fit

      var p = str.substring(0, i);
      if( isRepeating(p,str) ) return true;
      }
      return false;
      }


      function isRepeating(p, str)
      {
      if( str.length>p.length ) { // maybe more than 2 occurences

      var left = str.substring(0,p.length);
      var right = str.substring(p.length, str.length);
      return left===p && isRepeating(p,right);
      }
      return str===p;
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      Performance: https://jsperf.com/reegx-and-loop/13






      share|improve this answer





















      • 1





        Would it be faster to check if( str===p.repeat(str.length/i) ) return true; instead of using a recursive function?

        – Chronocidal
        10 hours ago






      • 1





        Don't put console.logs in jsperf tests, prepare the functions inside the globals section, also prepare the test strings in the globals section (sorry, cannot edit the jsperf)

        – Salman A
        9 hours ago











      • @Salman - good point. I just modified the jsperf from my predecessor (Pranav C), first time I used jsperf, cool tool.

        – Axel Podehl
        9 hours ago











      • @SalmanA : updated : jsperf.com/regex-and-loop/1 ... thanks for the info... even I'm not familiar with it(Jsperf) ... thanks for the information

        – Pranav C Balan
        9 hours ago











      • Hi Salman, thanks a lot for jsperf.com/reegx-and-loop/10 - yes, that new perf test makes much more sense. The setup of functions should go into the preparation code.

        – Axel Podehl
        9 hours ago














      2












      2








      2







      I think a recursive function might be very fast as well. The first observation is that the maximum repeated pattern length is half as long as the total string. And we could just test all possible repeated pattern lengths: 1, 2, 3, ..., str.length/2



      The recursive function isRepeating(p,str) tests if this pattern is repeated in str.



      If str is longer than the pattern, the recursion requires the first part (same length as p) to be a repetition as well as the remainder of str. So str is effectively broken up into pieces of length p.length.



      If the tested pattern and str are of equal size, recursion ends here, successfully.



      If the length is different (happens for "aba" and pattern "ab") or if the pieces are different, then false is returned, propagating up the recursion.






      function check(str)
      {
      if( str.length==1 ) return true; // trivial case
      for( var i=1;i<=str.length/2;i++ ) { // biggest possible repeated pattern has length/2 characters

      if( str.length%i!=0 ) continue; // pattern of size i doesn't fit

      var p = str.substring(0, i);
      if( isRepeating(p,str) ) return true;
      }
      return false;
      }


      function isRepeating(p, str)
      {
      if( str.length>p.length ) { // maybe more than 2 occurences

      var left = str.substring(0,p.length);
      var right = str.substring(p.length, str.length);
      return left===p && isRepeating(p,right);
      }
      return str===p;
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      Performance: https://jsperf.com/reegx-and-loop/13






      share|improve this answer















      I think a recursive function might be very fast as well. The first observation is that the maximum repeated pattern length is half as long as the total string. And we could just test all possible repeated pattern lengths: 1, 2, 3, ..., str.length/2



      The recursive function isRepeating(p,str) tests if this pattern is repeated in str.



      If str is longer than the pattern, the recursion requires the first part (same length as p) to be a repetition as well as the remainder of str. So str is effectively broken up into pieces of length p.length.



      If the tested pattern and str are of equal size, recursion ends here, successfully.



      If the length is different (happens for "aba" and pattern "ab") or if the pieces are different, then false is returned, propagating up the recursion.






      function check(str)
      {
      if( str.length==1 ) return true; // trivial case
      for( var i=1;i<=str.length/2;i++ ) { // biggest possible repeated pattern has length/2 characters

      if( str.length%i!=0 ) continue; // pattern of size i doesn't fit

      var p = str.substring(0, i);
      if( isRepeating(p,str) ) return true;
      }
      return false;
      }


      function isRepeating(p, str)
      {
      if( str.length>p.length ) { // maybe more than 2 occurences

      var left = str.substring(0,p.length);
      var right = str.substring(p.length, str.length);
      return left===p && isRepeating(p,right);
      }
      return str===p;
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      Performance: https://jsperf.com/reegx-and-loop/13






      function check(str)
      {
      if( str.length==1 ) return true; // trivial case
      for( var i=1;i<=str.length/2;i++ ) { // biggest possible repeated pattern has length/2 characters

      if( str.length%i!=0 ) continue; // pattern of size i doesn't fit

      var p = str.substring(0, i);
      if( isRepeating(p,str) ) return true;
      }
      return false;
      }


      function isRepeating(p, str)
      {
      if( str.length>p.length ) { // maybe more than 2 occurences

      var left = str.substring(0,p.length);
      var right = str.substring(p.length, str.length);
      return left===p && isRepeating(p,right);
      }
      return str===p;
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false





      function check(str)
      {
      if( str.length==1 ) return true; // trivial case
      for( var i=1;i<=str.length/2;i++ ) { // biggest possible repeated pattern has length/2 characters

      if( str.length%i!=0 ) continue; // pattern of size i doesn't fit

      var p = str.substring(0, i);
      if( isRepeating(p,str) ) return true;
      }
      return false;
      }


      function isRepeating(p, str)
      {
      if( str.length>p.length ) { // maybe more than 2 occurences

      var left = str.substring(0,p.length);
      var right = str.substring(p.length, str.length);
      return left===p && isRepeating(p,right);
      }
      return str===p;
      }

      console.log(check('aa')) //true
      console.log(check('aaa')) //true
      console.log(check('abcabcabc')) //true
      console.log(check('aba')) //false
      console.log(check('ababa')) //false






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 8 hours ago

























      answered 13 hours ago









      Axel PodehlAxel Podehl

      2,0101617




      2,0101617








      • 1





        Would it be faster to check if( str===p.repeat(str.length/i) ) return true; instead of using a recursive function?

        – Chronocidal
        10 hours ago






      • 1





        Don't put console.logs in jsperf tests, prepare the functions inside the globals section, also prepare the test strings in the globals section (sorry, cannot edit the jsperf)

        – Salman A
        9 hours ago











      • @Salman - good point. I just modified the jsperf from my predecessor (Pranav C), first time I used jsperf, cool tool.

        – Axel Podehl
        9 hours ago











      • @SalmanA : updated : jsperf.com/regex-and-loop/1 ... thanks for the info... even I'm not familiar with it(Jsperf) ... thanks for the information

        – Pranav C Balan
        9 hours ago











      • Hi Salman, thanks a lot for jsperf.com/reegx-and-loop/10 - yes, that new perf test makes much more sense. The setup of functions should go into the preparation code.

        – Axel Podehl
        9 hours ago














      • 1





        Would it be faster to check if( str===p.repeat(str.length/i) ) return true; instead of using a recursive function?

        – Chronocidal
        10 hours ago






      • 1





        Don't put console.logs in jsperf tests, prepare the functions inside the globals section, also prepare the test strings in the globals section (sorry, cannot edit the jsperf)

        – Salman A
        9 hours ago











      • @Salman - good point. I just modified the jsperf from my predecessor (Pranav C), first time I used jsperf, cool tool.

        – Axel Podehl
        9 hours ago











      • @SalmanA : updated : jsperf.com/regex-and-loop/1 ... thanks for the info... even I'm not familiar with it(Jsperf) ... thanks for the information

        – Pranav C Balan
        9 hours ago











      • Hi Salman, thanks a lot for jsperf.com/reegx-and-loop/10 - yes, that new perf test makes much more sense. The setup of functions should go into the preparation code.

        – Axel Podehl
        9 hours ago








      1




      1





      Would it be faster to check if( str===p.repeat(str.length/i) ) return true; instead of using a recursive function?

      – Chronocidal
      10 hours ago





      Would it be faster to check if( str===p.repeat(str.length/i) ) return true; instead of using a recursive function?

      – Chronocidal
      10 hours ago




      1




      1





      Don't put console.logs in jsperf tests, prepare the functions inside the globals section, also prepare the test strings in the globals section (sorry, cannot edit the jsperf)

      – Salman A
      9 hours ago





      Don't put console.logs in jsperf tests, prepare the functions inside the globals section, also prepare the test strings in the globals section (sorry, cannot edit the jsperf)

      – Salman A
      9 hours ago













      @Salman - good point. I just modified the jsperf from my predecessor (Pranav C), first time I used jsperf, cool tool.

      – Axel Podehl
      9 hours ago





      @Salman - good point. I just modified the jsperf from my predecessor (Pranav C), first time I used jsperf, cool tool.

      – Axel Podehl
      9 hours ago













      @SalmanA : updated : jsperf.com/regex-and-loop/1 ... thanks for the info... even I'm not familiar with it(Jsperf) ... thanks for the information

      – Pranav C Balan
      9 hours ago





      @SalmanA : updated : jsperf.com/regex-and-loop/1 ... thanks for the info... even I'm not familiar with it(Jsperf) ... thanks for the information

      – Pranav C Balan
      9 hours ago













      Hi Salman, thanks a lot for jsperf.com/reegx-and-loop/10 - yes, that new perf test makes much more sense. The setup of functions should go into the preparation code.

      – Axel Podehl
      9 hours ago





      Hi Salman, thanks a lot for jsperf.com/reegx-and-loop/10 - yes, that new perf test makes much more sense. The setup of functions should go into the preparation code.

      – Axel Podehl
      9 hours ago











      1














      My approach is similar to gnasher729, in that it uses the potential length of the substring as the main focus, but it is less math-y and process intensive:



      L: Length of original string



      S: Potential lengths of valid sub-strings



      Loop S from (integer part of) L/2 to 1. If L/S is an integer check your original string against the fist S characters of the original string repeated L/S times.



      The reason for looping from L/2 backwards and not from 1 onwards is to get the largest possible substring. If you want the smallest possible substring loop from 1 to L/2. Example: "abababab" has both "ab" and "abab" as possible substrings. Which of the two would be faster if you only care about a true/false result depends on the type of strings/substrings this will be applied to.






      share|improve this answer






























        1














        My approach is similar to gnasher729, in that it uses the potential length of the substring as the main focus, but it is less math-y and process intensive:



        L: Length of original string



        S: Potential lengths of valid sub-strings



        Loop S from (integer part of) L/2 to 1. If L/S is an integer check your original string against the fist S characters of the original string repeated L/S times.



        The reason for looping from L/2 backwards and not from 1 onwards is to get the largest possible substring. If you want the smallest possible substring loop from 1 to L/2. Example: "abababab" has both "ab" and "abab" as possible substrings. Which of the two would be faster if you only care about a true/false result depends on the type of strings/substrings this will be applied to.






        share|improve this answer




























          1












          1








          1







          My approach is similar to gnasher729, in that it uses the potential length of the substring as the main focus, but it is less math-y and process intensive:



          L: Length of original string



          S: Potential lengths of valid sub-strings



          Loop S from (integer part of) L/2 to 1. If L/S is an integer check your original string against the fist S characters of the original string repeated L/S times.



          The reason for looping from L/2 backwards and not from 1 onwards is to get the largest possible substring. If you want the smallest possible substring loop from 1 to L/2. Example: "abababab" has both "ab" and "abab" as possible substrings. Which of the two would be faster if you only care about a true/false result depends on the type of strings/substrings this will be applied to.






          share|improve this answer















          My approach is similar to gnasher729, in that it uses the potential length of the substring as the main focus, but it is less math-y and process intensive:



          L: Length of original string



          S: Potential lengths of valid sub-strings



          Loop S from (integer part of) L/2 to 1. If L/S is an integer check your original string against the fist S characters of the original string repeated L/S times.



          The reason for looping from L/2 backwards and not from 1 onwards is to get the largest possible substring. If you want the smallest possible substring loop from 1 to L/2. Example: "abababab" has both "ab" and "abab" as possible substrings. Which of the two would be faster if you only care about a true/false result depends on the type of strings/substrings this will be applied to.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 6 hours ago

























          answered 6 hours ago









          SunKnight0SunKnight0

          2,503167




          2,503167























              0














              I read the answer of gnasher729 and implemented it.
              The idea is that if there are any repetitions, then there must be (also) a prime number of repetitions. If you want performance, this is what you want.



              function* primeFactors (n) {
              for (var k = 2; k*k <= n; k++) {
              if (n % k == 0) {
              yield k
              do {n /= k} while (n % k == 0)
              }
              }
              if (n > 1) yield n
              }

              function check (str) {
              var n = str.length
              primeloop:
              for (p of primeFactors(n)) {
              var l = n/p
              var s = str.substring(0, l)
              for (var j=1; j<p; j++) {
              if (s != str.substring(l*j, l*(j+1))) continue primeloop
              }
              return true
              }
              return false
              }


              I've updated the jsPerf page that contains the algorithms used on this page.






              share|improve this answer




























                0














                I read the answer of gnasher729 and implemented it.
                The idea is that if there are any repetitions, then there must be (also) a prime number of repetitions. If you want performance, this is what you want.



                function* primeFactors (n) {
                for (var k = 2; k*k <= n; k++) {
                if (n % k == 0) {
                yield k
                do {n /= k} while (n % k == 0)
                }
                }
                if (n > 1) yield n
                }

                function check (str) {
                var n = str.length
                primeloop:
                for (p of primeFactors(n)) {
                var l = n/p
                var s = str.substring(0, l)
                for (var j=1; j<p; j++) {
                if (s != str.substring(l*j, l*(j+1))) continue primeloop
                }
                return true
                }
                return false
                }


                I've updated the jsPerf page that contains the algorithms used on this page.






                share|improve this answer


























                  0












                  0








                  0







                  I read the answer of gnasher729 and implemented it.
                  The idea is that if there are any repetitions, then there must be (also) a prime number of repetitions. If you want performance, this is what you want.



                  function* primeFactors (n) {
                  for (var k = 2; k*k <= n; k++) {
                  if (n % k == 0) {
                  yield k
                  do {n /= k} while (n % k == 0)
                  }
                  }
                  if (n > 1) yield n
                  }

                  function check (str) {
                  var n = str.length
                  primeloop:
                  for (p of primeFactors(n)) {
                  var l = n/p
                  var s = str.substring(0, l)
                  for (var j=1; j<p; j++) {
                  if (s != str.substring(l*j, l*(j+1))) continue primeloop
                  }
                  return true
                  }
                  return false
                  }


                  I've updated the jsPerf page that contains the algorithms used on this page.






                  share|improve this answer













                  I read the answer of gnasher729 and implemented it.
                  The idea is that if there are any repetitions, then there must be (also) a prime number of repetitions. If you want performance, this is what you want.



                  function* primeFactors (n) {
                  for (var k = 2; k*k <= n; k++) {
                  if (n % k == 0) {
                  yield k
                  do {n /= k} while (n % k == 0)
                  }
                  }
                  if (n > 1) yield n
                  }

                  function check (str) {
                  var n = str.length
                  primeloop:
                  for (p of primeFactors(n)) {
                  var l = n/p
                  var s = str.substring(0, l)
                  for (var j=1; j<p; j++) {
                  if (s != str.substring(l*j, l*(j+1))) continue primeloop
                  }
                  return true
                  }
                  return false
                  }


                  I've updated the jsPerf page that contains the algorithms used on this page.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 10 mins ago









                  user42723user42723

                  1304




                  1304























                      -2














                      I'm not familiar with JavaScript, so I don't know how fast this is going to be, but here is a linear time solution (assuming reasonable builtin implementation) using only builtins. I'll describe the algorithm in pseudocode.



                      function check(str) {
                      t = str + str;
                      find all overlapping occurrences of str in t;
                      for each occurrence at position i
                      if (i > 0 && i < str.length && str.length % i == 0)
                      return true; // str is a repetition of its first i characters
                      return false;
                      }


                      The idea is similar to MBo's answer. For each i that divides the length, str is a repetition of its first i characters if and only if it remains the same after shifting for i characters.



                      It comes to my mind that such a builtin may be unavailable or inefficient. In this case, it is always possible to implement the KMP algorithm manually, which takes about the same amount of code as the algorithm in MBo's answer.






                      share|improve this answer


























                      • The OP wants to know whether repetition exists. The second line of (the body of) your function counts the number of repetitions - that's the bit that needs to be explained. E.g. "abcabcabc" has 3 repetitions of "abc", but how did your second line work out whether it had any repetitions?

                        – Lawrence
                        13 hours ago











                      • @Lawrence I don't understand your question. This algorithm is based on the idea that the string is a repetition of its substring if and only if for some divisor of its length i, s[0:n-i] == s[i:n], or equivalently, s == s[i:n] + s[0:i]. Why does the second line need to work out whether it had any repetitions?

                        – infmagic2047
                        57 mins ago
















                      -2














                      I'm not familiar with JavaScript, so I don't know how fast this is going to be, but here is a linear time solution (assuming reasonable builtin implementation) using only builtins. I'll describe the algorithm in pseudocode.



                      function check(str) {
                      t = str + str;
                      find all overlapping occurrences of str in t;
                      for each occurrence at position i
                      if (i > 0 && i < str.length && str.length % i == 0)
                      return true; // str is a repetition of its first i characters
                      return false;
                      }


                      The idea is similar to MBo's answer. For each i that divides the length, str is a repetition of its first i characters if and only if it remains the same after shifting for i characters.



                      It comes to my mind that such a builtin may be unavailable or inefficient. In this case, it is always possible to implement the KMP algorithm manually, which takes about the same amount of code as the algorithm in MBo's answer.






                      share|improve this answer


























                      • The OP wants to know whether repetition exists. The second line of (the body of) your function counts the number of repetitions - that's the bit that needs to be explained. E.g. "abcabcabc" has 3 repetitions of "abc", but how did your second line work out whether it had any repetitions?

                        – Lawrence
                        13 hours ago











                      • @Lawrence I don't understand your question. This algorithm is based on the idea that the string is a repetition of its substring if and only if for some divisor of its length i, s[0:n-i] == s[i:n], or equivalently, s == s[i:n] + s[0:i]. Why does the second line need to work out whether it had any repetitions?

                        – infmagic2047
                        57 mins ago














                      -2












                      -2








                      -2







                      I'm not familiar with JavaScript, so I don't know how fast this is going to be, but here is a linear time solution (assuming reasonable builtin implementation) using only builtins. I'll describe the algorithm in pseudocode.



                      function check(str) {
                      t = str + str;
                      find all overlapping occurrences of str in t;
                      for each occurrence at position i
                      if (i > 0 && i < str.length && str.length % i == 0)
                      return true; // str is a repetition of its first i characters
                      return false;
                      }


                      The idea is similar to MBo's answer. For each i that divides the length, str is a repetition of its first i characters if and only if it remains the same after shifting for i characters.



                      It comes to my mind that such a builtin may be unavailable or inefficient. In this case, it is always possible to implement the KMP algorithm manually, which takes about the same amount of code as the algorithm in MBo's answer.






                      share|improve this answer















                      I'm not familiar with JavaScript, so I don't know how fast this is going to be, but here is a linear time solution (assuming reasonable builtin implementation) using only builtins. I'll describe the algorithm in pseudocode.



                      function check(str) {
                      t = str + str;
                      find all overlapping occurrences of str in t;
                      for each occurrence at position i
                      if (i > 0 && i < str.length && str.length % i == 0)
                      return true; // str is a repetition of its first i characters
                      return false;
                      }


                      The idea is similar to MBo's answer. For each i that divides the length, str is a repetition of its first i characters if and only if it remains the same after shifting for i characters.



                      It comes to my mind that such a builtin may be unavailable or inefficient. In this case, it is always possible to implement the KMP algorithm manually, which takes about the same amount of code as the algorithm in MBo's answer.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 14 hours ago









                      Peter Mortensen

                      14k1987114




                      14k1987114










                      answered 17 hours ago









                      infmagic2047infmagic2047

                      1347




                      1347













                      • The OP wants to know whether repetition exists. The second line of (the body of) your function counts the number of repetitions - that's the bit that needs to be explained. E.g. "abcabcabc" has 3 repetitions of "abc", but how did your second line work out whether it had any repetitions?

                        – Lawrence
                        13 hours ago











                      • @Lawrence I don't understand your question. This algorithm is based on the idea that the string is a repetition of its substring if and only if for some divisor of its length i, s[0:n-i] == s[i:n], or equivalently, s == s[i:n] + s[0:i]. Why does the second line need to work out whether it had any repetitions?

                        – infmagic2047
                        57 mins ago



















                      • The OP wants to know whether repetition exists. The second line of (the body of) your function counts the number of repetitions - that's the bit that needs to be explained. E.g. "abcabcabc" has 3 repetitions of "abc", but how did your second line work out whether it had any repetitions?

                        – Lawrence
                        13 hours ago











                      • @Lawrence I don't understand your question. This algorithm is based on the idea that the string is a repetition of its substring if and only if for some divisor of its length i, s[0:n-i] == s[i:n], or equivalently, s == s[i:n] + s[0:i]. Why does the second line need to work out whether it had any repetitions?

                        – infmagic2047
                        57 mins ago

















                      The OP wants to know whether repetition exists. The second line of (the body of) your function counts the number of repetitions - that's the bit that needs to be explained. E.g. "abcabcabc" has 3 repetitions of "abc", but how did your second line work out whether it had any repetitions?

                      – Lawrence
                      13 hours ago





                      The OP wants to know whether repetition exists. The second line of (the body of) your function counts the number of repetitions - that's the bit that needs to be explained. E.g. "abcabcabc" has 3 repetitions of "abc", but how did your second line work out whether it had any repetitions?

                      – Lawrence
                      13 hours ago













                      @Lawrence I don't understand your question. This algorithm is based on the idea that the string is a repetition of its substring if and only if for some divisor of its length i, s[0:n-i] == s[i:n], or equivalently, s == s[i:n] + s[0:i]. Why does the second line need to work out whether it had any repetitions?

                      – infmagic2047
                      57 mins ago





                      @Lawrence I don't understand your question. This algorithm is based on the idea that the string is a repetition of its substring if and only if for some divisor of its length i, s[0:n-i] == s[i:n], or equivalently, s == s[i:n] + s[0:i]. Why does the second line need to work out whether it had any repetitions?

                      – infmagic2047
                      57 mins ago











                      -7














                      One of the simple ideas is to replace the string with the substring of "" and if any text exist then it is false, else it is true.






                      'ababababa'.replace(/ab/gi,'')
                      "a" // return false
                      'abababab'.replace(/ab/gi,'')
                      ""// return true








                      share|improve this answer





















                      • 4





                        What about abcabcabc or unicornunicorn?

                        – adiga
                        19 hours ago











                      • yes, for abc or unicorn wouldn't user will check with /abc/ or /unicorn/ , sorry if i am missing your context

                        – Vinod kumar G
                        17 hours ago






                      • 1





                        The question could be clearer, but what it's asking for is a way of deciding whether the string is completely made up of 2 or more repetitions of any other string. It is not searching for a specific substring.

                        – HappyDog
                        16 hours ago






                      • 1





                        I've added some clarification to the question, which should make it clearer now.

                        – HappyDog
                        15 hours ago











                      • @Vinod if you are already going to use regex you should anchor your match and use test. No reason to modify the string just to validate some condition.

                        – Marie
                        13 hours ago
















                      -7














                      One of the simple ideas is to replace the string with the substring of "" and if any text exist then it is false, else it is true.






                      'ababababa'.replace(/ab/gi,'')
                      "a" // return false
                      'abababab'.replace(/ab/gi,'')
                      ""// return true








                      share|improve this answer





















                      • 4





                        What about abcabcabc or unicornunicorn?

                        – adiga
                        19 hours ago











                      • yes, for abc or unicorn wouldn't user will check with /abc/ or /unicorn/ , sorry if i am missing your context

                        – Vinod kumar G
                        17 hours ago






                      • 1





                        The question could be clearer, but what it's asking for is a way of deciding whether the string is completely made up of 2 or more repetitions of any other string. It is not searching for a specific substring.

                        – HappyDog
                        16 hours ago






                      • 1





                        I've added some clarification to the question, which should make it clearer now.

                        – HappyDog
                        15 hours ago











                      • @Vinod if you are already going to use regex you should anchor your match and use test. No reason to modify the string just to validate some condition.

                        – Marie
                        13 hours ago














                      -7












                      -7








                      -7







                      One of the simple ideas is to replace the string with the substring of "" and if any text exist then it is false, else it is true.






                      'ababababa'.replace(/ab/gi,'')
                      "a" // return false
                      'abababab'.replace(/ab/gi,'')
                      ""// return true








                      share|improve this answer















                      One of the simple ideas is to replace the string with the substring of "" and if any text exist then it is false, else it is true.






                      'ababababa'.replace(/ab/gi,'')
                      "a" // return false
                      'abababab'.replace(/ab/gi,'')
                      ""// return true








                      'ababababa'.replace(/ab/gi,'')
                      "a" // return false
                      'abababab'.replace(/ab/gi,'')
                      ""// return true





                      'ababababa'.replace(/ab/gi,'')
                      "a" // return false
                      'abababab'.replace(/ab/gi,'')
                      ""// return true






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 14 hours ago









                      Peter Mortensen

                      14k1987114




                      14k1987114










                      answered 19 hours ago









                      Vinod kumar GVinod kumar G

                      423412




                      423412








                      • 4





                        What about abcabcabc or unicornunicorn?

                        – adiga
                        19 hours ago











                      • yes, for abc or unicorn wouldn't user will check with /abc/ or /unicorn/ , sorry if i am missing your context

                        – Vinod kumar G
                        17 hours ago






                      • 1





                        The question could be clearer, but what it's asking for is a way of deciding whether the string is completely made up of 2 or more repetitions of any other string. It is not searching for a specific substring.

                        – HappyDog
                        16 hours ago






                      • 1





                        I've added some clarification to the question, which should make it clearer now.

                        – HappyDog
                        15 hours ago











                      • @Vinod if you are already going to use regex you should anchor your match and use test. No reason to modify the string just to validate some condition.

                        – Marie
                        13 hours ago














                      • 4





                        What about abcabcabc or unicornunicorn?

                        – adiga
                        19 hours ago











                      • yes, for abc or unicorn wouldn't user will check with /abc/ or /unicorn/ , sorry if i am missing your context

                        – Vinod kumar G
                        17 hours ago






                      • 1





                        The question could be clearer, but what it's asking for is a way of deciding whether the string is completely made up of 2 or more repetitions of any other string. It is not searching for a specific substring.

                        – HappyDog
                        16 hours ago






                      • 1





                        I've added some clarification to the question, which should make it clearer now.

                        – HappyDog
                        15 hours ago











                      • @Vinod if you are already going to use regex you should anchor your match and use test. No reason to modify the string just to validate some condition.

                        – Marie
                        13 hours ago








                      4




                      4





                      What about abcabcabc or unicornunicorn?

                      – adiga
                      19 hours ago





                      What about abcabcabc or unicornunicorn?

                      – adiga
                      19 hours ago













                      yes, for abc or unicorn wouldn't user will check with /abc/ or /unicorn/ , sorry if i am missing your context

                      – Vinod kumar G
                      17 hours ago





                      yes, for abc or unicorn wouldn't user will check with /abc/ or /unicorn/ , sorry if i am missing your context

                      – Vinod kumar G
                      17 hours ago




                      1




                      1





                      The question could be clearer, but what it's asking for is a way of deciding whether the string is completely made up of 2 or more repetitions of any other string. It is not searching for a specific substring.

                      – HappyDog
                      16 hours ago





                      The question could be clearer, but what it's asking for is a way of deciding whether the string is completely made up of 2 or more repetitions of any other string. It is not searching for a specific substring.

                      – HappyDog
                      16 hours ago




                      1




                      1





                      I've added some clarification to the question, which should make it clearer now.

                      – HappyDog
                      15 hours ago





                      I've added some clarification to the question, which should make it clearer now.

                      – HappyDog
                      15 hours ago













                      @Vinod if you are already going to use regex you should anchor your match and use test. No reason to modify the string just to validate some condition.

                      – Marie
                      13 hours ago





                      @Vinod if you are already going to use regex you should anchor your match and use test. No reason to modify the string just to validate some condition.

                      – Marie
                      13 hours ago


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55823298%2fhow-do-i-check-if-a-string-is-entirely-made-of-the-same-substring%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      VNC viewer RFB protocol error: bad desktop size 0x0I Cannot Type the Key 'd' (lowercase) in VNC Viewer...

                      Tribunal Administrativo e Fiscal de Mirandela Referências Menu de...

                      looking for continuous Screen Capture for retroactivly reproducing errors, timeback machineRolling desktop...