排序字符串忽略大小写;大写优先的相等字符串

时间:2019-02-15 20:37:19

标签: c

我写了这样的一段代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

int compare_str(const void* a, const void* b)
{
    char * const * aa=a;
    char * const * bb=b;
    return strcasecmp(*aa, *bb);
}

int sort_alphabetically(char tab[])
{
    if(strlen(tab)<1 || tab[strlen(tab)-1]=='\n')
    {
        return 1;
    }
    for(unsigned int i=0; i<strlen(tab); i++)
    {
        if(tab[i]=='-')
        {
            return 1;
        }
    }
    int spaces_count=0;
    int first=0;
    int ch=0;
    for(unsigned int i=1; i<strlen(tab); i++)
    {
        if(tab[i]!=' ')
            first=1;
        if(tab[0]==' ' && tab[1]==' ')
            ch=1;
        if(tab[i]==' ' && tab[i+1]>=33 && tab[i+1]<=126 && first==1)
            spaces_count++;
    }
    int words_count=spaces_count+1;
    char **words=malloc(words_count * sizeof(char*));
    char *pch;
    int word_idx=0;
    pch=strtok(tab, " ");
    while(pch!=NULL)
    {
        words[word_idx++]=strdup(pch);
        pch=strtok(NULL, " ");
    }
    qsort(words, words_count, sizeof(char*), compare_str);
    for(int i=0; i<words_count; i++)
    {
        for(unsigned int j=0; j<strlen(words[i]); j++)
        {
            if(ch==0)
                *(tab++)=words[i][j];
            else
                if(words[i][j]!=' ')
                {
                    *(tab++)=words[i][j];
                    ch=0;
                }
        }
        if(i!=words_count-1)
            *(tab++)=' ';
        else
            *(tab++)='\0';
        free(words[i]);
    }
    free(words);
    for(unsigned int i=0; i<strlen(tab); i++)
        if(tab[i]==' ' && tab[i+1]==' ')
            tab[i]='\0';
    return 0;
}

int main()
{
    char input[1000];
    printf("Enter text: ");
    if(fgets(input, 1000, stdin))
    {
        if(input[strlen(input)-1]=='\n')
            input[strlen(input)-1]='\0';
        if(sort_alphabetically(input))
        {
            fprintf(stderr, "Incorrect input data");
            return 2;
        }
        else
            printf("%s", input);
    }
    return 0;
}

它按用户输入的字母顺序对单词进行排序。关键是它能胜任工作,但我也想检查一下单词是否相同。如果它们是首字母大写的单词,则应留在首字母小写的单词之前。 例如:

输入文字:

技术是我们对人类的主要威胁

输出应为:

成为人类的对我们来说是主要的技术

但这是

成为人类的人对我们进行技术维修的技术

我应该进行哪些更改?

2 个答案:

答案 0 :(得分:4)

要实现所需的功能,必须稍微更改比较功能。 正如您所观察到的,strcasecmp()将使两个相等的单词的顺序不确定。因此,如果strcasecmp()认为两个单词相等(不区分大小写),则必须将它们区分大小写进行比较(使用适当的函数,您将猜测哪个;)并返回该结果。否则,只需返回strcasecmp()的结果即可。

答案 1 :(得分:2)

您的比较函数compare_strstrcasecmp()的包装,它显式且专门执行不区分大小写的比较。如果您希望区分大小写的比较,则可以将其交换为提供一个的函数,或者编写一个替换函数,或者仅向compare_str添加代码以在strcasecmp()返回0的情况下进行更精细的区分,完全取决于您想要的顺序。

由于问题的性质和细节使我怀疑这是一项学术练习,因此我将由您自己来解决细节。目的是compare_str()如果第一个参数应在第二个参数之前排序,则必须返回负数;如果第二个参数应在第一个参数之前排序,则必须返回正数;如果可接受任何顺序,则返回零。