Вывести на экран слова, отличающиеся лишь порядком следования букв - C (СИ)
Формулировка задачи:
Всем здрасте! Заранее спасибо, если Вы даже просто подумали над моей проблемкой. В общем, к делу. Задача была таковой:
Дана строка (неизвестной длины) - вывести на экран слова (из данной строки), которые отличаются лишь порядком следования букв (мама - амма - амам и т.д.).
Я долго бился над решением и решил, что это можно сделать следующим образом: разделить строку на слова, в каждом слове буквы свести к одному регистру и отсортировать в алфавитном порядке(написал для этого функцию). Затем каждое слово сравнить таким образом с остальными и, как только найдется "пара" - вывести на экран. Вот мое скудное (наверняка некрасивое), но творение:
Прошу прощения за такое большое количество переменных, не обессудьте.
У меня здесь две проблемы (ну.. пока те, на которые я наткнулся) - 1)Не распознает слова = не выводит их на экран по отдельности (Выдает ошибку, вида "бла-бла-бла, адрес программы. Строка 49. Выражение (string !=NULL). бла-бла-бла")
2) Какая-то глупая ошибка в функции сортировки слова (или не глупая... я ее, в общем, найти не могу)..
Прошу помощи, если вам не трудно)
Я писал пока только для латинских букв.. и в строке не может быть ничего, окромя латинских букв и пробелов.. Потом, как с вашей божьей помощью разберусь с тем, что здесь неверно, пойду разбираться с русскими буквами и знаками препинания. Еще раз спасибо за внимание!
#include <locale> #include <stdio.h> #include <stddef.h> #include <cstdio> #include <conio.h> #include <iostream> #include <string.h> #define maxn 10000 char S[maxn], *NewWord, **Words; int i,f,N, WBeg,WEnd,WLeng, Numb, col, row, z; char *expansion (char *Word) {char *FuncAr; char C; int j; j=0; while (Word[j]!='\0') j++; FuncAr=(char*)calloc(j, sizeof (char)); for (int k = 0;k<=j;k++) FuncAr[k]=Word[k]; FuncAr=strlwr(FuncAr); j=1; while (j=1) { j=0; for (int k=1; k<=i;k++) { if (FuncAr[k]<FuncAr[k-1]) {j=1; C=FuncAr[k]; FuncAr[k]=FuncAr[k-1]; FuncAr[k-1]= C;}}} puts (FuncAr); return FuncAr; } void main () { setlocale (0,"russian"); do{ printf ("Введите вашу строку!\n"); gets_s (S); i=0; N=1; while (S[i]!='\0' && N==1) {if ((S[i]!=' ') && ! ((S[i]>='A' && S[i]<='Z') || (S[i]>='a' && S[i]<='z'))) /*|| ((unsigned char)S[i]>=(unsigned char)'А' && (unsigned char)S[i]<=(unsigned char)'я')*/ N=0; i++; } if (N==0) printf ("Ввод некорректен. Попробуйте заново\n"); }while (N==0); N=i; i=0; Words = (char**)calloc(N, sizeof(*Words)); Numb=1; while (i<=N) { while (S[i]==' ') i++; WBeg=i; while (S[i]!=' ') i++; WEnd=i; WLeng=WEnd-WBeg; Words[Numb]=(char*)calloc(WLeng, sizeof(char)); for (int k = 0, i=WBeg;i<=WEnd; i++, k++) { Words[Numb][k]=S[i];} Numb++; printf ("Слово № %d :\n", Numb); puts (Words[Numb]); printf ("\n\n"); } printf ("Результат:\n"); row=1; while (row<=Numb) { for (i=0;i<=Numb;i++) {if (strcmp(expansion(Words[row]),expansion(Words[i]))) puts(Words[row]);} row++;} free (Words); system ("pause"); }
Решение задачи: «Вывести на экран слова, отличающиеся лишь порядком следования букв»
textual
Листинг программы
#include <stdio.h> #include <stdlib.h> #include <string.h> //создаем массив из слов введенной строки char **CreateArray(char line[], int len, int *cnt) { int i = -1; int count = 0; char *buf = (char*) malloc(strlen(line) + 1); //копия исходной строки, уничтожается в процессе подсчета слов strcpy(buf, line); char *delims = " ,.-\n"; char *word = strtok(buf, delims); while (word != NULL) { ++count; //считаем фактическое кво слов word = strtok(NULL, delims); } free(buf); *cnt = count; char **words = (char**) malloc(count * sizeof(char*)); //выделяем память под count слов длиной len while (++i < count) words[i] = (char*) malloc(len); word = strtok(line, delims); //заполняем массив словами из строки i = -1; while (word != NULL) { strcpy(words[++i], word); word = strtok(NULL, delims); } return words; } //печать массива слов void ShowArray(char **words, int count) { int i = -1; while (++i < count) printf("%s\n", words[i]); } //копия массива слов char **CopyArray(char **words, int count) { int i = -1; char **copy = (char**) malloc(count * sizeof(char*)); while (++i < count) { copy[i] = (char*) malloc(strlen(words[i]) + 1); strcpy(copy[i], words[i]); } return copy; } //очистка памяти void DestroyArray(char **words, int count) { while (--count > -1) free(words[count]); free(words); } //своп двух букв для сортировки по алфавиту void Swap(char *a, char *b) { char t = *a; *a = *b; *b = t; } //сортировка слова по алфавиту void SortLetters(char *word) { int i, j, len = strlen(word); for (i = 0; i < len - 1; i++) for (j = i + 1; j < len; j++) if (word[j] < word[i]) Swap(&word[i], &word[j]); } //собственно, решение задачи void FindBros(char **words, int count) { int i, j; char **copy = CopyArray(words, count); //создаем копию массива слов for (i = 0; i < count; i++) SortLetters(copy[i]); //в каждом слове переставляем все буквы по алфавиту int *mask = (int*) malloc(count * sizeof(int)); //маска: слово уже было найдено как "двойник по буквам" или нет for (i = 0; i < count; i++) mask[i] = 0; //сначала - все 0 for (i = 0; i < count - 1; i++) { if (!mask[i]) //если i-ое слово еще не было "двойником по буквам" { printf("\n%20s: ", words[i]); for (j = i + 1; j < count; j++) if (strcmp(copy[i], copy[j]) == 0) //сравниваем i-ую и j-ую копию, т.е. буквенный состав слов words[i] и words[j] { printf("%20s ", words[j]); //если буквенный состав совпал - выводим words[j] mask[j] = 1; //в маске помечаем j-ое слово как уже найденное в качестве "двойника" } } } DestroyArray(copy, count); free(mask); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main() { char str[BUFSIZ]; int len = 20, count = 0; printf("Your string:\n"); fgets(str, BUFSIZ, stdin); char **words = CreateArray(str, len, &count); printf("\n\nYour words:\n"); ShowArray(words, count); printf("\n\nWords with the same set of letters:\n"); FindBros(words, count); DestroyArray(words, count); getchar(); return 0; }
Объяснение кода листинга программы
- Объявлены функции:
- CreateArray
- ShowArray
- CopyArray
- DestroyArray
- Swap
- SortLetters
- FindBros
- В функции CreateArray создается массив из слов введенной строки.
- В функции ShowArray выводится на экран массив слов.
- В функции CopyArray создается копия массива слов.
- В функции DestroyArray освобождается память, выделенная под массив слов.
- В функции Swap происходит обмен двух букв.
- В функции SortLetters сортируются буквы в слове по алфавиту.
- В функции FindBros осуществляется поиск слов с одинаковым набором букв.
- В функции main происходит ввод строки, разделение ее на слова, вывод списка слов, поиск слов с одинаковым набором букв, освобождение памяти.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д