Varying string variable in an if condition - c

I used this program to take input mm as the month of the year and print out the name of the month:
#include <stdio.h>
#include <string.h>
int main(){
int mm;
printf("input month ");
scanf("%d", &mm);
char mname[9];
if (mm == 1) {mname = "January";}
if (mm == 2) {mname = "February";}
if (mm == 3) {mname = "March";}
if (mm == 4) {mname = "April";}
if (mm == 5) {mname = "May";}
if (mm == 6) {mname = "June";}
if (mm == 7) {mname = "July";}
if (mm == 8) {mname = "August";}
if (mm == 9) {mname = "September";}
if (mm == 10) {mname = "October";}
if (mm == 11) {mname = "November";}
if (mm == 12) {mname = "December";}
printf("%d is month %s", mm, mname);
return 0;
}
it gave an error assignment to expression with array type. please help

Taking Michael Walz two great comments and adding them as an answer:
#include <stdio.h>
#include <string.h>
void main(int argc, char** argv)
{
int mm = 0;
printf("Please enter a month number [1-12]:\n");
scanf("%d", &mm);
static const char* months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
if (mm >= 1 && mm <= 12)
{
printf("%d is month %s", mm, months[mm - 1]);
}
else
{
printf("You have entered an invalid month number %d\n", mm);
}
}
Validity check was done (mentioned in above comments).
Hope it helps.
Cheers,
Guy.

Basically there are two different ways to think about / talk about strings:
An array of characters, terminated by a '\0' character. (This is the formal definition of a string in C.)
As a pointer to character, or char *, pointing at the first of a sequence (an array) of characters, terminated by a '\0' character.
So you can declare an array, and copy a string into it:
char arraystring[10];
strcpy(arraystring, "Hello");
Or you can declare an array, and give it an initial value when you declare it:
char arraystring2[] = "world!";
Or you can declare a pointer, and make it point to a string:
char *pointerstring;
pointerstring = "Goodbye";
Or you can declare a pointer, and give it an initial value:
char *pointerstring2 = "for now";
It's worth knowing how these "look" in memory:
+---+---+---+---+---+---+---+---+---+---+
arraystring: | H | e | l | l | o |\0 |\0 |\0 |\0 |\0 |
+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+
arraystring2: | w | o | r | l | d | ! |\0 |
+---+---+---+---+---+---+---+
+---------------+
pointerstring: | * |
+-------|-------+
| +---+---+---+---+---+---+---+---+
+---------> | G | o | o | d | b | y | e |\0 |
+---+---+---+---+---+---+---+---+
+---------------+
pointerstring2: | * |
+-------|-------+
| +---+---+---+---+---+---+---+---+
+---------> | f | o | r | | n | o | w |\0 |
+---+---+---+---+---+---+---+---+
Now, the thing is, you can't assign arrays in C. You can assign pointers. You can also make use of the special rule (the "equivalence between arrays and pointers") by which when you use an array in an expression, what you get is a pointer to the array's first element.
So if you want to assign one string-as-pointer to another string-as-pointer, that works:
pointerstring = pointerstring2;
If you try to assign one string-as-array to another string-as-array, that doesn't work
arraystring = arraystring2; /* WRONG -- compiler complains, attempt to assign array */
If you want to copy one string-as-array to another, you have to call strcpy (and of course you have to worry about overflow):
strcpy(arraystring, arraystring2);
You can also assign a string-as-array to a string-as-pointer:
pointerstring = arraystring;
This works because the compiler treats it exactly as if you'd written
pointerstring = &arraystring[0];
Finally, if you attempt to assign a string-as-pointer to a string-as-array, this doesn't work, again because you can't assign to an array:
arraystring = pointerstring; /* WRONG */
Again, you could call strcpy instead, as long as you're sure the string will fit:
strcpy(arraystring, pointerstring); /* but worry about overflow */
In your original code, mname was a string-as-array, so you can't assign to it. You have two choices:
Use strcpy to copy strings into it:
if (mm == 1) { strcpy(mname, "January"); }
Declare mname as p a pointer instead:
char *mname;
...
if (mm == 1) { mname = "January"; }
Addendum: For completeness, I should mention one more set of points.
When you initialize a pointer to point to a string, in either of these ways:
char *pointerstring = "Goodbye";
char * pointerstring2;
pointerstring2 = "for now";
those strings "Goodbye" and "for now" are read-only. You can't modify them. So if you try to do something like
strcpy(pointerstring, pointerstring2); /* WRONG: overwriting constant string */
it won't work, because you're trying to copy the second string into the memory where the first string is stored, but that memory isn't writable.
So when you're using arrays, you can't use assignment, you must use strcpy; but when you're using pointers, you can use assignment, and you probably can't call strcpy.

