сортировка слов (Пузырёк)

Тема в разделе "WASM.BEGINNERS", создана пользователем Nok, 10 фев 2008.

  1. Nok

    Nok New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2008
    Сообщения:
    33
    Есть программа, сортирующая слова в алфавитном порядке методом пузырька (BubbleSort). Считка и запись в текстовые файлы, их там три: 1й-исходный, 2й-промежуточный, и 3й-отсортированный. Все хорошо но никак не могу присобачить порядковые номера к каждой строчке..так чтобы во втором файле получилось!

    1 шла
    2 собака
    3 по
    4 роялю

    а в третем соответственно..

    3 по
    4 роялю
    2 собака
    1 шла

    Код (Text):
    1. #include <iostream>
    2. #include <windows.h>
    3. #include <cstring>
    4. using namespace std;
    5.  
    6. // сортировка пузырьком
    7. void bubbleSort(char **a,int size) {
    8.     int i, j;
    9.     char* x;
    10.  
    11.     for( i=0; i < size; i++) {            // i - номер прохода
    12.         for( j = size-1; j > i; j-- ) {     // внутренний цикл прохода
    13.             if (strcmp(a[j-1],a[j])>0){
    14.                 x=a[j-1];
    15.                 a[j-1]=a[j];
    16.                 a[j]=x;
    17.             }
    18.         }
    19.     }
    20. }
    21.  
    22. // Сохранение массива слов
    23. void save(char **a,FILE *f){
    24.     int i=0;
    25.     // пока не встретим NULL пишем в файл
    26.     while(a[i]!=NULL){
    27.         fputs(a[i++],f);
    28.         fputs("\n",f);
    29.     }
    30. }
    31.  
    32. void main(){
    33.     int size =10000; // размер массива слов (массива указателей на char)
    34.     int str_size =512; // размер одной строки
    35.     char **ar = new char*[size]; // выделяем память под массив указателей
    36.     for(int i=0;i<size;i++) // заполняем массив NULL_указателями
    37.         ar[i] = NULL;// Изначально массив пустой
    38. FILE *f = fopen("1.txt","r"); // открываем исходный файл
    39.     i=0;
    40.     char buf[128]; // под строку
    41.     char *token; // вспомагательн для strtok в каждый укахатель адрес след ликсемы слаживать
    42.     char sep[] =  " -,.!)(?:\ t\n\" "; // разделители
    43. // пока не конец файла и не предел массива строк запоминаем строки в массив строк
    44.     while(!feof(f) && i<size){
    45.         fgets(buf,128,f);
    46.         token = strtok(buf,sep);
    47.  
    48.         while(token!=NULL){// если нет след слова то 0 выход
    49.             ar[i] = new char[54];
    50.             strcpy(ar[i],token);
    51.             i++;
    52.             token = strtok(NULL,sep);
    53.         }
    54.         }
    55.  
    56.    
    57.  
    58.  
    59. fclose(f); // закрываем исходный файл
    60.  
    61. f = fopen("2.txt","w");
    62.     save(ar,f);
    63.     fclose(f);
    64.  
    65.     bubbleSort (ar,i); // Сортируем
    66. f = fopen("3.txt","w");
    67.     save(ar,f);
    68.     fclose(f);
    69.  
    70. // освобождаем память
    71.     for(i=0;i<size;i++)
    72.         delete ar[i];
    73.  
    74.     delete [] ar;
    75.  
    76. }
    Очень буду благодарен если подскажете как реализовать!..
     
  2. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    нужно при сравнении исключить номера из строк. Грубый пример, если номер строки имеет только один символ (и после него один пробел):
    Код (Text):
    1. if (strcmp(a[j-1] + 2,a[j] + 2)>0){
     
  3. Nok

    Nok New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2008
    Сообщения:
    33
    да хоть так!..
    Код (Text):
    1. if (strcmp(a[j-1] + 5,a[j] + 5)>0){
    трабл в том, что не могу записать в файл нумерацию!..
    ничего лучше в голову не приходит..

    Код (Text):
    1. void save(char **a,FILE *f){
    2.     int j,i=0;
    3.     while(a[i]!=NULL){
    4.         fputs(a[i++],f);
    5.                 for (j=0; j<1000; j++)
    6.                  fputs(S[j],f);
    7.         fputs("\n",f);
    8.     }
     
  4. boobl

    boobl New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2008
    Сообщения:
    18
    Можно в первых двух байтах строки хранить порядковое число, которое задается при парсинге строк в первый раз, а потом делать сравнение уже со смещением + 2.

    типа того:
    Код (Text):
    1. #include <iostream>
    2. #include <windows.h>
    3. #include <cstring>
    4. using namespace std;
    5.  
    6. // сортировка пузырьком
    7. void bubbleSort(char **a,int size) {
    8.     int i, j;
    9.     char* x;
    10.  
    11.     for( i=0; i < size; i++) {            // i - номер прохода
    12.         for( j = size-1; j > i; j-- ) {     // внутренний цикл прохода
    13.             if (strcmp(a[j-1] + 2,a[j] + 2)>0){
    14.                 x=a[j-1];
    15.                 a[j-1]=a[j];
    16.                 a[j]=x;
    17.             }
    18.         }
    19.     }
    20. }
    21.  
    22. // Сохранение массива слов
    23. void save(char **a,FILE *f){
    24.     int i=0;
    25.     // пока не встретим NULL пишем в файл
    26.     while(a[i]!=NULL){
    27.         fprintf(f, "%d %s\n", *((short*)(a[i])), a[i] + 2);
    28.         i++;
    29.     }
    30. }
    31.  
    32. int main(){
    33.     int size =10000; // размер массива слов (массива указателей на char)
    34.     int str_size =512; // размер одной строки
    35.     char **ar = new char*[size]; // выделяем память под массив указателей
    36.     int i;
    37.     for(i=0;i<size;i++) // заполняем массив NULL_указателями
    38.         ar[i] = NULL;// Изначально массив пустой
    39. FILE *f = fopen("1.txt","r"); // открываем исходный файл
    40.     i=0;
    41.     char buf[128]; // под строку
    42.     char *token; // вспомагательн для strtok в каждый укахатель адрес след ликсемы слаживать
    43.     char sep[] =  " -,.!)(?:\\ t\n\" "; // разделители
    44. // пока не конец файла и не предел массива строк запоминаем строки в массив строк
    45.     while(!feof(f) && i<size){
    46.         fgets(buf,128,f);
    47.         token = strtok(buf,sep);
    48.  
    49.         while(token!=NULL){// если нет след слова то 0 выход
    50.             ar[i] = new char[54];
    51.             strcpy((ar[i] + 2),token);
    52.             *((short*)(ar[i])) = i + 1;
    53.             i++;
    54.             token = strtok(NULL,sep);
    55.         }
    56.         }
    57.  
    58.    
    59.  
    60.  
    61. fclose(f); // закрываем исходный файл
    62.  
    63. f = fopen("2.txt","w");
    64.     save(ar,f);
    65.     fclose(f);
    66.  
    67.     bubbleSort (ar,i); // Сортируем
    68. f = fopen("3.txt","w");
    69.     save(ar,f);
    70.     fclose(f);
    71.  
    72. // освобождаем память
    73.     for(i=0;i<size;i++)
    74.         delete ar[i];
    75.  
    76.     delete [] ar;
    77.     return 0;
    78. }
     
  5. Nok

    Nok New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2008
    Сообщения:
    33
    мы уже сместили на 2 в начале кода так что лучше записать так ..
    Код (Text):
    1. fprintf(f, "%d %s\n", *((short*)(a[i])), a[i]);
    ..но записывает нумерацию соотвеццно в байтовом виде!..
     
  6. boobl

    boobl New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2008
    Сообщения:
    18
    И совсем не лучше: смещенную строку мы никуда не сохраняли, так что пускай будет a + 2.
     
  7. Nok

    Nok New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2008
    Сообщения:
    33
    а ты попробуй запустить с a + 2 посмотри, что делает с ключами..
    а потом с моим!..


    Код (Text):
    1. #include <iostream>
    2. #include <windows.h>
    3. #include <cstring>
    4. using namespace std;
    5.        ostream &operator<<(ostream &obj, char *strWin)
    6. {
    7.     char strDos[255];
    8.     CharToOem(strWin,strDos);
    9.     obj.write(strDos,strlen(strDos));
    10.     return obj;
    11. }
    12.  
    13.  
    14. void bubbleSort(char **a,int razm) {
    15.     int i, j;
    16.     char* x;
    17.  
    18.         SetConsoleTitle("Bubblesort");
    19.  
    20.     for( i=0; i < razm; i++) {            // i - номер прохода
    21.         for( j = razm-1; j > i; j-- ) {     // внутренний цикл прохода
    22.             if (strcmp(a[j-1] + 2,a[j] + 2)>0){
    23.                 x=a[j-1];
    24.                 a[j-1]=a[j];
    25.                 a[j]=x;}}}}
    26. // Сохранение массива слов
    27. void save(char **a,FILE *f){
    28.     int j,i=0;
    29.         char S[255];
    30.     while(a[i]!=NULL){
    31.         fprintf(f, "%d %s\n", *((int*)(a[i])), a[i]);
    32.         i++;
    33.  
    34.     }
    35. }
    36.  
    37. void main(){
    38.     int razm =10000; // размер массива слов (массива указателей на char)
    39.     int str_razm =512; // размер одной строки
    40.     char **ar = new char*[razm];
    41.     for(int i=0;i<razm;i++)
    42.         ar[i] = NULL;
    43. FILE *f = fopen("1.txt","r");
    44.     int i=0;
    45.     char buf[128]; // под строку
    46.     char *token; // вспомагательн для strtok в каждый указатель адрес след ликсемы слаживать
    47.     char other[] =  " -,.!)(?:\ t\n\" "; // разделители
    48. // пока не конец файла и не предел массива строк запоминаем строки в массив строк
    49.     while(!feof(f) && i<razm){
    50.         fgets(buf,128,f);
    51.         token = strtok(buf,other);
    52.  
    53.         while(token!=NULL){// если нет след слова то 0 выход
    54.             ar[i] = new char[54];
    55.             strcpy(ar[i],token);
    56.             i++;
    57.             token = strtok(NULL,other);
    58.         }
    59.         }
    60.  
    61. fclose(f);
    62.  
    63. f = fopen("2.txt","w");
    64.     save(ar,f);
    65.     fclose(f);
    66.     bubbleSort (ar,i); // Сортируем
    67. f = fopen("3.txt","w");
    68.     save(ar,f);
    69.     fclose(f);
    70.  
    71.     cout<<"Нажмите для окончания ENTER!";
    72.     getchar();
    73.     }
    отож!..
     
  8. boobl

    boobl New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2008
    Сообщения:
    18
    Я вижу в твоем коде что ты выводишь первые 4 байта строки как число, а потом строку. Причем в тех самых 4 байтах лежит начало строки, ибо больше ничего ты туда не кладешь.
    В результате получается:
    2.txt
    14740472 шла
    -522064143 собака
    61167 по
    -335548688 роялю

    3.txt
    61167 по
    14740472 шла
    -522064143 собака
    -335548688 роялю

    если брать мою программу, без каких-либо изменений, выходит следующее:
    2.txt
    1 шла
    2 собака
    3 по
    4 роялю

    3.txt
    3 по
    4 роялю
    2 собака
    1 шла

    А теперь напрашивается вопрос: ты мой код вообще тестил? И если тестил то чего тебе в нем не нравится?
     
  9. Nok

    Nok New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2008
    Сообщения:
    33
    сорри, чувак..пропустил строчку кода!..исправил..огромное спасибо!..
     
  10. Nok

    Nok New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2008
    Сообщения:
    33
    кому интересно..сортировка слов методом простых вставок=)..
    еще раз всем спасибо!..


    Код (Text):
    1. #include <iostream>
    2. #include <windows.h>
    3. #include <cstring>
    4. using namespace std;
    5.        ostream &operator<<(ostream &obj, char *strWin)
    6. {
    7.      char strDos[255];
    8.      CharToOem(strWin,strDos);
    9.      obj.write(strDos,strlen(strDos));
    10.      return obj;
    11. }
    12.  
    13. //*********************************************************************
    14. //*****************************INSERT SORT ****************************
    15. //*********************************************************************
    16. void InsertSort(char **a,int razm) {
    17.      int i, j;
    18.      char* x;
    19.  
    20.         SetConsoleTitle("**********************INSERTSORT*********************");
    21.  
    22. for ( i=0; i < razm; i++) {  // цикл проходов, i - номер прохода
    23. x=a[i];
    24.     for ( j=i-1; j>=0 &&(strcmp( a[j]+2, x+2)>0); j--)
    25.       a[j+1] = a[j];       // сдвигаем элемент направо, пока не дошли
    26.  
    27.      // место найдено, вставить элемент
    28.     a[j+1] = x;  }
    29.  
    30.     }
    31. // Сохранение массива слов
    32. void save(char **a,FILE *f){
    33.     int j,i=0;
    34.         char S[255];
    35.     while(a[i]!=NULL){
    36.         fprintf(f, "%d %s\n", *((short*)(a[i])), a[i]+2);
    37.         i++;
    38.  
    39.     }
    40. }
    41.  
    42. void main(){
    43.     int razm =10000; // размер массива слов (массива указателей на char)
    44.     int str_razm =512; // размер одной строки
    45.     char **ar = new char*[razm];
    46.     for(int i=0;i<razm;i++)
    47.         ar[i] = NULL;
    48. FILE *f = fopen("1.txt","r");
    49.     int i=0;
    50.     char buf[128]; // под строку
    51.     char *token; // вспомагательн для strtok в каждый указатель адрес след ликсемы слаживать
    52.     char other[] =  " -,.!)(?:\ t\n\" "; // разделители
    53. // пока не конец файла и не предел массива строк запоминаем строки в массив строк
    54.     while(!feof(f) && i<razm){
    55.         fgets(buf,128,f);
    56.         token = strtok(buf,other);
    57.  
    58.         while(token!=NULL){// если нет след слова то 0 выход
    59.             ar[i] = new char[54];
    60.             strcpy(ar[i]+2,token);
    61.                         *((short*)(ar[i])) = i + 1;
    62.             i++;
    63.             token = strtok(NULL,other);
    64.         }
    65.         }
    66.  
    67. fclose(f);
    68.  
    69. f = fopen("2.txt","w");
    70.     save(ar,f);
    71.     fclose(f);
    72.     InsertSort (ar,i); // Сортируем
    73. f = fopen("3.txt","w");
    74.     save(ar,f);
    75.     fclose(f);
    76.  
    77.     cout<<"Нажмите для окончания ENTER!";
    78.     getchar();
    79.     }
    и еще..Кнут жжот!..
     
  11. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907