我现在已经坐了近十天了。 我正在编写一个函数来获取2个不同字符串的两个指针,如果有相同数量的单词,函数需要返回1,如果没有,则返回0。
我不允许使用任何lib,全局或静态int等,没有循环,只有递归,不允许更改函数的签名。 我写的是两句话之间的差异。首先,我的代码计算第一句中的单词总和,当它到达第一个句子的'\ 0'时,它开始对第二个句子起作用,并且每次有一个单词时减去。 现在我的功能输出是delta,我想以某种方式告诉函数,如果delta(“返回”)为0则返回1,否则返回1.
“
int same_num_words(char *s1, char *s2)
{
printf("%s\n", s1);
printf("%s\n", s2);
if(s1[0]=='\0' && s2[0] == '\0')
{
return 0;
}
if (s1[0] == '\0' ) // AFTER first sentence is complete, substract the second sentence count.
{
if(s2[0]!= ' ' && s2[1]== ' ')
{
return same_num_words(s1, s2+1) -1 ;
}
if(s2[0]!= ' ' && s2[1]== '\0')
{
return same_num_words(s1, s2+1)-1;
}
return same_num_words(s1, s2+1);
}
if(s1[0]!='\0') // first sentence
{
if((s1[0]!= ' ' && s1[1]== ' ') || (s1[0]!= ' ' && s1[1]== '\0') ) // first sentence
{
return same_num_words(s1+1, s2)+1;
}
}
return same_num_words(s1+1, s2);
}
"
任何帮助?
答案 0 :(得分:3)
每个字符都是字母或分隔符('\0'
或空格:空格,\n
\t
等)
1 - 任何领先的空白都无关紧要,所以请跳过这些空白 2 - 如果代码在任一字符串的末尾,我们就完成了 3 - 由于现在每个字符串都以字母开头,因此 next 字符也是一个字母。
int same_num_words(const char *s1, const char *s2) {
// printf("'%s' ", s1);
// printf("'%s'\n", s2);
if (s1[0] == ' ') return same_num_words(s1 + 1, s2);
if (s2[0] == ' ') return same_num_words(s1, s2 + 1);
if (s1[0] == '\0' && s2[0] == '\0') return 1; // same
if (s1[0] == '\0') return 0; // differ
if (s2[0] == '\0') return 0;
// Both s1,s2 begin with a letter (non-delimiter)
// If the next character is also a letter, skip over the current one.
// as code is looking for the end-of-word.
if (!(s1[1] == '\0' || s1[1] == ' ')) return same_num_words(s1+1, s2);
if (!(s2[1] == '\0' || s2[1] == ' ')) return same_num_words(s1, s2+1);
return same_num_words(s1+1, s2+1);
}
根据需要将s1[0] == ' '
展开到s1[0] == ' ' || s1[0] == '\t' || ...
。
OP代码的一个关键变化是首先跳过前导空格,因为它消耗了字符串的前导和尾随空格。
为了好玩,通过更少的递归实现更清晰的实现。
int same_num_words(const char *s1, const char *s2) {
int sp1 = *s1 == ' ';
int sp2 = *s2 == ' ';
if (sp1 | sp2) return same_num_words(s1 + sp1, s2 + sp2);
int nc1 = *s1 == '\0';
int nc2 = *s2 == '\0';
if (nc1 | nc2) return nc1 & nc2;
// Both s1,s2 begin with a letter (non-delimiter)
// How about the next character?
int nxt_let1 = !(s1[1] == '\0' || s1[1] == ' ');
int nxt_let2 = !(s2[1] == '\0' || s2[1] == ' ');
if (nxt_let1 | nxt_let2) return same_num_words(s1 + nxt_let1, s2 + nxt_let2);
return same_num_words(s1 + 1, s2 + 1);
}
答案 1 :(得分:1)
此解决方案遵循规则的字母(尽管我添加了一些const
)。如果任一参数为same_num_words
,它会重载NULL
的含义以返回字符串中的单词数。第二个参数是NULL
如果前一个字符读取(如果有的话)是空格,第一个参数NULL
如果我们只读了一个单词字符。
int same_num_words(const char *s1, const char *s2) {
if (!s1 || !s2) {
const char *s = s1 ? s1 : s2;
if (*s == '\0') return !s1;
if (*s == ' ') return !s1 + same_num_words(s + 1, 0);
return same_num_words(0, s + 1);
}
return same_num_words(s1, 0) == same_num_words(s2, 0);
}
这是一些检查实施的单元测试。
#include <assert.h>
#include <stdio.h>
int main(int argc, char **argv) {
struct {
const char *word1;
const char *word2;
int want;
} cases[] = {
{"This is a test", "one two three four", 1},
{"", "", 1},
{"one", "", 0},
{" one two three ", "one two three", 1},
{"one two three ", "one two three", 1},
{"one two three ", "one two three four", 0},
{" ", "", 1},
};
int failed = 0;
for (int i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
int got = same_num_words(cases[i].word1, cases[i].word2);
if (got != cases[i].want) {
printf("same_num_words('%s', '%s') = %d, want %d\n", cases[i].word1, cases[i].word2, got, cases[i].want);
failed = 1;
}
got = same_num_words(cases[i].word2, cases[i].word1);
if (got != cases[i].want) {
printf("same_num_words('%s', '%s') = %d, want %d\n", cases[i].word2, cases[i].word1, got, cases[i].want);
failed = 1;
}
}
assert(!failed);
return 0;
}
答案 2 :(得分:0)
试试这个:
int check_words(char *str1, char*str2) {
if (!str1 && !str2) {
return 1;
}
if (!str1 || !str2) {
return 0;
}
if (*str1=='\0' && *str2=='\0') {
return 1;
}
if((*str1==' ' || *str1=='\t') && (!(*str2==' ' || *str2=='\t' || *str2=='\0')))
return check_words(str2+1, str1);
if((*str2==' ' || *str2=='\t') && (!(*str1==' ' || *str1=='\t' || *str1=='\0')))
return check_words(str1+1, str2);
if (*str1=='\0' && (*str2==' ' || *str2=='\t')) {
return check_words(str1, str2+1);
}
if (*str2=='\0' && (*str1==' ' || *str1=='\t')) {
return check_words(str2, str1+1);
}
if (*str1!='\0' && *str2!='\0') {
return check_words(str1+1, str2+1);
}
else {
return 0;
}
}