Как завершить K & R Exercise 2-4?

Я изучаю, как писать программы на C, используя книгу k & r (язык программирования C), и у меня есть проблема с одним из упражнений. Он просил меня обнаружить и удалить символ в строке s1, который соответствует любым символам в строке s2.

Итак, скажем s1 = "A";

И s2 = "AABAACAADAAE"

Я хочу, чтобы он возвращал "BCDE"

Я знаю, что я нахожусь на правильном пути к этому, я просто не знаю, как правильно проектировать программы, не могли бы вы дать мне дополнительные советы. Я попытался прочитать об алгоритме дерева двоичных данных, но чувствовал, что он слишком продвинулся для этой мирской задачи.

Спасибо всем!

/* An alternate version of squeeze(s1, s2) that deletes each character in
 * s1 that matches any character in the string s2
 *
 * [email protected]
 */

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

void squeeze(char s[], char t[]);

char string[] = "BAD";
char sstring[] = "ABC";

int
main(void)
{
    squeeze(string, sstring);
    return 0;
}

void
squeeze(char s[], char t[])
{
    int i, j, d;

    d = 0;
    if(strstr(s, t) == NULL)
        printf("%c", s[i]);
    s[j] = '\0';
}

Ответ 1

Великая книга. Если бы я был вами, я бы пошел точно так же, как для squeeze() в разделе 2.8, но вместо прямого сравнения (s [i]!= C) я бы написал и использовал функцию

 int contains(char s[], int c)

который возвращает 1, если строка s содержит c, 0 в противном случае. Начните с простого подхода; когда он работает, вы можете улучшить производительность с помощью более сложных решений (двоичный поиск, но обратите внимание, что проблема не требует, чтобы символы в s2 были в определенном порядке).

Ответ 2

Для этого двоичный поиск - это избыток. Вам нужны три индекса. Один индекс (i) должен пройти через s, один индекс (k), чтобы пройти через t и один индекс (j), чтобы отслеживать, где вы находитесь в s для символов что вам нужно сохранить, потому что они не находятся в t. Итак, для каждого символа в s, проверьте и посмотрите, находится ли он в t. Если это не так, сохраните его в s.

void squeeze(char *s, char *t) {
    int i, j, k;
    int found = 0;

    for(i = j = 0; s[i] != '\0'; i++) {
        found = 0;
        for(k = 0; t[k] != '\0' && (found == 0); k++) {
            if(t[k] == s[i]) {
                found = 1;
            }
        }

        if(found == 0) {
            s[j++] = s[i];
        }

    }

    s[j] = '\0';
}

Ответ 3

Вам не нужен фантастический бинарный поиск для выполнения задания. Вам понадобится цикл double для цикла, который проверяет наличие каждого char в одной строке в другой и копирует не встречающиеся символы в третий массив char (который является вашим результатом).

Код может быть примерно следующим (не проверен!):

char *s1, *s2, *result; /* original strings and the result string */
int len1, len2; /* lengths of the strings */
for (i = 0; i < len1; i++) {
   for (j = 0; j < len2; j++) {
     if (s1[i] == s2[j]) {
       break;
     }
   }
   if (j == len2) {  /* s1[i] is not found in s2 */
     *result = s1[i]; 
     result++; /* assuming your result array is long enough */
   }
}

Ответ 4

void squeeze(char s1[], char s2[])
{
    int i,j,k;
    char c;
    for(i=0;s2[i]!='\0';i++)
    {
        c=s2[i];
        for(j=k=0;s1[j]!='\0';j++)
            if(s1[j]!=c)
                s1[k++]=s1[j];
            s1[k]='\0';
    }
}

Ответ 5

это моя функция:

void squeeze(char s1[],char s2[])
{
int i,j,p;
int found;

p=0;
for(i=0;s1[i]!='\0';i++)
{
    for(j=0;s2[j]!='\0';j++)
        if(s1[i]==s2[j])
            found=YES;
        else
            found=NO;
    if(found==NO)
        s1[p++]=s1[i];
     }
    s1[p]='\0';
}