我看好多玩家都借助了额外空间(数组)来排序,这种就不多介绍了。这里主要介绍一种仅在初始数组内部就完成排序的方法

根据题意,考虑到输入的顺序不能变,比如输入Aa就要输出Aa,如果输入aA则输出Aa,这说明 要求排序是稳定的。 考虑使用 冒泡排序

换汤不换药,,,普通的冒泡就是相邻元素之间交换的,循环的时候每次i++ j++这样,这个本质上不就是一直找下一个元素嘛! 于是只要写个 next(i) / pre(i) ,用来求下标 i 的 下一个/上一个 英文字母的下标,然后用 next/pre 代替 i++ / i--,这样就和普通的冒泡排序没啥区别了,一般的冒泡是逻辑相邻加物理相邻,而这个冒泡则是逻辑相邻(就算是链表照样能够冒!)(注意临界条件)

直接上C语言:

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

char s[500];
int n;

// 获取下标 i 之后的下一个字母的下标
int next(int i)
{
    ++i;
    while (i < n && !isalpha(s[i])) ++i;
    return i;
}

// 获取下标 i 之前的上一个字母的下标
int pre(int i)
{
    --i;
    while (i >= 0 && !isalpha(s[i])) --i;
    return i;
}

void func()
{
    // 跳过非英文字母结尾,这部分不用考虑排序
    while (n - 1 >= 0 && !isalpha(s[n - 1])) --n;
    // last_second是倒数第二个英文字母的下标
    int last_second = pre(n - 1), has_sorted = 0;

    for (int i = 0; i <= last_second; i = next(i)) {
        for (int j = 0, j1; j <= last_second - has_sorted; j = j1) {
            j1 = next(j);
            if (tolower(s[j]) > tolower(s[j1])) {
                char tmp = s[j];
                s[j] = s[j1];
                s[j1] = tmp;
            }
        }
        ++has_sorted;
    }

    puts(s);
}

int main()
{
    while (fgets(s, sizeof(s), stdin)) {
        n = strlen(s);
        s[--n] = '\0';  // replace '\n' with '\0'
        func();
        memset(s, 0, sizeof(s));
    }

    return 0;
}