2016-06-20 2 views
3

Я уже почти десять дней сижу на коде. Я пишу funtion, который получает два указателя для двух разных строк, и функция должна возвращать 1, если имеется такое же количество слов, или 0, если нет.Сравнение строки

Мне не разрешено использовать какой-либо lib, глобальный или статический int и т. Д., Нет циклов, только рекурсия, не разрешается изменять подпись функции. То, что я написал, является дельтами между двумя предложениями. Сначала мой код вычисляет сумму слов в первом предложении, когда он достигает «\ 0» первого предложения, он начинает работать над вторым предложением и вычитает каждый раз, когда есть слово. прямо сейчас выход моего Funtion является дельта, я хочу, чтобы как-то сказать функцию, если дельта («возвращение») 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

Я думаю, вам будет проще иметь рекурсивную функцию count_words(), которую вы вызываете для обоих предложений, а затем сравниваете результаты. –

+0

* «если дельта (« возврат ») равна 0 return 1, else return 1.» * Это опечатка? Вы имели в виду сказать: * «если delta (« return ») равно 0 return 0, else return 1." * –

+0

Если инструкция состоит в том, что 'same_num_words()' * self * будет рекурсивным и не должен звонить другому рекурсивная вспомогательная функция (я не могу это прочитать). Я не могу думать ни о каком другом пути, кроме как пройти мимо.как рекурсивный уровень, чтобы решить, что вы должны возвращать 0/1 вместо дельта слов или иметь дополнительную переменную 'int *' для дельта и всегда возвращать 0/1. В обоих случаях у вас есть дополнительный параметр, который вообще не имеет смысла для внешнего вызывающего абонента этой функции, но я думаю, что это потому, что сама инструкция не имеет смысла ... –

ответ

3

Каждый символ является либо буква или разделителем ('\0' или пробелы: пространство, \n\t и т.д.?).

1 - Любой ведущий пробельные не имеет никакого значения, так что пропустить тех
2 - Если код находится в конце любой строки, мы закончили.
3 - Поскольку каждая строка теперь начинается с буквы, см. Ее следующий символ также письмо.

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

Expand 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); 
} 
+0

Мне не разрешено использовать const в вопросе, только идти вперед с указателем char. Я думаю, это изменило все это, потому что Im не позволил изменить подпись funtion. – Tom

+0

@Tom, 1) Затем просто удалите 'const'. 2) Лучше добавить это новое требование к сообщению: «не разрешено изменять подпись функции». – chux

+0

Я добавил. извините – Tom

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

Прошу простить эти критерии. –

+0

Я снял петли ... Надеюсь, это сработает ... –

+0

Держись .. я думаю, что все еще есть проблемы .. :( –

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