Как мне получить букву, соответствующую количеству вхождений для сортировки?

Я делаю небольшое приложение ANSI C, используя GCC в Ubuntu. Программа находит значение вхождений для каждой буквы в строке, а затем должна отсортировать их в порядке убывания на основе количества вхождений.

Мой файл main.c:

/*
* preprocessor directives
*/
#include "bubbleSort.h"

/*
* global variables
*/
char Ar[] = "All Gaul is divided into three parts, one of which the Belgae inhabit, the Aquitani another, those who in their own language are called Celts, in our Gauls, the third. All these differ from each other in language, customs and laws. The river Garonne separates the Gauls from the Aquitani; the Marne and the Seine separate them from the Belgae. Of all these, the Belgae are the bravest, because they are furthest from the civilization and refinement of [our] Province, and merchants least frequently resort to them, and import those things which tend to effeminate the mind; and they are the nearest to the Germans, who dwell beyond the Rhine , with whom they are continually waging war; for which reason the Helvetii also surpass the rest of the Gauls in valor, as they contend with the Germans in almost daily battles, when they either repel them from their own territories, or themselves wage war on their frontiers. One part of these, which it has been said that the Gauls occupy, takes its beginning at the river Rhone ; it is bounded by the river Garonne, the ocean, and the territories of the Belgae; it borders, too, on the side of the Sequani and the Helvetii, upon the river Rhine , and stretches toward the north. From 'Caesar's Conquest of Gaul', Translator. W. A. McDevitte. Translator. W. S. Bohn. 1st Edition. New York. Harper & Brothers. 1869. Harper's New Classical Library. Published under creative commons and available at http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.02.0001";

/*
* main function
*/
int main(void) {
    /*array to hold count of each letter in alphabet*/
    int ABStats[ALPHABET_SIZE] = { 0 };

    /*array to hold letters of alphabet*/
    char chAlphabet[ALPHABET_SIZE] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

    /*pointers for use in finding frequency of characters*/
    char *pAr = Ar;
    char *pAlphabet = chAlphabet;
    int *pABStats = ABStats;

    GetFrequency(pAr, pABStats); /*get the frequency of each letter*/
    DisplayVHist(pABStats, ALPHABET_SIZE); /*display the frequency of each letter*/

    int i, j;
    for (i = ALPHABET_SIZE-1; i >= 0; i--) {
        for (j = 0; j < i; j++) {
            if (*(pABStats+j) < *(pABStats+j+1)) {
                Swap(pABStats+j, pABStats+j+1);
            }
        }
    }

    DisplayVHist(pABStats, ALPHABET_SIZE); /*display the frequency of each letter*/

    return EXIT_SUCCESS; /*return zero*/
}

Мой файл bubbleSort.c:

/*
* preprocessor directives
*/
#include "bubbleSort.h"

/*
* functions
*/
int GetFrequency(char *pAr, int *pABStats) {
    int chNum = 0;
    for (; *pAr != '\0'; pAr++) { /*check if at the end of the array*/
        char ch = *pAr; /*store current letter as a char*/
        if (isalpha(ch)) /*if character is a letter*/
            chNum = (toupper(ch) - 'A'); /*return ascii code of specified letter*/
        pABStats[chNum]++; /*store ascii value in array and increment array*/
    }
    return chNum;
}

void DisplayVHist(int *pABStats, int size) {
    int i, j;
    const float lengthAr = strlen(Ar); /*store length of array as a float*/
    for (i = 0; i < size; i++) { /*for each letter in the alphabet*/
        float chPercent = 100 * (*pABStats / lengthAr); /*calculate percentage*/
        printf("'%c' --> %6.3f percent --> %3d occurances --> ", (i + 'A'), chPercent, *pABStats);
        for (j = 0; j < (*pABStats / 2); j++) { /*for every two values being pointed to by pointer*/
            printf("%c",'*'); /*print asterisk*/
        }
        printf("\n");
        pABStats++;
    }
}

void Swap(int *pA, int *pB) {
    int temp;
    temp = *pA;
    *pA = *pB;
    *pB = temp;
}

Мой файл bubbleSort.h:

/*
* preprocessor directives
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define ALPHABET_SIZE 26

/*
* global variables
*/
extern char Ar[];

