Вывести на экран слова, отличающиеся лишь порядком следования букв - C (СИ)

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

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

Всем здрасте! Заранее спасибо, если Вы даже просто подумали над моей проблемкой. В общем, к делу. Задача была таковой: Дана строка (неизвестной длины) - вывести на экран слова (из данной строки), которые отличаются лишь порядком следования букв (мама - амма - амам и т.д.). Я долго бился над решением и решил, что это можно сделать следующим образом: разделить строку на слова, в каждом слове буквы свести к одному регистру и отсортировать в алфавитном порядке(написал для этого функцию). Затем каждое слово сравнить таким образом с остальными и, как только найдется "пара" - вывести на экран. Вот мое скудное (наверняка некрасивое), но творение:
Листинг программы
  1. #include <locale>
  2. #include <stdio.h>
  3. #include <stddef.h>
  4. #include <cstdio>
  5. #include <conio.h>
  6. #include <iostream>
  7. #include <string.h>
  8. #define maxn 10000
  9. char S[maxn], *NewWord, **Words;
  10. int i,f,N, WBeg,WEnd,WLeng, Numb, col, row, z;
  11.  
  12. char *expansion (char *Word) {char *FuncAr; char C; int j;
  13. j=0;
  14. while (Word[j]!='\0') j++;
  15. FuncAr=(char*)calloc(j, sizeof (char));
  16. for (int k = 0;k<=j;k++) FuncAr[k]=Word[k];
  17. FuncAr=strlwr(FuncAr);
  18. j=1;
  19. while (j=1) {
  20. j=0;
  21. for (int k=1; k<=i;k++) { if (FuncAr[k]<FuncAr[k-1]) {j=1;
  22. C=FuncAr[k];
  23. FuncAr[k]=FuncAr[k-1];
  24. FuncAr[k-1]= C;}}}
  25. puts (FuncAr);
  26. return FuncAr;
  27. }
  28. void main ()
  29. {
  30. setlocale (0,"russian");
  31. do{
  32. printf ("Введите вашу строку!\n");
  33. gets_s (S);
  34. i=0;
  35. N=1;
  36. while (S[i]!='\0' && N==1)
  37. {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)'я')*/
  38. N=0;
  39. i++;
  40. }
  41. if (N==0) printf ("Ввод некорректен. Попробуйте заново\n");
  42. }while (N==0);
  43. N=i;
  44. i=0;
  45. Words = (char**)calloc(N, sizeof(*Words));
  46. Numb=1;
  47. while (i<=N)
  48. {
  49. while (S[i]==' ') i++;
  50. WBeg=i;
  51. while (S[i]!=' ') i++;
  52. WEnd=i;
  53. WLeng=WEnd-WBeg;
  54. Words[Numb]=(char*)calloc(WLeng, sizeof(char));
  55. for (int k = 0, i=WBeg;i<=WEnd; i++, k++) {
  56. Words[Numb][k]=S[i];}
  57. Numb++;
  58. printf ("Слово № %d :\n", Numb);
  59. puts (Words[Numb]);
  60. printf ("\n\n");
  61. }
  62. printf ("Результат:\n");
  63. row=1;
  64. while (row<=Numb) {
  65. for (i=0;i<=Numb;i++) {if (strcmp(expansion(Words[row]),expansion(Words[i]))) puts(Words[row]);}
  66. row++;}
  67. free (Words);
  68. system ("pause");
  69. }
Прошу прощения за такое большое количество переменных, не обессудьте. У меня здесь две проблемы (ну.. пока те, на которые я наткнулся) - 1)Не распознает слова = не выводит их на экран по отдельности (Выдает ошибку, вида "бла-бла-бла, адрес программы. Строка 49. Выражение (string !=NULL). бла-бла-бла") 2) Какая-то глупая ошибка в функции сортировки слова (или не глупая... я ее, в общем, найти не могу).. Прошу помощи, если вам не трудно) Я писал пока только для латинских букв.. и в строке не может быть ничего, окромя латинских букв и пробелов.. Потом, как с вашей божьей помощью разберусь с тем, что здесь неверно, пойду разбираться с русскими буквами и знаками препинания. Еще раз спасибо за внимание!

Решение задачи: «Вывести на экран слова, отличающиеся лишь порядком следования букв»

