我看好多玩家都借助了额外空间(数组)来排序,这种就不多介绍了。这里主要介绍一种仅在初始数组内部就完成排序的方法 。
根据题意,考虑到输入的顺序不能变,比如输入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;
} 
京公网安备 11010502036488号