I am writing a function that returns 1 if a string consists of two repetitions, 0 otherwise.
Example: If the string is "hellohello", the function will return 1 because the string consists of the same two words "hello" and "hello".
The first test I did was to use a nested for loop but after a bit of reasoning I thought that the idea is wrong and is not the right way to solve, here is the last function I wrote.
It is not correct, even if the string consists of two repetitions, it returns 0.
Also, I know this problem could be handled differently with a while loop following another algorithm, but I was wondering if it could be done with the for as well.
My idea would be to divide the string in half and check it character by character.
This is the last function I tried:
int doubleString(char *s){
int true=1;
char strNew[50];
for(int i=0;i<strlen(s)/2;i ){
strNew[i]=s[i];
}
for(int j=strlen(s)/2;j<strlen(s);j ){
if(!(strNew[j]==s[j])){
true=0;
}
}
return true;
}
CodePudding user response:
The problem in your function is with the comparison in the second loop: you are using the j
variable as an index for both the second half of the given string and for the index in the copied first half of that string. However, for that copied string, you need the indexes to start from zero – so you need to subtract the s_length/2
value from j
when accessing its individual characters.
Also, it is better to use the size_t
type when looping through strings and comparing to the results of functions like strlen
(which return that type). You can also improve your code by saving the strlen(s)/2
value, so it isn't computed on each loop. You can also dispense with your local true
variable, returning 0
as soon as you find a mismatch, or 1
if the second loop completes without finding such a mismatch:
int doubleString(char* s)
{
char strNew[50] = { 0, };
size_t full_len = strlen(s);
size_t half_len = full_len / 2;
for (size_t i = 0; i < half_len; i ) {
strNew[i] = s[i];
}
for (size_t j = half_len; j < full_len; j ) {
if (strNew[j - half_len] != s[j]) { // x != y is clearer than !(x == y)
return 0;
}
}
return 1;
}
In fact, once you have appreciated why you need to subtract that "half length" from the j
index of strNew
, you can remove the need for that temporary copy completely and just use the modified j
as an index into the original string:
int doubleString(char* s)
{
size_t full_len = strlen(s);
size_t half_len = full_len / 2;
for (size_t j = half_len; j < full_len; j ) {
if (s[j - half_len] != s[j]) { // x != y is clearer than !(x == y)
return 0;
}
}
return 1;
}
CodePudding user response:
This loop
for(int j=strlen(s)/2;j<strlen(s);j ){
if(!(strNew[j]==s[j])){
true=0;
}
}
is incorrect. The index in the array strNew
shall start from 0 instead of the value of the expression strlen( s ) / 2
.
But in any case your approach is incorrect because at least you are using an intermediate array with the magic number 50
. The user can pass to the function a string of any length.
char strNew[50];
The function can look much simpler. For example
int doubleString( const char *s )
{
int double_string = 0;
size_t n = 0;
if ( ( double_string = *s != '\0' && ( n = strlen( s ) ) % 2 == 0 ) )
{
double_string = memcmp( s, s n / 2, n / 2 ) == 0;
}
return double_string;
}
That is the function at first checks that the passed string is not empty and its length is an even number. If so then the function compares two halves of the string.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
int doubleString( const char *s )
{
int double_string = 0;
size_t n = 0;
if (( double_string = *s != '\0' && ( n = strlen( s ) ) % 2 == 0 ))
{
double_string = memcmp( s, s n / 2, n / 2 ) == 0;
}
return double_string;
}
int main( void )
{
printf( "doubleString( \"\" ) = %d\n", doubleString( "" ) );
printf( "doubleString( \"HelloHello\" ) = %d\n", doubleString( "HelloHello" ) );
printf( "doubleString( \"Hello Hello\" ) = %d\n", doubleString( "Hello Hello" ) );
}
The program output is
doubleString( "" ) = 0
doubleString( "HelloHello" ) = 1
doubleString( "Hello Hello" ) = 0
Pay attention to that the function parameter should have the qualifier const
because the passed string is not changed within the function. And you will be able to call the function with constant arrays without the need to defined one more function for constant character arrays.
CodePudding user response:
it's better to do it with a while loop since you don't always have to iterate through all the elements of the string but since you want the for loop version here it is (C version):
int doubleString(string s){
int s_length = s.length();
if(s_length%2 != 0) {
return 0;
}
for (int i = 0; i < s_length/2; i ) {
if (s[i] != s[s_length/2 i]){
return 0;
}
}
return 1;
}