textual
Листинг программы
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. //создаем массив из слов введенной строки
  6. char **CreateArray(char line[], int len, int *cnt) {
  7.     int i = -1;
  8.     int count = 0;
  9.     char *buf = (char*) malloc(strlen(line) + 1); //копия исходной строки, уничтожается в процессе подсчета слов
  10.     strcpy(buf, line);
  11.  
  12.     char *delims = " ,.-\n";
  13.     char *word = strtok(buf, delims);
  14.     while (word != NULL) {
  15.         ++count;                                  //считаем фактическое кво слов
  16.         word = strtok(NULL, delims);
  17.     }
  18.     free(buf);
  19.     *cnt = count;
  20.     char **words = (char**) malloc(count * sizeof(char*)); //выделяем память под count слов длиной len
  21.     while (++i < count)
  22.         words[i] = (char*) malloc(len);
  23.  
  24.     word = strtok(line, delims); //заполняем массив словами из строки
  25.     i = -1;
  26.     while (word != NULL) {
  27.         strcpy(words[++i], word);
  28.         word = strtok(NULL, delims);
  29.     }
  30.     return words;
  31. }
  32.  
  33. //печать массива слов
  34. void ShowArray(char **words, int count) {
  35.     int i = -1;
  36.     while (++i < count)
  37.         printf("%s\n", words[i]);
  38. }
  39.  
  40. //копия массива слов
  41. char **CopyArray(char **words, int count) {
  42.     int i = -1;
  43.     char **copy = (char**) malloc(count * sizeof(char*));
  44.     while (++i < count) {
  45.         copy[i] = (char*) malloc(strlen(words[i]) + 1);
  46.         strcpy(copy[i], words[i]);
  47.     }
  48.     return copy;
  49. }
  50.  
  51. //очистка памяти
  52. void DestroyArray(char **words, int count) {
  53.     while (--count > -1)
  54.         free(words[count]);
  55.     free(words);
  56. }
  57.  
  58. //своп двух букв для сортировки по алфавиту
  59. void Swap(char *a, char *b) {
  60.     char t = *a;
  61.     *a = *b;
  62.     *b = t;
  63. }
  64.  
  65. //сортировка слова по алфавиту
  66. void SortLetters(char *word) {
  67.     int i, j, len = strlen(word);
  68.     for (i = 0; i < len - 1; i++)
  69.         for (j = i + 1; j < len; j++)
  70.             if (word[j] < word[i])
  71.                 Swap(&word[i], &word[j]);
  72. }
  73.  
  74. //собственно, решение задачи
  75. void FindBros(char **words, int count) {
  76.     int i, j;
  77.  
  78.     char **copy = CopyArray(words, count);          //создаем копию массива слов
  79.     for (i = 0; i < count; i++)
  80.         SortLetters(copy[i]); //в каждом слове переставляем все буквы по алфавиту
  81.  
  82.     int *mask = (int*) malloc(count * sizeof(int)); //маска: слово уже было найдено как "двойник по буквам" или нет
  83.     for (i = 0; i < count; i++)
  84.         mask[i] = 0;                                    //сначала - все 0
  85.  
  86.     for (i = 0; i < count - 1; i++) {
  87.         if (!mask[i])        //если i-ое слово еще не было "двойником по буквам"
  88.         {
  89.             printf("\n%20s: ", words[i]);
  90.             for (j = i + 1; j < count; j++)
  91.                 if (strcmp(copy[i], copy[j]) == 0) //сравниваем i-ую и j-ую копию, т.е. буквенный состав слов words[i] и words[j]
  92.                         {
  93.                     printf("%20s ", words[j]); //если буквенный состав совпал - выводим words[j]
  94.                     mask[j] = 1; //в маске помечаем j-ое слово как уже найденное в качестве "двойника"
  95.                 }
  96.         }
  97.     }
  98.  
  99.     DestroyArray(copy, count);
  100.     free(mask);
  101. }
  102.  
  103. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. int main() {
  105.     char str[BUFSIZ];
  106.     int len = 20, count = 0;
  107.     printf("Your string:\n");
  108.  
  109.     fgets(str, BUFSIZ, stdin);
  110.  
  111.     char **words = CreateArray(str, len, &count);
  112.     printf("\n\nYour words:\n");
  113.     ShowArray(words, count);
  114.  
  115.     printf("\n\nWords with the same set of letters:\n");
  116.     FindBros(words, count);
  117.  
  118.     DestroyArray(words, count);
  119.     getchar();
  120.     return 0;
  121. }

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

  1. Объявлены функции:
    • CreateArray
    • ShowArray
    • CopyArray
    • DestroyArray
    • Swap
    • SortLetters
    • FindBros
  2. В функции CreateArray создается массив из слов введенной строки.
  3. В функции ShowArray выводится на экран массив слов.
  4. В функции CopyArray создается копия массива слов.
  5. В функции DestroyArray освобождается память, выделенная под массив слов.
  6. В функции Swap происходит обмен двух букв.
  7. В функции SortLetters сортируются буквы в слове по алфавиту.
  8. В функции FindBros осуществляется поиск слов с одинаковым набором букв.
  9. В функции main происходит ввод строки, разделение ее на слова, вывод списка слов, поиск слов с одинаковым набором букв, освобождение памяти.

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


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

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

14   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы