C字符串递归函数来找出从中间
平等,我觉得有点失落,因为我们开始学习指针我还挺着跟着,我知道它在C.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;
}
所以我想我有一些问题与指针
看来你指的是以下
#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;
想一想。
但是使用常量字符也是禁止的,我应该提及它:/ – Alex
@AlexBoyev如果删除限定符,它将是一个错误的函数声明。也就是说,这种情况下的函数可能不适用于常量字符串。但是,如果需要,您可以删除限定符。 –
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;
}
它完美的作品,没有测试极限点......但你能解释一下,'我'如何保持不变而不提升? – Alex
'* i'所保存的值就是从字符串的前面到中间的距离。所以,当你给'str'加1时,'str + * i'指向中间后面的下一个字符,依此类推。 –
@ Alex--请注意,由于您计算字符串中间的方式,“ADAMADAM”和“MADAMADAM”都返回TRUE。 –
问题规范说(或多或少):我有
做一个递归函数,将获得2个指针:
- 指针1指向索引[0]。
- 指针2指向字符串的中间部分。
我必须检查从0到中间的第一部分是否等于从中间到第二部分的第二部分,如:
ADAMADAM
。
作为递归的运动,这是好的;作为实现功能的一种方式,递归是过度的(迭代很好)。
关于函数接口存在混淆(模棱两可) - 问题的措辞似乎暗示了两个值char *
,但代码使用指向一个整数的指针作为第二个参数。这是奇特的。整数值可能有意义,但指向整数的指针不会。
我们需要仔细定义条件。以给出的示例字符串(char str1[] = "ADAMADAM";
),这两个指针可能为char *p1 = &str1[0]; char *p2 = &str1[0] + strlen(str1)/2;
--意指p1
指向第一个A
和p2
到第三个A
。考虑一个替代字符串:char str2[] = "MADAMADAM";
;等效公式将使p1
指向第一个M
和p2
指向第二个M
。
p1
假设和p2
在锁步递增,则:
- 字符串是如果不同,在任何点
*p2
等于'\0'
,*p1 != *p2
之前。 - 如果
*p2
等于'\0'
,则字符串是相同的。 - 按照定义,
p1
和p2
指向相同的数组,因此指针差异是合法的。 - 此外,
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]
和。 - 但是,这个“强有力的论据”也是一个设计决定。简单地要求从
p2
到EOS(字符串结尾)的子字符串与来自p1
的字符串的长度相同是可行的。在那种情况下,在"AMAMAMAM"
上使用&str[0]
与&str[2]
或(或确实与正常&str[4]
)可以正常工作。
使用这些观察中的一些导致此代码。如果您确实不遵守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;
}
第二断言确保p1
和p2
都指向相同的字符串 - 不存在之间的位置处通过p1
和p2
指出一个空字节。
测试用例输出:
[ADAMADAM] ([ADAM]) = TRUE
[MADAMADAM] ([MADAM]) = TRUE
[nonsense] ([ense]) = FALSE
为了记录,相同功能的迭代版本是:
static bool identical_halfstrings(const char *p1, const char *p2)
{
assert(p1 <= p2);
assert(strlen(p1) >= strlen(p2) + (p2 - p1));
while (*p2 != '\0')
{
if (*p1++ != *p2++)
return false;
}
return true;
}
它产生用于采样数据相同的输出。
为什么你把它标记为'C++'? – PaulMcKenzie
为什么你将'int'指针传递给'CheckString()'?而'我++'可能不是你想要的。 –
嗨大卫,ty回应...多数民众赞成在我被问... 2指针。 – Alex