首页 > 试题广场 >

字符串排序

[编程题]字符串排序
  • 热度指数:305096 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}对于给定的由可见字符和空格组成的字符串,按照下方的规则进行排序:
\hspace{23pt}\bullet\,按照字母表中的顺序排序(不区分大小写);
\hspace{23pt}\bullet\,同一字母的大小写同时存在时,按照输入顺序排列;
\hspace{23pt}\bullet\,非字母字符保持原来的位置不参与排序;
\hspace{15pt}直接输出排序后的字符串。

\hspace{15pt}字符串由 ASCII 码在 32126 范围内的字符组成。您可以参阅下表获得其详细信息。

../图片/可见字符集Ascii.png


输入描述:
\hspace{15pt}在一行上输入一个长度为 1 \leqq {\rm length}(s) \leqq 1000 ,由上表中的字符组成的字符串 s


输出描述:
\hspace{15pt}输出一个字符串,代表按照规则排序后的字符串。
示例1

输入

BabA

输出

aABb
示例2

输入

Hello NowCoder!

输出

CdeeH llNooorw!
#include<stdio.h>
#include<string.h>

int main()
{
    char a[1001],b[1000],e;
    int i,j,l=0,k=0;
    fgets(a, sizeof(a), stdin);
    for (i = 0; i < 26; i++)
    {
        for (j = 0; j < strlen(a); j++)
        {
            if (a[j] == 'A' + i || a[j] == 'a' + i)
            {
                b[l] = a[j];
                l++;
            }
        }  
    }
    for (i = 0,j = 0; i < strlen(a); i++)
    {
        if (a[i] < 'A' || (a[i] > 'Z' && a[i] < 'a') || a[i]>'z')
            printf("%c", a[i]);
        else
        {
            printf("%c", b[j]);
            j++;
        }
    }
}
发表于 2025-07-11 14:13:30 回复(0)
#include <stdio.h>
#include <ctype.h>
#include <string.h>

void sort_string(char* str, size_t len) {
    char letters[1000];   // 存储所有字母字符
    int positions[1000];  // 存储所有字母字符的原始位置
    int letter_count = 0;

    // 步骤1: 提取字母字符及其原始位置
    for (int i = 0; i < len; i++) {
        if (isalpha(str[i])) {
            letters[letter_count] = str[i];
            positions[letter_count] = i;
            letter_count++;
        }
    }

    // 步骤2: 冒泡排序(不区分大小写,稳定排序)
    for (int i = 0; i < letter_count - 1; i++) {
        for (int j = 0; j < letter_count - i - 1; j++) {
            // 比较相邻字符的小写形式
            char a = tolower(letters[j]);
            char b = tolower(letters[j + 1]);
            if (a > b || (a == b && positions[j] > positions[j + 1])) {
                // 交换字符
                char temp_char = letters[j];
                letters[j] = letters[j + 1];
                letters[j + 1] = temp_char;
            }
        }
    }

    // 步骤3: 将排序后的字符按原始位置放回
    for (int i = 0; i < letter_count; i++) {
        str[positions[i]] = letters[i];
    }
}

int main() {
    char str[1000] = {0};
    scanf("%[^\n]",str);
    size_t len = strlen(str);
    sort_string(str, len);
    printf("%s\n", str);
    return 0;
}
发表于 2025-02-28 21:08:17 回复(0)
#include <stdio.h>
#include <string.h>

int main() {
    char str[1000];
    gets(str);

    int length = strlen(str);
    char temp[length];
    /* 1、先将所有的字母a-z, A-Z排序*/
    int k = 0;
    for (int i = 0; i < 26; i++) {
        for (int j = 0; j < length; j++) {
            if ( str[j] == ('a' + i) || str[j] == ('A' + i)) {
                temp[k++] = str[j]; // 排好序的字符串就存放在temp中
            }
        }
    }

    /* 2、将temp按照顺序写回到str中,遇到非字母就跳过 */
    k = 0;
    for (int i = 0; i < length; i++) {
        if (((str[i] >= 'a') && (str[i] <= 'z')) || ((str[i] >= 'A') &&
                (str[i] <= 'Z'))) {
            str[i] = temp[k++];
        }
    }

    printf("%s", str);

    return 0;
}


