Вывести на экран слова, отличающиеся лишь порядком следования букв - 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 происходит ввод строки, разделение ее на слова, вывод списка слов, поиск слов с одинаковым набором букв, освобождение памяти.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д