在字符串数组中排序单词

时间:2015-10-19 23:33:34

标签: c arrays string

我的程序旨在允许用户输入字符串,我的程序将输出每个字母和单词的出现次数。我的程序还按字母顺序对单词进行排序。

我的问题是:我将看到的单词(首先未分类)和它们的出现作为表格输出,在我的表格中我不想要重复。的解决

例如,如果单词" to"被看过两次我只想要"到"在我的表格中只出现一次,输出出现次数。

我该如何解决这个问题?另外,为什么我不能简单地将string[i] == delim设置为应用于每个分隔符而不必为每个分隔符手动分配它?

编辑:修正了输出错误。但是,如何设置string[i]的条件等于我的代码中的任何分隔符,而不仅仅是为空格键工作?例如,在我的输出中,如果我输入"你,你"它会把你,你,#34;而不只是"你"。如何编写它以便删除逗号并比较"你,你"作为一个词。

感谢任何帮助。我的代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char delim[] = ", . - !*()&^%$#@<> ? []{}\\ / \"";
#define SIZE 1000

void occurrences(char s[], int count[]);
void lower(char s[]);


int main()

{

    char string[SIZE], words[SIZE][SIZE], temp[SIZE];

    int i = 0, j = 0, k = 0, n = 0, count;
    int c = 0, cnt[26] = { 0 };

    printf("Enter your input string:");
    fgets(string, 256, stdin);
    string[strlen(string) - 1] = '\0';
    lower(string);
    occurrences(string, cnt);
    printf("Number of occurrences of each letter in the text: \n");
    for (c = 0; c < 26; c++){
        if (cnt[c] != 0){
            printf("%c \t  %d\n", c + 'a', cnt[c]);
        }
    }
/*extracting each and every string and copying to a different place */
    while (string[i] != '\0')

    {
        if (string[i] == ' ')

        {
            words[j][k] = '\0';
            k = 0;
            j++;
        }

        else

        {
            words[j][k++] = string[i];
        }
        i++;
    }

    words[j][k] = '\0';
    n = j;

        printf("Unsorted Frequency:\n");
    for (i = 0; i < n; i++)

    {
        strcpy(temp, words[i]);
        for (j = i + 1; j <= n; j++)

        {
            if (strcmp(words[i], words[j]) == 0)

            {
                for (a = j; a <= n; a++)
                    strcpy(words[a], words[a + 1]);

                n--;
            }
        } //inner for
    }
    i = 0;

/* find the frequency of each word  */
    while (i <= n) {
        count = 1;
        if (i != n) {
            for (j = i + 1; j <= n; j++) {
                if (strcmp(words[i], words[j]) == 0) {
                    count++;
                }
            }
        }

        /* count - indicates the frequecy of word[i] */
        printf("%s\t%d\n", words[i], count);
        /* skipping to the next word to process */

        i = i + count;
    }
    printf("ALphabetical Order:\n");

    for (i = 0; i < n; i++)

    {
        strcpy(temp, words[i]);
        for (j = i + 1; j <= n; j++)

        {
            if (strcmp(words[i], words[j]) > 0)

            {
                strcpy(temp, words[j]);
                strcpy(words[j], words[i]);
                strcpy(words[i], temp);
            }
        } 
    }  
    i = 0;
    while (i <= n) {
        count = 1;
        if (i != n) {
            for (j = i + 1; j <= n; j++) {
                if (strcmp(words[i], words[j]) == 0) {
                    count++;
                }
            }
        }

        printf("%s\n", words[i]);
        i = i + count;
    }
    return 0;

}

void occurrences(char s[], int count[]){
    int i = 0;
    while (s[i] != '\0'){
        if (s[i] >= 'a' && s[i] <= 'z')
            count[s[i] - 'a']++;
        i++;
    }
}

void lower(char s[]){
    int i = 0;
    while (s[i] != '\0'){
        if (s[i] >= 'A' && s[i] <= 'Z'){
            s[i] = (s[i] - 'A') + 'a';
        }
        i++;
    }
}

2 个答案:

答案 0 :(得分:0)

我有问题的解决方案,其名称称为Wall。不,当你遇到一个你似乎无法解决的问题而不是你希望你的编译器发出的警告时,不要碰到你的头类:所有这些。

如果你使用-Wall编译C代码,那么你可以提交人们告诉你的所有错误,这就是为什么C是如此危险。但是一旦启用警告,编译器就会告诉你它们。

我的节目有4个:

for (c; c< 26; c++) {第一个c没有做任何事情,可以写成for (; c < 26; c++) {,也可以写成for (c = 0; c <26; c++) {

words[i] == NULL“声明无效”。那可能不是你想做的。编译器告诉你该行没有做任何事情。

“未使用的变量'文字'。”这也很清楚:你已经将文本定义为变量,但从未使用它。也许你的意思或者它可能是你认为你需要的变量。无论哪种方式,现在都可以。

“控制到达非空函数的结束”。在C main中通常定义为int main,即main返回一个int。标准做法是如果程序成功完成则返回0,而其他一些值则返回错误。在main的末尾添加return 0;将起作用。

答案 1 :(得分:0)

您可以简化分隔符。任何 a-z(在下限之后)都是分隔符。你不[需要]关心它是哪一个。这是一个词的结尾。不是指定分隔符,而是指定字chars的字符(例如,如果字是C符号,字chars将是:A-Z,a-z,0-9和_)。但是,看起来你只想要a-z。

以下是一些[未经测试]的例子:

void
scanline(char *buf)
{
    int chr;
    char *lhs;
    char *rhs;
    char tmp[5000];

    lhs = tmp;

    for (rhs = buf;  *rhs != 0;  ++rhs) {
        chr = *rhs;

        if ((chr >= 'A') && (chr <= 'Z'))
            chr = (chr - 'A') + 'a';

        if ((chr >= 'a') && (chr <= 'z')) {
            *lhs++ = chr;
            char_histogram[chr] += 1;
            continue;
        }

        *lhs = 0;
        if (lhs > tmp)
            count_string(tmp);

        lhs = tmp;
    }

    if (lhs > tmp) {
        *lhs = 0;
        count_string(tmp);
    }
}

void
count_string(char *str)
{
    int idx;
    int match;

    match = -1;
    for (idx = 0;  idx < word_count;  ++idx) {
        if (strcmp(words[idx],str) == 0) {
            match = idx;
            break;
        }
    }

    if (match < 0) {
        match = word_count++;
        strcpy(words[match],str);
    }

    word_histogram[match] += 1;
}

使用单独的数组很难看。使用结构可能更好:

#define STRMAX        100        // max string length
#define WORDMAX        1000        // max number of strings

struct word {
    int word_hist;                // histogram value
    char word_string[STRMAX];    // string value
};

int word_count;                    // number of elements in wordlist
struct word wordlist[WORDMAX];    // list of known words