/*
* function prototypes
*/
int GetFrequency(char*, int*);
void DisplayVHist(int*, int);
void Swap(int*, int*);

В настоящее время он сортирует значения вхождения в порядке убывания, чего я и хочу, но затем, когда я отображаю результаты, «A» будет иметь самое высокое значение, что было бы неправильно. Я хочу, чтобы буквы были отсортированы так же, как и вхождения, чтобы буква с наибольшим числом вхождений (то есть «E») отображалась вверху списка вместе с ее вхождениями. Я создал массив символов с именем chAlphabet на случай, если он мне понадобится для этой цели.

Я должен использовать указатели для этого приложения, хотя это может быть не самый эффективный способ работы с этим приложением. Мне также необходимо использовать функцию Sort() внутри bubbleSort.c для сортировки.

Любая помощь будет оценена по достоинству. Я довольно новичок в программировании на C. Спасибо.


person Benjamin    schedule 01.03.2014    source источник
comment
Ваш файл пузырьковой сортировки на самом деле не сортируется; почему ты делаешь это в main? Это ужасная идея иметь непоследовательное имя файла.   -  person Filipe Gonçalves    schedule 01.03.2014
comment
@FilipeGonçalves Я знаю, что циклы for и вся логика должны выполняться внутри функции Swap().   -  person Benjamin    schedule 01.03.2014
comment
Во-первых, одна небольшая вещь: вы вызываете функцию DisplayVHist дважды, вы уверены, что хотите это сделать? Я думаю, вы, возможно, захотите сделать это только один раз в конце...   -  person Utkan Gezer    schedule 01.03.2014
comment
@ThoAppelsin Я вызывал его дважды для отладки, но вы правы, я хочу, чтобы он вызывался только один раз в конце.   -  person Benjamin    schedule 01.03.2014


Ответы (1)


Итак, вы уже можете поменять местами pABStats, статистику каждой буквы, теперь все, что вам нужно сделать, это также поменять местами алфавит. Для этого вам понадобится массив, как и pABStats для алфавита, который, к счастью, у вас уже есть: chAlphabet

Затем вам понадобится функция, которая будет выполнять обмен, как и функция Swap, которая у вас есть, но на этот раз вместо этого она должна принимать char * аргументов, например, так:

//in bubbleSort.c

void SwapAlphabet( char *pA, char *pB ) {
    char temp;
    temp = *pA;
    *pA = *pB;
    *pB = temp;
}

Вызовите это точно так же, как вы вызываете функцию Swap, и сразу после или перед чем угодно:

//inside the second for in main in main.c

if ( blabla ) {
    Swap( ... );
    SwapAlphabet( chAlphabet + j, chAlphabet + j + 1 ); // <-- added this
}

И, наконец, введите в функцию печати новый третий аргумент, DisplayVHist, который будет содержать chAlphabet из main:

//in bubbleSort.c
void DisplayVHist( ..., ..., char *chAlphabet ) { ... }

//and in bubbleSort.h
void DisplayVHist( ..., ..., char* );

И вызовите функцию с chAlphabet в качестве третьего аргумента от main:

//towards the end in main in main.c
DisplayVHist( ..., ..., chAlphabet );

Я врал раньше, но это будет последняя часть. Измените (i + 'A') внутри printf внутри DisplayVHist, чтобы сделать то, что вы уже сделали для pABStats там. Это должно быть что-то вроде этого:

//inside the DisplayVHist in bubbleSort.c

printf( "...", *chAlphabet, chPercent, *pABStats );
...
chAlphabet++;

Это должно быть так, если я не пропустил редактирование, которое я сделал здесь. Не стесняйтесь спрашивать о чем угодно, когда вам нужны дополнительные разъяснения.

person Utkan Gezer    schedule 01.03.2014
comment
Большое спасибо! Работает отлично! - person Benjamin; 01.03.2014
comment
Пожалуйста, Бенджамин, я надеюсь, что в то же время смог быть поучительным. - person Utkan Gezer; 01.03.2014
comment
Ты был. У меня большой опыт программирования, но я новичок в C, и ваши шаги помогли мне лучше понять мой код. Спасибо еще раз. - person Benjamin; 01.03.2014