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;
}

运行结果

相关推荐
信奥卷王8 分钟前
[GESP202406 六级] 二叉树(含视频)
数据结构·算法
学逆向的13 分钟前
C 可变量参数
c语言·开发语言·网络安全
小莞尔40 分钟前
【51单片机】【protues仿真】基于51单片机六路抢答器系统
c语言·单片机·嵌入式硬件·物联网·51单片机
Tisfy1 小时前
LeetCode 3863.将一个字符串排序的最小操作次数:分类讨论(一次遍历)——简单易懂版
算法·leetcode·字符串·题解·分类讨论
starzy19902 小时前
KafkaProducer 源码深度剖析:支撑高吞吐的数据结构设计
大数据·数据结构·kafka
心中有你02143 小时前
C 语言文件操作详解:从写入、追加到读取与定位的完整 实战
c语言·开发语言
罗湖老棍子14 小时前
【例 1】Sightseeing Trip(信息学奥赛一本通- P1494)(洛谷-P10927)
数据结构·算法·图论·最短路·floyd·最小环
郝亚军17 小时前
manifest 中 `sha256` 与 `signValue` 的作用
java·开发语言·数据结构
Nil20818 小时前
LeetCode 283移动零
数据结构·算法·leetcode
知识分享小能手19 小时前
C学习教程,从入门到精通,C语言文件 — 完整知识点详解(14)
c语言·网络·学习