发表于 2024-09-09 23:12:03 回复(0)
#include <stdio.h>
#include <string.h>
int main() {
    char arr[1001];
    char ch[1001];
    int n=0;
    gets(arr);
    int len=strlen(arr);
    for (int i=0;i<=len-1;i++){
        for(int j=0;j<=len-1;j++){
            if(arr[j]-'a'==i || arr[j]-'A'==i){
                ch[n]=arr[j];
                
                n++;
            }
        }
    }
    n=0;
    for(int i=0;i<=len-1;i++){
        if((arr[i]>='a'&&arr[i]<='z') || (arr[i]>='A'&&arr[i]<='Z')){
            arr[i]=ch[n];
            n++;
            printf("%c",arr[i]);

        }
        else {
        printf("%c",arr[i]);
        }
    }
    return 0;
}

发表于 2024-09-01 23:28:57 回复(0)
#include <stdio.h>
#include <string.h>

int letter(char x) {
    if (x >= 'a' && x <= 'z') {
        x = x - ('a' - 'A');
        return x;
    } else if (x >= 'A' && x <= 'Z') return x;
    else return -1;
}
int main() {
    char s[1005];
    int pos[1005];
    gets(s);
    int a, b;
    char temp;
    int x;
    for (int i = 0; i < strlen(s); i++) {
        pos[i] = i;
    }
    for (int i = 0; i < strlen(s) - 1; i++) {
        for (int j = i + 1; j < strlen(s); j++) {
            a = letter(s[i]);
            b = letter(s[j]);
            if (a != -1 && b != -1) {
                if (a > b) {
                    temp = s[i] ;
                    s[i] = s[j];
                    s[j] = temp;
                    x = pos[i];
                    pos[i] = pos[j];
                    pos[j] = x;
                } else if (a == b) {
                    if (pos[i] > pos[j]) {
                        temp = s[i] ;
                        s[i] = s[j];
                        s[j] = temp;
                        x = pos[i];
                        pos[i] = pos[j];
                        pos[j] = x;
                    }
                }
            }
        }
    }
    printf("%s", s);
}

发表于 2024-05-15 15:07:41 回复(0)
看到某个写法受到启发写了个简洁的,思路就是按照a到z的顺序输出,在输出到符号的位置输出符号。实际输出与预期输出是一样的可为什么过不了呢?

#include <stdio.h>
#include <string.h>
int main() {
    char str[1001] = { 0 }; int output = 0;  /*output表示已经输出的字符数量*/
    gets(str);
    int len = strlen(str);
    for (int i = 0; i < 26; i++)
    {
        char word = 'A' + i;
        for (int j = 0; j < len; j++)
        {
            if (str[output]<'A' || str[output]>'z' || (str[output]>'Z'&&str[output] < 'a')) /*即为非字母*/
            {
                printf("%c",str[output]);
                output++;
            }
            if (str[j] == word || str[j] == word + 32)
            {
                printf("%c", str[j]);
                output++;
            }
        }
    }
    return 0;
}

编辑于 2024-03-24 18:05:49 回复(0)
#include <stdio.h>
#include <string.h>

int main() {
    char str[1000];
    int str_count[1000];
    memset(str_count,0,sizeof(str_count));
    scanf("%[^\n]\n",str);
    char *x,*y=str;
    for(char i='A';i<='Z';i++)
    {
        for(int j=0;j<strlen(str);j++)
        {
            if(str_count[j])
            continue;
            else if(str[j]>='a'&&str[j]<='z')
            {
                if(str[j]=i-'A'+'a')
                {
                    printf("%c",str[j]);
                    str_count[j]++;
                }
            }
            else if(str[j]>='A'&&str[j]<='Z')
            {
                if(str[j]=i)
                {
                    printf("%c",str[j]);
                    str_count[j]++;
                }
            }
            else {
                printf("%c",str[j]);
                str_count[j]++;
            }
        };
    }
    
    return 0;
}

