Вывести слова этого же текста, множества символов которых являются подмножествами множества символов - C (СИ)
Формулировка задачи:
Для каждого слова w данного текста вывести слова этого же текста, множества символов которых являются подмножествами множества символов слова w.
Сделал таким образом:
Что нужно изменить в программе если вместо *free_mass[MAXWORDS] сделать **free_mass?
#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;
}Решение задачи: «Вывести слова этого же текста, множества символов которых являются подмножествами множества символов»
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);
}
Объяснение кода листинга программы
- Ввод строки из стандартного ввода с помощью
fgets(). - Создание пустого списка слов с помощью
firstиlast. - Разделение входной строки на слова с помощью
strtok(). - Добавление каждого слова в список с помощью
new_word(). - Если память не может быть выделена, выводится сообщение об ошибке и программа завершается.
- Каждое слово во введенной строке проверяется на наличие всех символов в каждом другом слове в списке.
- Если слово не проходит проверку, оно выводится в консоль.
- После завершения проверки все выделенное в программе память освобождается с помощью
delete_words(). - Программа завершается с успехом.