Вывести слова этого же текста, множества символов которых являются подмножествами множества символов - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Для каждого слова w данного текста вывести слова этого же текста, множества символов которых являются подмножествами множества символов слова w. Сделал таким образом:
#include <stdio.h>
#include <stdlib.h>
#define MAXWORDS 5000 /* максимальное количество слов в тексте */
#define MAXLEN  1000/* максимальная длина входного слова */
 
/* strcpy: копирует строку t в s */
void strcpy (char *s, char *t)
{
    while (*s++ = *t++)
        ;
}
 
/* strlen: возвращает длину строки s */
int strlen (char *s)
{
    int i = 0;
 
    while (s[i] != '\0')
        ++i;
    return i;
}
 
char *get_word (int n, char *c)
{
    char s[n], *p;
    int i = 0;
 
    if (*c == '\n'){
        p = NULL;
        return p;
    }
    while (*c == ' ')
        *c = getchar();
    while (*c != ' ' && i < n && *c != '\n'){
        s[i++] = *c;
        *c = getchar();
    }
    s[i++] = '\0';
    if (i > n  || (p = (char *) malloc(i)) == NULL)
        p = NULL;
    else strcpy (p, s);
    return p;
}
 
void poisk (char *pmass[], int n)
{
    int i, j, k, l, f;
 
    for (i = 0; i < n; ++i){
        printf ("For %s:\n", pmass[i]);
        for (j = 0; j < n; ++j){
            if (i == j && i!=n-1)
                j++;
            else if (i = n - 1 && i == j)
                    return;
            k = 0;
            f = 1;
            while (pmass[j][k] != '\0' && f == 1){
                f = 0;
                l = 0;
                while (pmass[i][l] != '\0' && f == 0){
                    if (pmass[j][k] == pmass[i][l]) 
                        f = 1;
                        else l++;
                }
                k++;
            }
            if (f == 1)
                printf ("%s\n",pmass[j]);
        }
    }
    return;
}
 
int main()
{
    char *free_mass[MAXWORDS], *p, c;
    int nword = 0, i;
 
    printf ("Vvedite text\n");
    c = getchar();
    p = get_word (MAXLEN, &c);
    while (p != NULL){
        if (nword < MAXWORDS + 1){
        free_mass[nword++] = p;
        p = get_word (MAXLEN, &c);
        } else {
            printf ("error\n");
            return 0;
        }
    }
    poisk (free_mass, nword);
    for (i = 0; i < nword; ++i)
        free (free_mass[i]);
    getchar();
    return 0;
}
Что нужно изменить в программе если вместо *free_mass[MAXWORDS] сделать **free_mass?

Решение задачи: «Вывести слова этого же текста, множества символов которых являются подмножествами множества символов»

textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define SEP " ,.;:\t\n"
 
typedef struct WRD {
    struct WRD * next;
    char * word;
} wrd_t;
 
wrd_t * new_word(const char * s, wrd_t * last){
    wrd_t * w;
    if ( ( w = (wrd_t*)malloc(sizeof(wrd_t)) ) == NULL )
        return NULL;
    if ( ( w->word = strdup(s) ) == NULL ){
        free(w);
        return NULL;
    }
    w->next = NULL;
    if ( last )
        last->next = w;
    return w;
}
 
void delete_words(wrd_t * w){
    wrd_t * t;
    while ( w ){
        t = w->next;
        free(w->word);
        free(w);
        w = t;
    }
}
 
/* возвращает 0 если все буквы из слова b есть в слове a */
int check_word(const char * a, const char * b){
    while ( *b  && strchr(a, *b) )
        ++b;
    return *b;
}
 
int main(void){
    char buf[BUFSIZ], * p;
    wrd_t * first, * last, * i, *j;
 
    printf("String: ");
    if ( ! fgets(buf, BUFSIZ, stdin) || *buf == '\n' ){
        fprintf(stderr, "Wrong or empty string!\n");
        exit(EXIT_FAILURE);
    }
 
    first = last = NULL;
    for ( p = strtok(buf, SEP); p; p = strtok(NULL, SEP) ){
        if ( ( last = new_word(p, last) ) == NULL ){
            fprintf(stderr, "Memory error!");
            if ( first )
                delete_words(first);
            exit(EXIT_FAILURE);
        }
        if ( ! first )
            first = last;
    }
 
    if ( ! first ){
        fprintf(stderr, "Shit happens!\n");
        exit(EXIT_FAILURE);
    }
 
    for ( i = first; i != NULL; i = i->next ){
        printf("\n%s\n", i->word);
        for ( j = first; j != NULL; j = j->next ){
            if ( j == i )
                continue;
            if ( ! check_word(i->word, j->word) )
                printf("\t%s\n", j->word);
        }
    }
 
    delete_words(first);
    exit(EXIT_SUCCESS);
}

Объяснение кода листинга программы

  1. Ввод строки из стандартного ввода с помощью fgets().
  2. Создание пустого списка слов с помощью first и last.
  3. Разделение входной строки на слова с помощью strtok().
  4. Добавление каждого слова в список с помощью new_word().
  5. Если память не может быть выделена, выводится сообщение об ошибке и программа завершается.
  6. Каждое слово во введенной строке проверяется на наличие всех символов в каждом другом слове в списке.
  7. Если слово не проходит проверку, оно выводится в консоль.
  8. После завершения проверки все выделенное в программе память освобождается с помощью delete_words().
  9. Программа завершается с успехом.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 4.3 из 5
Похожие ответы