C语言/数据结构字符串题解:按字符类型重排(数字→字母→符号)——三趟扫描稳定分区

问题描述

小明在整理班级的图书角时,发现每本书的封面上都印有一个字符(可能是字母、数字或符号)。为了便于分类,老师希望将这些字符按照类型重新排序:先排列所有数字字符('0'-'9'),然后是所有字母字符('a'-'z', 'A'-'Z'),最后是其他符号字符。同时,要求在同类型字符中保持它们在原始字符串中的相对顺序不变。

请帮助小明设计一个算法,实现字符串的字符类型排序。

要求:

  1. 算法的时间复杂度应为 O(n),其中 n 是字符串的长度。
  2. 尽量减少额外空间的使用,以体现算法优化能力。

测试样例

样例1:

输入:s = "a1b2c3" 输出:"123abc" 解释:原始字符串中的数字字符 '1','2','3' 排在前面,接着是字母字符 'a','b','c',它们都保持了原始顺序。

样例2:

输入:s = "Hi! How are you? 123?" 输出:"123HiHowareyou! ? ?" 解释:数字字符 '1','2','3' 先输出,然后是大写字母 'H','H',小写字母 'i','o','w','a','r','e','y','o','u',最后是符号字符 '!',' '(空格)、'?',' '(空格)、'?'。所有字符保持原始相对顺序。

样例3:

输入:s = "Test123!!" 输出:"123Test!!" 解释:数字字符 '1','2','3' 排在最前,然后是字母字符 'T','e','s','t',最后是符号字符 '!','!'。

约束条件

  • 1 ≤ s.length ≤ 1000
  • 字符串 s 可能包含任意可打印 ASCII 字符(ASCII 值从 32 到 126)
  • 输出字符串应包含输入字符串中的所有字符(包括空格等符号),且同类型字符的相对顺序与输入一致

程序代码

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

char* sortCharacters(char* s) {

int n = strlen(s);

char* result = (char*)malloc((n + 1) * sizeof(char));

int idx = 0;

// 第一趟:数字

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

if (si >= '0' && si <= '9') {

resultidx++ = si;

}

}

// 第二趟:字母

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

if ((si >= 'a' && si <= 'z') || (si >= 'A' && si <= 'Z')) {

resultidx++ = si;

}

}

// 第三趟:其他符号

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

if (!(si >= '0' && si <= '9') &&

!(si >= 'a' && si <= 'z') &&

!(si >= 'A' && si <= 'Z')) {

resultidx++ = si;

}

}

resultidx = '\0';

return result;

}

int main() {

char* r1 = sortCharacters("a1b2c3");

char* r2 = sortCharacters("Hi! How are you? 123?");

char* r3 = sortCharacters("Test123!!");

printf("%s\n", r1); // 123abc

printf("%s\n", r2); // 123HiHowareyou! ? ?

printf("%s\n", r3); // 123Test!!

free(r1);

free(r2);

free(r3);

return 0;

}

cpp 复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* sortCharacters(char* s) {
    int n = strlen(s);
    char* result = (char*)malloc((n + 1) * sizeof(char));
    int idx = 0;
    
    // 第一趟:数字
    for (int i = 0; i < n; i++) {
        if (s[i] >= '0' && s[i] <= '9') {
            result[idx++] = s[i];
        }
    }
    
    // 第二趟:字母
    for (int i = 0; i < n; i++) {
        if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {
            result[idx++] = s[i];
        }
    }
    
    // 第三趟:其他符号
    for (int i = 0; i < n; i++) {
        if (!(s[i] >= '0' && s[i] <= '9') && 
            !(s[i] >= 'a' && s[i] <= 'z') && 
            !(s[i] >= 'A' && s[i] <= 'Z')) {
            result[idx++] = s[i];
        }
    }
    
    result[idx] = '\0';
    return result;
}

int main() {
    char* r1 = sortCharacters("a1b2c3");
    char* r2 = sortCharacters("Hi! How are you? 123?");
    char* r3 = sortCharacters("Test123!!");
    
    printf("%s\n", r1);  // 123abc
    printf("%s\n", r2);  // 123HiHowareyou! ? ? 
    printf("%s\n", r3);  // 123Test!!
    
    free(r1);
    free(r2);
    free(r3);
    
    return 0;
}

运行结果

相关推荐
Logic1017 小时前
C语言/数据结构位运算题解:异或XOR找出学习计划中的“独特学习时间“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
wuminyu8 小时前
C++协程实现接收端的零拷贝Buffer管理原理剖析
java·linux·c语言·jvm·c++
小蒋学算法8 小时前
算法-交替删除操作后最后剩下的整数-跟着灵茶山艾府学算法
数据结构·算法
思麟呀10 小时前
位运算:从一个整数到一个集合
c语言·数据结构·c++·算法
All for pursuit.12 小时前
【分治-3】347.前K个高频元素
数据结构·c++·算法·leetcode
SuperByteMaster12 小时前
低功耗GPIO引脚配置
c语言
phltxy12 小时前
C 语言自定义类型:结构体、位段、枚举与联合体
c语言·开发语言
All for pursuit.13 小时前
【二分查找-2】34.在排序数组中查找元素的第一个和最后一个位置
数据结构·c++·算法·leetcode
大侠归来13 小时前
C语言与C++在基础语法上的区别
java·c语言·c++