Basically array types are constant pointers, so when you try to assign a new value to pointer mname the compiler detects an error.
You could use function strcpy as in the following example to solve the problem:
if (mm == 1) {
strcpy(mname, "January");
}

Related

Can this be solve only by loops?

Since I am kind of a beginner to programming, I try to programm as much as possible. I saw a illustration on how an integer array saves its bytes. I tried to make this illustration in c, just for the learning and I wondered if there is a better way than i did it.
The code below works on its own and if there is a more efficient way, it still should have the same output.
I know that my code would be very challenging if the array would have 100 integers.
#include <stdio.h>
int main() {
int lange = 3;
int c[lange];
c[0] = 3;
c[1] = 1;
c[2] = 2;
for (int i = 0; i < lange*4; i++) {
printf("| ");
if (i == 0) {
printf("%d", c[0]);
}
else if (i==4) {
printf("%d", c[1]);
}
else if (i==8){
printf("%d",c[2]);
}
}
return 0;
}
This could be done more compactly by changing the if-tree in the loop to be just
if ((i % 4) == 0)
printf("%d", c[i/4]);
or you could print every byte by doing something like
printf("%d", (c[i/4] >> (i%4 * 8)) & 0xff);
You should use a #define C_LEN 3 and use that instead of your magic number 3. You loop prints out a '|' in every iteration so your loop body cannot really be simplified other than:
if(!(i % 4)) printf("%d", c[i/4]);
If you only want to print something for 0, 4 and 8 then you iterate by 4 instead of 1, or better iterate by 1 (see below).
The output is:
| 3| | | | 1| | | | 2| | |
If that is all you want, I would write a single print statement:
printf("| %d| | | | %d| | | | %d| | | ", c[0], c[1], c[2]);
Or if you want a loop on group at a time and just iterate to 3 times:
for (int i = 0; i < C_LEN; i++) {
printf("| %d| | | ", c[i]);
}
It seems that you are trying to print the elements of the array, based on multiple of 4.
You can generalize your program by creating an array of any size and have your for loop like this:
int index = 0;
for (int i = 0; i < lange*4; i++)
{
printf("| ");
if (i == 0)
{
index = 0;
}
else if((i % 4) == 0)
{
index = i/4;
}
else
{
continue;
}
printf("%d",c[index]);
}

Print elements from array of matrices in C?

