Как выполнить упражнение K & R 2-4? - PullRequest
2 голосов
/ 07 января 2009

Я учусь писать программы на 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
 *
 * Angie@odfx.org
 */

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

Ответы [ 5 ]

3 голосов
/ 07 января 2009

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

 int contains(char s[], int c)

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

2 голосов
/ 07 января 2009

Бинарный поиск является излишним для этого. Вам нужно три индекса. Один индекс (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';
}
0 голосов
/ 16 июня 2014

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

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';
}
0 голосов
/ 28 ноября 2013
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';
    }
}
0 голосов
/ 07 января 2009

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

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

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 */
   }
}
...