C字符串递归函数从中间找出相等

时间:2017-05-31 22:55:58

标签: c string pointers c-strings

我觉得有点失落,因为我们开始学习指针,我有点无法跟随,我知道它在C中非常重要。

反正!

所以我得做一个递归函数,它会得到2个指针:

1)指向索引[0]的指针。

2)指针2到字符串的中间。

现在..我要检查0到中间的第一部分是否从中到端相等。像..... ADAMADAM。

在我转移字符串之前我将整个较低的字母更改为大写以避免区分大小写...所以我得到了类似的东西..但它拒绝工作。

也禁止使用常数......

#include <stdio.h> 
#include <string.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define SS 81
int CheckString(char *,int *);

int main() {
    char str[SS];
    int length,len,strcheck;
    printf("Please enter a string:\n");
    fgets(str,SS,stdin);

    len=(strlen(str) - 1);  
    if((len>0)&&(str[len]=='\n'))   // replacing '\n' key to '\0'
        str[len]='\0';

    length=len/2;
    strcheck=CheckString(str,&length);
    if (strcheck==FALSE)
       printf("FALSE.\n");
    else
       printf("TRUE.\n");
    return 0;
}

// function
int CheckString(char *str, int *i) {
if (*str != '\0')
    if (*str == str[*i])
        return CheckString(str+1,i++);
    else
        return FALSE;
    return TRUE;
}

所以我猜我的指针存在一些问题

3 个答案:

答案 0 :(得分:1)

看来你的意思是以下

#include <stdio.h>
#include <string.h>

int CheckString(const char *s, size_t *i)
{
    return s[*i] == '\0' || *s == s[*i] && CheckString(s + 1, i);
}

int main( void )
{
    char *s = "ADAMADAM";
    size_t i = strlen(s) / 2;

    int result = CheckString(s, &i);
    printf("%s\n", result ? "true" : "false");

    return 0;
}

程序输出

true

注意:也许你应该按照以下方式计算第二个参数的值

    size_t i = ( strlen(s) + 1 ) / 2;

想一想。

答案 1 :(得分:0)

CheckString()内的循环中的外部条件应检查*(str + *i) != '\0',或等效地检查str[*i] != '\0'。此外,您不需要增加*i,当然也不需要增加i,因为这是一个指针。值*i是在字符串的两半中检查的字符之间的距离。

修改后的功能可能如下所示:

int CheckString(char *str, int *i) {
    if (str[*i] != '\0') {
        if (*str == str[*i]) {
            return CheckString(str+1,i);
        } else {
            return FALSE;
        }
    }
    return TRUE;
}

答案 2 :(得分:0)

问题规范说(或多或少):

  

我必须制作一个能得到2个指针的递归函数:

     
      
  1. 指针1指向[0]。
  2.   
  3. 指针2到字符串的中间。
  4.         

    我必须检查0到中间的第一部分是否等于中间到结尾的第二部分,例如:ADAMADAM

作为递归练习,这很好;作为实现功能的一种方式,递归是过度的(迭代很好)。

关于函数的接口存在混淆(含糊不清) - 问题的措辞似乎暗示了两个char *值,但代码使用指向整数的指针作为第二个参数。这非常奇特。整数值可能有意义,但指向整数的指针不会。

我们需要仔细定义条件。根据给定的示例字符串(char str1[] = "ADAMADAM";),两个指针可能是char *p1 = &str1[0]; char *p2 = &str1[0] + strlen(str1) / 2; - 意味着p1指向第一个Ap2指向第三个A 1}}。考虑一个替代字符串:char str2[] = "MADAMADAM";;等效公式会使p1指向第一个Mp2指向第二个M

假设p1p2以锁定步骤递增,则:

  • 如果*p2等于'\0'*p1 != *p2之前的任何时候字符串都不同。
  • 如果*p2等于'\0',则字符串相同。
  • 根据定义,p1p2指向同一个数组,因此指针差异是合法的。
  • 此外,p1必须小于p2才有用; p1等于p2表示字符串相同。
  • 有一个强有力的论据,即“字符串的中间”标准意味着p2[p2 - p1] == '\0'p2[p2 - p1 + 1] == '\0'(分别为偶数和奇数字符串长度)。也就是说,两个指针之间的距离表示字符串末尾必须在哪里。这意味着使用p1 = &str[0]p2 = &str[2](在任一示例字符串上)都会失败,因为字符串的结尾不在正确的位置。如果字符串为"AMAMAMAM",则使用&str[0]&str[2]会失败,因为字符串的结尾不在正确的位置;同上&str[0]&str[6]
  • 然而,这个“强有力的论据”也是一个设计决定。简单地要求从p2到EOS(字符串的结尾)的子字符串与来自p1的字符串相同的长度是可行的。在这种情况下,在&str[0]上使用&str[2]&str[6]&str[4](或者,实际上与正常的"AMAMAMAM")一起使用会很好。

使用其中一些观察结果会产生此代码。如果您真的受到不使用const的指示,只需删除它们出现的const限定符即可。代码也是一样的。

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

static bool identical_halfstrings(const char *p1, const char *p2)
{
    assert(p1 <= p2);
    assert(strlen(p1) >= strlen(p2) + (p2 - p1));

    if (*p2 == '\0')
        return true;
    if (*p1 != *p2)
        return false;
    return identical_halfstrings(p1+1, p2+1);
}

int main(void)
{
    const char *strings[] =
    {
        "ADAMADAM",
        "MADAMADAM",
        "nonsense",
    };
    enum { NUM_STRINGS = sizeof(strings) / sizeof(strings[0]) };

    for (int i = 0; i < NUM_STRINGS; i++)
    {
        const char *p1 = strings[i];
        const char *p2 = strings[i] + strlen(strings[i]) / 2;
        printf("[%s] ([%s]) = %s\n", p1, p2,
               identical_halfstrings(p1, p2) ? "TRUE" : "FALSE");
    }
    return 0;
}

第二个断言确保p1p2指向同一个字符串 - p1和{{1}指向的位置之间没有空字节}。

测试用例输出:

p2

仅供记录,同一功能的迭代版本是:

[ADAMADAM] ([ADAM]) = TRUE
[MADAMADAM] ([MADAM]) = TRUE
[nonsense] ([ense]) = FALSE

它为样本数据生成相同的输出。