I am trying to print each char of an array of matrices for a brick breaker game (the full message would be YOU LOSE). I am new to C and I don't feel too confident about using pointers; I feel that that may be the source of my problem. To try to solve the problem, I've read plenty of online guides on how to deal with strings in C; but the fact that I'm dealing with an array of arrays of arrays of chars makes this task quite a bit harder. If you know how to print matrices of strings (in yet another array) in C, or you have a better solution, please let me know!
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define LETTER_WIDTH 13
#define LETTER_HEIGHT 6
char Y[LETTER_HEIGHT][LETTER_WIDTH] = {
"___ __\n",
"\\ \\__ / /\n",
"\\ \\ / /\n",
"| | |\n",
"| | |\n",
"|__|__|\n"};
char O[LETTER_HEIGHT][LETTER_WIDTH] = {
" _______ \n",
" / __ \\\n",
"| | | |\n",
"| |__| |\n",
" \\_______/\n"};
char *SENTENCE[2][LETTER_HEIGHT][LETTER_WIDTH] = {*Y, *O};
void printLetter(char letter[LETTER_HEIGHT][LETTER_WIDTH]) {
for (int i = 0; i < LETTER_HEIGHT; i++) {
for (int j = 0; j < LETTER_WIDTH; j++) {
printf("%c", letter[i][j]);
}
}
}
void printSentence() {
for (int i = 0; i < 2; i++) {
char letter[LETTER_HEIGHT][LETTER_WIDTH];
strcpy(*letter, **SENTENCE[i]);
printLetter(letter);
sleep(1);
}
}
int main() {
printSentence();
return 0;
}
Firstly this should be better
char* Y[LETTER_HEIGHT] = {
"___ __\n",
"\\ \\__ / /\n",
"\\ \\ / /\n",
"| | |\n",
"| | |\n",
"|__|__|\n"};
char* O[LETTER_HEIGHT] = {
" _______ \n",
" / __ \\\n",
"| | | |\n",
"| |__| |\n",
" \\_______/\n"};
Now these are arrays of size 6 (you must add one line because O now have height of 5) containing pointers to arrays of chars. Next
char** SENTENCE[2] = {Y, O};
You did some really weird things with this line before, this defines SENTENCE as 2 element array of pointers to array of pointers to char arrays (which are Y and O).
Next
void printLetter(char** letter) {
for (int i = 0; i < LETTER_HEIGHT; i++) {
printf("%s", letter[i]);
}
}
This function takes pointer to array of pointers to char arrays. Then goes 6 times and print each array as string. Next
void printSentence() {
for (int i = 0; i < 2; i++) {
printLetter(SENTENCE[i]);
sleep(1);
}
}
Here you can use simple for loop to pass to printLetter each pointer to array of pointers to char arrays (which are these letters) from SENTENCE.
or you have a better solution, please let me know!
Yes, there is a much simpler and, I would argue, better solution, it's to place the SENTENCE in a single 2D array and print it in one go, even if you are to use ncurses, this makes your job easier.
Note that with ncurses you can reposition the cursor so you can print each letter separately in one line, you wouldn't need to join them together like you try to do in SENTENCE.
#define LETTER_WIDTH 100
#define LETTER_HEIGHT 6
char SENTENCE[LETTER_HEIGHT][LETTER_WIDTH] = {
"__ __ ______ \n",
"\\ \\ / / / __ \\\n",
" \\ \\/ / | | | |\n",
" | | | | | |\n",
" | | | |__| |\n",
" |__| \\______/\n"};
void printSentence()
{
for (int i = 0; i < 6; i++)
{
printf("%s", SENTENCE[i]);
}
}
Output:
__ __ ______
\ \ / / / __ \
\ \/ / | | | |
| | | | | |
| | | |__| |
|__| \______/

Marking Stack Variables for Garbage Collection

I'm trying to learn how to implement a simple mark-and-sweep garbage collection algorithm. I'm learning by looking at the tgc library.
I'm figuring out how to iterate through the stack to mark reachable heap allocated variables. This is done in the following lines in tgc.c:
static void tgc_mark_stack(tgc_t *gc) {
void *stk, *bot, *top, *p;
bot = gc->bottom; top = &stk;
if (bot == top) { return; }
if (bot < top) {
for (p = top; p >= bot; p = ((char*)p) - sizeof(void*)) {
tgc_mark_ptr(gc, *((void**)p));
}
}
if (bot > top) {
for (p = top; p <= bot; p = ((char*)p) + sizeof(void*)) {
tgc_mark_ptr(gc, *((void**)p));
}
}
}
How does p = ((char*)p) - sizeof(void*) and p = ((char*)p) + sizeof(void*) not cause pointer p to overshoot or undershoot pointing at the correct address for the stack variable? As an example, my intuition is that we can possibly have something like this which wouldn't yield the correct heap address of char *:
void *bottom -> ----------- High address/bottom of stack
| |
| char a | 1 byte
| |
-----------
| |
(char*)p + sizeof(void*) -> | char *str | 8 bytes
| |
-----------
| |
| int x | 4 bytes
| |
void *p = void *top -> -----------
| |
| void *stk | 8 bytes
| |
----------- Low address/top of stock
But I've tested this out, and the loop seems to work regardless of the stack layout. I figured that we'd do something like p = ((char*)p) - sizeof(char) which also seems to work but is a bit slower. Why does the method used in the above code work?

How to print pointer to pointers

