检查字符串是否由两次重复组成

发布于 2025-01-17 06:31:26 字数 625 浏览 0 评论 0原文

我正在编写一个函数,如果字符串包含两次重复,则返回 1,否则返回 0。

示例:如果字符串是“hellohello”,则该函数将返回 1,因为该字符串由相同的两个单词“hello”和“hello”组成。

我做的第一个测试是使用嵌套的 for 循环,但经过一番推理后,我认为这个想法是错误的,不是正确的解决方法,这是我编写的最后一个函数。

这是不正确的,即使字符串由两次重复组成,它也会返回 0。

另外,我知道这个问题可以通过遵循另一种算法的 while 循环以不同的方式处理,但我想知道是否也可以使用 for 来完成。

我的想法是将字符串分成两半并逐个字符地检查它。

这是我尝试的最后一个功能:

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;
}

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

神经大条 2025-01-24 06:31:26

您的函数中的问题在于第二个循环中的比较:您使用 j 变量作为给定字符串后半部分的索引 作为索引在该字符串的复制前半部分中。但是,对于复制的字符串,您需要索引从零开始 - 因此在访问其各个字符时,您需要从 j 中减去 s_length/2 值。

此外,在循环字符串并与 strlen(返回该类型)等函数的结果进行比较时,最好使用 size_t 类型。您还可以通过保存 strlen(s)/2 值来改进代码,这样就不会在每个循环上计算它。您还可以省去本地 true 变量,一旦发现不匹配就返回 0,如果第二个循环完成而没有找到不匹配则返回 1这样的不匹配:

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;
}

事实上,一旦您明白为什么需要从 strNewj 索引中减去“半长”,您就可以可以完全消除对该临时副本的需要,并且只需使用修改后的j作为原始字符串的索引:

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;
}

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;
}
爱本泡沫多脆弱 2025-01-24 06:31:26

这个循环

for(int j=strlen(s)/2;j<strlen(s);j++){
  if(!(strNew[j]==s[j])){
    true=0;
  }
}

是不正确的。数组strNew中的索引应从0开始,而不是表达式strlen( s ) / 2的值。

但无论如何,您的方法都是不正确的,因为至少您使用的是带有幻数 50 的中间数组。用户可以向函数传递任意长度的字符串。

char strNew[50];

该函数看起来简单得多。
例如

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;
}

,该函数首先检查传递的字符串不为空并且其长度为偶数。如果是,则该函数比较字符串的两半。

这是一个演示程序。

#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" ) );
}

程序输出为

doubleString( "" ) = 0
doubleString( "HelloHello" ) = 1
doubleString( "Hello Hello" ) = 0

注意函数参数应该有限定符 const 因为传递的字符串在函数内不会改变。您将能够使用常量数组调用该函数,而无需为常量字符数组再​​定义一个函数。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文