为什么会这样啊????
编辑于 2024-02-25 19:08:36 回复(1)
#include <stdio.h>
int main(void)
{
    char str[100], stand[100] ;
    while(scanf("%s", str)==1){
    int a, b,c=strlen(str),k=0;
    for (b = 'A'; b <= 'Z'; b++)
    {   
        for (a = 0; a < c; a++)
        {
            
            if (str[a] == b || str[a] - 32 == b)
            {
                stand[k] = str[a];
                k++;
            }
        }
    }

    k = 0;
    for (a = 0; a < c; a++)
    {
        if (str[a] >= 'A' && str[a] <= 'Z' || str[a] >= 'a' && str[a] <= 'z')
            printf("%c", stand[k++]);
        else printf("%c", str[a]);
    }   
    printf("\n");
    }
    return 0;
}
发表于 2024-01-28 23:03:50 回复(0)
//思路:读取字符串中的所有字母,由于字母不分大小写,所以只要遇到字母,就加到alp字符组中
//输出时遍历str,遇到字母就输出alp中的字符,遇到非字母则输出str中的内容

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

int main(){
    char str[1001] = {'\0'},alp[1001] = {'\0'};
    int n = 0;
    gets(str);
    for(int i = 0 ; i < 26 ; i++ ){ //从'a'/'A'开始遍历
        for(int j = 0 ; j < strlen(str) ; j++){
            if(str[j] - 'a' == i || str[j] - 'A' == i ) //例如:str[j]中遇到b/B,则会把str[j]放在alp[n]中,然后n++
                alp[n++] = str[j];
        }
    }
    //printf("%s\n",alp);   //输出alp中的所有字母
    n = 0;
    for(int i = 0 ; i < strlen(str) ; i++ ){
        if( (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') ){
            printf("%c",alp[n++]);
        }
        else
            printf("%c",str[i]);
    }
    return 0;
}

编辑于 2023-12-23 19:43:34 回复(0)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
struct word
{
    char c;
    int index;//输入序号
};


int compare(const void *a, const void *b) 
{
    struct word *wordA = (struct word *)a;
    struct word *wordB = (struct word *)b;
    
    //比较字母大小,不考虑大小写,全部按照大写字母比较
    int diff = toupper(wordA->c) - toupper(wordB->c);
    if (diff != 0) 
    {
        return diff;
    }
    
    //如果字母相同,比较输入序号
    return wordA->index - wordB->index;
}

void sort(char str[],int len)
{
    struct word arr[1000]={0};//结构体数组,存放字母和输入序号
    int i=0;
    int j=0;
    for(i=0;i<len;i++) 
    {
        if(isalpha(str[i]))//是字母就存到排序数组中
        {
            arr[j].c = str[i];
            arr[j].index =i;
            j++;
        }
    }

    //compaer(arr,j);//排序
    qsort(arr, j, sizeof(struct word), compare);//使用qsort函数

    for(i =0,j=0;i<len;i++)//排序后替换到原来的数组中
    {
        if(isalpha(str[i]))
        {
            str[i]=arr[j].c;
            j++;
        }
    }
}

int main() 
{
    //输入
    char str[1001]={0};
    fgets(str,sizeof(str),stdin);
    int len= strlen(str)-1;
    //排序
    sort(str,len);
    //输出
    printf("%s",str);
    return 0;
}
//a-z
//1>2
//非英文不动

//这是排序过程的实现函数,也可以制定好规则后使用qsort函数。
//结构体数组按照字母大小排序
// void compaer(struct word arr[],int n)
// {
//     int i =0;
//     int j =0;
//     char tmp=0;
//     int tmp_index=0;
//     //冒泡排序
//     for(i=0;i<n;i++)
//     {
//         for(j=i;j<n;j++)
//         {
//             //比较字母大小,不考虑大小写,全部按照大写字母比较
//             if(toupper(arr[i].c)-toupper(arr[j].c)>0)
//             {
//                 //交换字母
//                 tmp =arr[i].c;
//                 arr[i].c =arr[j].c;
//                 arr[j].c =tmp;
//                 //交换序号
//                 tmp_index =arr[i].index;
//                 arr[i].index =arr[j].index;
//                 arr[j].index =tmp_index;
//             }
//             //如果字母相同,比较输入序号
//             else if(toupper(arr[i].c)-toupper(arr[j].c) ==0)
//             {
//                 if(arr[i].index>arr[j].index)
//                 {
//                 //交换字母
//                     tmp =arr[i].c;
//                     arr[i].c =arr[j].c;
//                     arr[j].c =tmp;
//                     //交换序号
//                     tmp_index =arr[i].index;
//                     arr[i].index =arr[j].index;
//                     arr[j].index =tmp_index;
//                 }
//             }
//         }
//     }
// }

发表于 2023-12-12 13:12:01 回复(0)
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main() {
    char str[1001];
    while (gets(str) != NULL) {
        int len = strlen(str);
        for(int i = 0;i<len-1 ;i++)
        {
            for(int j = 0;j<len-i-1;j++)
            {
                //判断是不是字母
                if(isalpha(str[j]))
                {
                    //是就冒泡排序
                    int k = j+1;
                    while(!isalpha(str[k])&&k<len-i-1)
                    {
                        k++;
                    }
                    if(toupper(str[j])-toupper(str[k])>0&& isalpha(str[k]))
                    {
                        char tmp = str[j];
                        str[j] = str[k];
                        str[k] = tmp;
                    }
                }
                else {
                continue;
                }
            }
        }
        for(int i = 0;i<len;i++)
        {
            printf("%c",str[i]);
        }
    }
    return 0;
}
发表于 2023-10-09 15:50:16 回复(0)
#include <stdio.h>
#include <ctype.h>  // 包含 isalpha() 函数的头文件
#include <stdlib.h> // 包含 qsort() 函数的头文件

// 比较两个字符并忽略大小写的函数
int compare(const void* a, const void* b) {
    // 将参数转换为 char 指针并解引用,将两个字符都转换为小写,然后相减得到差值
    return tolower(*(char*)a) - tolower(*(char*)b);
}

int main() {
    char str[1000], alp[1000]; // 输入字符串、排序字符串
    int id, len; // 输入字符串索引、排序字符串长度

    scanf("%s", str); // 从标准输入读取字符串到输入字符串中
    for (id = 0, len = 0; str[id]; id++) // 遍历输入字符串
        if (isalpha(str[id])) // 检查当前字符是否是字母
            alp[len++] = str[id];// 添加到排序字符串并更新长度
    qsort(alp, len, sizeof(char), compare); // 按字母顺序排序
    for (id = 0, len = 0; str[id]; id++) // 再次遍历输入字符串
        if (isalpha(str[id])) // 检查当前字符是否是字母
            str[id] = alp[len++]; // 用排序字符串的字符替换它
    printf("%s", str); // 将修改后的字符串打印到标准输出
}

发表于 2023-03-22 18:25:29 回复(0)
字母数量规模较小,直接空间换时间,用26个队列存储字母,总共遍历两边即可。
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main() {
    char queue[26][1000] = {0};
    int tail[26] = {0};
    char buf[1001] = {0};
    scanf("%[^\n]", buf);
    for (int i = strlen(buf)-1; i >= 0; --i) {
        if (!isalpha(buf[i])) {
            continue;
        }
        int idx = tolower(buf[i]) - 'a';
        queue[idx][tail[idx]++] = buf[i];
    }
    int idx = 0;
    for (int i = 0; i < 26; ++i) {
        while (tail[i] > 0) {
            if (!isalpha(buf[idx])) {
                printf("%c", buf[idx++]);
            } else {
                printf("%c", queue[i][tail[i]-1]);
                --tail[i];
                ++idx;
            }
        }
    }
    while (idx < strlen(buf)) {
        printf("%c", buf[idx++]);
    }
    return 0;
}


发表于 2022-08-16 11:59:10 回复(0)
获取输入时注意换行符
#include <stdio.h>
#include <string.h>

int main(){
    char a[1000];
    while(scanf("%s",a)!=EOF){
        int len=strlen(a);int k,j;char b[1000]={0};int n=0;
        for(j='a',k='A';j<='z',k<='Z';j++,k++){
            for(int m=0;m<len;m++){
                if(a[m]==k || a[m]==j){
                    b[n++]=a[m];
                }
            }
        }
        n=0;
        for(int m=0;m<len;m++){
            if(!((a[m]>='a' && a[m]<='z') || (a[m]>='A' && a[m]<='Z'))){
                printf("%c",a[m]);
            }
            else{
                printf("%c",b[n++]);
            }
        }
    }
}


发表于 2022-06-07 10:38:02 回复(0)
//萌新的朴素解法
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//使用函数是为了方便理解,实际上直接在主函数里面写也完全可以

//检查一个字符是否为大小写字母,是字母返回1,否则返回0
int check_zimu(char ch){    
    if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')) return 1;
    return 0;
}

//输入两个英文字母,检查是否需要交换,需要交换返回1,否则返回0
int check_exchange(char slow,char fast){        
    if(slow>='a'&&slow<='z') slow-=('a'-'A');    //统一为大写
    if(fast>='a'&&fast<='z') fast-=('a'-'A');
    if(slow>fast)return 1;        //比较
    return 0;
}


int main(){
    char ch[1002];
    gets(ch);
    int len=strlen(ch);
    
    //构造辅助字符串,将原字符串的字母复制到辅助字符串,
    //并在原字符串中字母的原位置做标记(这里标记为'a'),方便还原。
    char ch2[1002];
    int p_ch=0,p_ch2=0;
    for(p_ch=0;p_ch<len;p_ch++){
        int flag=check_zimu(ch[p_ch]);
        if(flag==1){
            ch2[p_ch2++]=ch[p_ch];
            ch[p_ch]='a';
        }
    }
    
    //在辅助字符串中对英文字母进行排序
    for(int slow=0;slow<p_ch2-1;slow++){
        int exchange=slow;
        for(int fast=slow+1;fast<p_ch2;fast++){
            int flag=check_exchange(ch2[exchange], ch2[fast]);
            if(flag==1){
                exchange=fast;
            }
        }
        if(exchange!=slow){
            char temp=ch2[exchange];
            for(int i=exchange-1;i>=slow;i--){
                ch2[i+1]=ch2[i];
            }
            ch2[slow]=temp;
        }
    }
    
    //将排序好的辅助字符串重新插入原字符串有标记的位置
    p_ch2=0;
    for(p_ch=0;p_ch<len;p_ch++){
        if(ch[p_ch]=='a'){
            ch[p_ch]=ch2[p_ch2++];
        }
    }
    
    printf("%s",ch);

    return 0;
}

发表于 2022-04-20 16:18:58 回复(0)
#include <stdio.h>
#include <string.h>
#define    N    1000
int main()
{
    char str[N],temp[N],ch;
    int i,j,k,len,flag[N]={0},m='a'-'A',f;
    gets(str);
    len=strlen(str);
    for(i=0,j=0;i<len;i++)
    {
        if((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z'))
        {
            if(str[i]>='A'&&str[i]<='Z')
            {
                temp[j]=str[i]+m;
                flag[j]=1;
            }
            else
            {
                temp[j]=str[i];
            }
            j++;
        }
    }
    k=j;
    for(i=0;i<k-1;i++)
    {
        for(j=0;j<k-1-i;j++)
        {
            if(temp[j]>temp[j+1])
            {
                ch=temp[j];
                temp[j]=temp[j+1];
                temp[j+1]=ch;
                f=flag[j];
                flag[j]=flag[j+1];
                flag[j+1]=f;
            }
        }
    }
    for(i=0,j=0;i<len;i++)
    {
        if(!((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z')))
        {
            continue;
        }
        else
        {
            if(flag[j]==1)
            {
                temp[j]-=m;
            }
            str[i]=temp[j];
            j++;
        }
    }
    printf("%s\n",str);
    return 0;
}

发表于 2022-04-19 11:38:16 回复(0)