I am a newbie trying to understand the working of double pointers and to print double pointers. I increment m by one but it's always pointing to the last value pointed by p. Can someone please help me?
#include <stdio.h>
int main () {
/* an array with 5 elements */
double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p;
double **m;
int i;
p = balance;
m = &p;
/* output each array element's value */
printf( "Array values using pointer\n");
for ( i = 0; i < 5; i++ ) {
printf("*(p + %d) : %f\n", i, *(p+i) );
}
for ( i = 0; i < 5; i++ ) {
printf("**(m + %d) : %f\n", i, *m);
m++;
}
printf( "Array values using balance as address\n");
for ( i = 0; i < 5; i++ ) {
printf("*(balance + %d) : %f\n", i, *(balance + i) );
}
return 0;
}
Your array balance is like this
+--------+--------+--------+--------+--------+
| 1000.0 | 2.0 | 3.4 | 17.0 | 50.0 |
+--------+--------+--------+--------+--------+
After you initialize p and m it is like this:
+---+
| m |
+---+
|
v
+---+
| p |
+---+
|
V
+--------+--------+--------+--------+--------+
| 1000.0 | 2.0 | 3.4 | 17.0 | 50.0 |
+--------+--------+--------+--------+--------+
That is, m points to the location of p, and p points to the first value of the balance array.
When you dereference m (i.e. when you do *m) you get the value of where m is pointing. This value is another pointer (p) that you need to dereference to get to an element in the array.
Using m the second element in balance (i.e. balance[1]) is (*m)[1].
Now if you increment m (with e.g. m++) it will point to the next element of p:
+---+
| m |
+---+
|
v
+---+
| p |
+---+
|
V
+--------+--------+--------+--------+--------+
| 1000.0 | 2.0 | 3.4 | 17.0 | 50.0 |
+--------+--------+--------+--------+--------+
You can clearly see the problem here: It no longer points to p and you can no longer us it to access the balance array. Dereferencing m after the increment will lead to undefined behavior.
Also, for any pointer or array, the array-indexing expression and the pointer arithmetic expression are equal. So for balance, the expression balance[i] is equal to *(balance + i). There is really no difference between them.
So after you execute
double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p;
double **m;
p = balance;
m = &p;
the following are all true:
m == &p // double **
*m == p == &balance[0] // double *
**m == *p == balance[0] // double
(*m)[i] == p[i] == balance[i] // double
Remember that the expression a[i] is defined as *(a + i); given the address a, offset i elements (not bytes1) from that address and dereference the result.
This means that *p is equivalent to *(p + 0), which is equivalent to p[0]. Thus, you can use p[i] in place of balance[i]. Since *m == p, you can also use (*m)[i] in place of p[i]. The parentheses are necessary - unary * has lower precedence than postfix [], so *m[i] would be parsed as *(m[i]), which is not what you want here.
You can increment p directly to "walk" through the balance array:
p = balance; // p == &balance[0];
for ( i = 0; i < 5; i++ )
printf( "%f\n", *p++ );
Each time through the loop, p is incremented to point to the next element of balance.
You can do something similar with the expression (*m):
p = balance; // p == &balance[0]
m = &p;
for ( i = 0; i < 5; i++ )
printf( "%f\n", (*m)++ );
Again, the parentheses around *m are necessary; since postfix ++ has higher precedence than unary *, the expression *m++ would be parsed as *(m++), which is not what we want. We don't want to change the value of m, we want to change the value of what m points to, which in this case is p.
Now, suppose we leave p out of the picture completely; can we do something like:
double balance[5] = { ... };
double **m;
*m = balance;
No. In this example, m is an invalid pointer; it hasn't been initialized to point anywhere meaningful, so *m will invoke undefined behavior (which can include, but is not limited to, a segfault). m has to point to an object of type double * before you can dereference it. There has to be a middleman like p in order for that scheme to work.
Pointer arithmetic always takes the size of the pointed-to type into account - if a points to an object of type T, then a + 1 yields the address of the next object of type T, which may be more than 1 byte away from the current address.

How to find repeating sequence of characters in a given array?

My problem is to find the repeating sequence of characters in the given array. simply, to identify the pattern in which the characters are appearing.
.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
1: | J | A | M | E | S | O | N | J | A | M | E | S | O | N |
'---'---'---'---'---'---'---'---'---'---'---'---'---'---'
.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
2: | R | O | N | R | O | N | R | O | N | R | O | N | R | O | N |
'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'
.---.---.---.---.---.---.---.---.---.---.---.---.
3: | S | H | A | M | I | L | S | H | A | M | I | L |
'---'---'---'---'---'---'---'---'---'---'---'---'
.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
4: | C | A | R | P | E | N | T | E | R | C | A | R | P | E | N | T | E | R |
'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'
Example
Given the previous data, the result should be:
"JAMESON"
"RON"
"SHAMIL"
"CARPENTER"
Question
How to deal with this problem efficiently?
Tongue-in-cheek O(NlogN) solution
Perform an FFT on your string (treating characters as numeric values). Every peak in the resulting graph corresponds to a substring periodicity.
For your examples, my first approach would be to
get the first character of the array (for your last example, that would be C)
get the index of the next appearance of that character in the array (e.g. 9)
if it is found, search for the next appearance of the substring between the two appearances of the character (in this case CARPENTER)
if it is found, you're done (and the result is this substring).
Of course, this works only for a very limited subset of possible arrays, where the same word is repeated over and over again, starting from the beginning, without stray characters in between, and its first character is not repeated within the word. But all your examples fall into this category - and I prefer the simplest solution which could possibly work :-)
If the repeated word contains the first character multiple times (e.g. CACTUS), the algorithm can be extended to look for subsequent occurrences of that character too, not only the first one (so that it finds the whole repeated word, not only a substring of it).
Note that this extended algorithm would give a different result for your second example, namely RONRON instead of RON.
In Python, you can leverage regexes thus:
def recurrence(text):
import re
for i in range(1, len(text)/2 + 1):
m = re.match(r'^(.{%d})\1+$'%i, text)
if m: return m.group(1)
recurrence('abcabc') # Returns 'abc'
I'm not sure how this would translate to Java or C. (That's one of the reasons I like Python, I guess. :-)
First write a method that find repeating substring sub in the container string as below.
boolean findSubRepeating(String sub, String container);
Now keep calling this method with increasing substring in the container, first try 1 character substring, then 2 characters, etc going upto container.length/2.
Pseudocode
len = str.length
for (i in 1..len) {
if (len%i==0) {
if (str==str.substr(0,i).repeat(len/i)) {
return str.substr(0,i)
}
}
}
Note: For brevity, I'm inventing a "repeat" method for strings, which isn't actually part of Java's string; "abc".repeat(2)="abcabc"
Using C++:
//Splits the string into the fragments of given size
//Returns the set of of splitted strings avaialble
set<string> split(string s, int frag)
{
set<string> uni;
int len = s.length();
for(int i = 0; i < len; i+= frag)
{
uni.insert(s.substr(i, frag));
}
return uni;
}
int main()
{
string out;
string s = "carpentercarpenter";
int len = s.length();
//Optimistic approach..hope there are only 2 repeated strings
//If that fails, then try to break the strings with lesser number of
//characters
for(int i = len/2; i>1;--i)
{
set<string> uni = split(s,i);
if(uni.size() == 1)
{
out = *uni.begin();
break;
}
}
cout<<out;
return 0;
}
The first idea that comes to my mind is trying all repeating sequences of lengths that divide length(S) = N. There is a maximum of N/2 such lengths, so this results in a O(N^2) algorithm.
But i'm sure it can be improved...
Here is a more general solution to the problem, that will find repeating subsequences within an sequence (of anything), where the subsequences do not have to start at the beginning, nor immediately follow each other.
given an sequence b[0..n], containing the data in question, and a threshold t being the minimum subsequence length to find,
l_max = 0, i_max = 0, j_max = 0;
for (i=0; i<n-(t*2);i++) {
for (j=i+t;j<n-t; j++) {
l=0;
while (i+l<j && j+l<n && b[i+l] == b[j+l])
l++;
if (l>t) {
print "Sequence of length " + l + " found at " + i + " and " + j);
if (l>l_max) {
l_max = l;
i_max = i;
j_max = j;
}
}
}
}
if (l_max>t) {
print "longest common subsequence found at " + i_max + " and " + j_max + " (" + l_max + " long)";
}
Basically:
Start at the beginning of the data, iterate until within 2*t of the end (no possible way to have two distinct subsequences of length t in less than 2*t of space!)
For the second subsequence, start at least t bytes beyond where the first sequence begins.
Then, reset the length of the discovered subsequence to 0, and check to see if you have a common character at i+l and j+l. As long as you do, increment l.
When you no longer have a common character, you have reached the end of your common subsequence.
If the subsequence is longer than your threshold, print the result.
Just figured this out myself and wrote some code for this (written in C#) with a lot of comments. Hope this helps someone:
// Check whether the string contains a repeating sequence.
public static bool ContainsRepeatingSequence(string str)
{
if (string.IsNullOrEmpty(str)) return false;
for (int i=0; i<str.Length; i++)
{
// Every iteration, cut down the string from i to the end.
string toCheck = str.Substring(i);
// Set N equal to half the length of the substring. At most, we have to compare half the string to half the string. If the string length is odd, the last character will not be checked against, but it will be checked in the next iteration.
int N = toCheck.Length / 2;
// Check strings of all lengths from 1 to N against the subsequent string of length 1 to N.
for (int j=1; j<=N; j++)
{
// Check from beginning to j-1, compare against j to j+j.
if (toCheck.Substring(0, j) == toCheck.Substring(j, j)) return true;
}
}
return false;
}
Feel free to ask any questions if it's unclear why it works.
and here is a concrete working example:
/* find greatest repeated substring */
char *fgrs(const char *s,size_t *l)
{
char *r=0,*a=s;
*l=0;
while( *a )
{
char *e=strrchr(a+1,*a);
if( !e )
break;
do {
size_t t=1;
for(;&a[t]!=e && a[t]==e[t];++t);
if( t>*l )
*l=t,r=a;
while( --e!=a && *e!=*a );
} while( e!=a && *e==*a );
++a;
}
return r;
}
size_t t;
const char *p;
p=fgrs("BARBARABARBARABARBARA",&t);
while( t-- ) putchar(*p++);
p=fgrs("0123456789",&t);
while( t-- ) putchar(*p++);
p=fgrs("1111",&t);
while( t-- ) putchar(*p++);
p=fgrs("11111",&t);
while( t-- ) putchar(*p++);
Not sure how you define "efficiently". For easy/fast implementation you could do this in Java:
private static String findSequence(String text) {
Pattern pattern = Pattern.compile("(.+?)\\1+");
Matcher matcher = pattern.matcher(text);
return matcher.matches() ? matcher.group(1) : null;
}
it tries to find the shortest string (.+?) that must be repeated at least once (\1+) to match the entire input text.
This is a solution I came up with using the queue, it passed all the test cases of a similar problem in codeforces. Problem No is 745A.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
string s, s1, s2; cin >> s; queue<char> qu; qu.push(s[0]); bool flag = true; int ind = -1;
s1 = s.substr(0, s.size() / 2);
s2 = s.substr(s.size() / 2);
if(s1 == s2)
{
for(int i=0; i<s1.size(); i++)
{
s += s1[i];
}
}
//cout << s1 << " " << s2 << " " << s << "\n";
for(int i=1; i<s.size(); i++)
{
if(qu.front() == s[i]) {qu.pop();}
qu.push(s[i]);
}
int cycle = qu.size();
/*queue<char> qu2 = qu; string str = "";
while(!qu2.empty())
{
cout << qu2.front() << " ";
str += qu2.front();
qu2.pop();
}*/
while(!qu.empty())
{
if(s[++ind] != qu.front()) {flag = false; break;}
qu.pop();
}
flag == true ? cout << cycle : cout << s.size();
return 0;
}
I'd convert the array to a String object and use regex
Put all your character in an array e.x. a[]
i=0; j=0;
for( 0 < i < count )
{
if (a[i] == a[i+j+1])
{++i;}
else
{++j;i=0;}
}
Then the ratio of (i/j) = repeat count in your array.
You must pay attention to limits of i and j, but it is the simple solution.

Resources