当前位置: 首页 > news >正文

C风格字符串排序全解析【模板练习题】

void sort(char data[][M], int n) { for (int i = 0; i < n - 1; ++i) { for (int j = 0; j < n - 1 - i; ++j) { if (strcmp(data[j], data[j + 1]) > 0) { char temp[M]; strcpy(temp, data[j]); strcpy(data[j], data[j + 1]); strcpy(data[j + 1], temp); } } } }

二维字符数组(C 风格字符串数组)作为函数参数的标准写法

  • 第一维(行数 / 字符串个数)可以省略:数组传参会退化为指针,编译器不需要提前知道总共有多少行;
  • 第二维(每行的长度 / 单个字符串最大长度)必须明确写死:编译器需要靠这个长度计算内存地址,才能正确定位到每一行的起始位置。

因此:

  • char data[][M]char (*data)[M](数组指针)是完全等价的
  • 含义是:data指向一组字符数组,每个字符数组的固定长度为M
  • 这里的M是代码开头的宏定义#define M 30,表示每个字符串最多存 30 个字符(含末尾的结束符\0
  • 这个参数专门对应题目里type == 4的场景:

    每一行data[j]就是一个完整的 C 风格字符串(比如"abc""bca")整个二维数组就是一个 “字符串列表”,总共有n个字符串这个sort函数的作用,就是把这 n 个字符串按字典序从小到大排序

原因在于C 字符串不能直接用>比较大小

  • 对于intdoublechar来说,arr[j] > arr[j+1]比较的是数值大小,逻辑正确;
  • 但对于 C 字符串(本质是char*指针)来说,直接用>比较的是字符串在内存中的地址大小,不是字典序,排序结果完全错误。

所以必须单独写这个重载版本,用 C 标准库函数做字符串专属操作:

  • 比较用strcmpstrcmp(data[j], data[j+1]) > 0表示前一个字符串字典序更大,需要交换,符合从小到大排序的逻辑。
  • 交换用strcpy:C 字符串不能直接用=赋值(只会拷贝指针地址,不会拷贝内容),必须通过strcpy逐个字符拷贝完成交换。

cpp里面两种字典序的实现

C风格字符串char[]/char*必须用strcmp(s1,s2)函数
C++string 类必须用> < == 运算符即可,内部自动按字典序比较

strcmp

返回<0 s1<s2;

>0 s1>s2;

=0 s1=s2;

不用C风格的字符串,用的是string的封装,已经封装好了,比较的时候自动比较的就是字典序的大小,就使用通用的排序模板sort即可。

#include <iostream> #include <string> #include <fstream> using namespace std; // 通用输入模板 template <class T> void input(T arr[], int n, ifstream& in) { for (int i = 0; i < n; ++i) in >> arr[i]; } // 通用冒泡排序模板 template <class T> void sort(T arr[], int n) { for (int i = 0; i < n - 1; ++i) for (int j = 0; j < n - 1 - i; ++j) if (arr[j] > arr[j + 1]) swap(arr[j], arr[j + 1]); // 可以直接用std::swap简化交换代码 } // 通用输出模板 template <class T> void output(T arr[], int n, ofstream& out) { for (int i = 0; i < n; ++i) { if (i != 0) out << " "; out << arr[i]; } out << endl; } int main() { ifstream in("input.txt"); ofstream out("output.txt"); int type, n; while(in >> type && type) { if(type == 1) { in >> n; int *data = new int[n]; input(data, n, in); sort(data, n); output(data, n, out); delete []data; } else if(type == 2) { in >> n; char *data = new char[n]; input(data, n, in); sort(data, n); output(data, n, out); delete []data; } else if(type == 3) { in >> n; double *data = new double[n]; input(data, n, in); sort(data, n); output(data, n, out); delete []data; } else if(type == 4) { in >> n; string *data = new string[n]; // 改用string数组 input(data, n, in); sort(data, n); // string自带字典序比较,直接走通用模板 output(data, n, out); delete []data; } } in.close(); out.close(); return 0; }

原题目有框架要求,故代码如下:

#include <iostream> #include <string> #include <fstream> #include <cstring> using namespace std; #define M 30 // 字符串串长小于30 // 补齐排序、输入、输出函数模版等 template <class T> void input(T arr[], int n, ifstream& in) { for (int i = 0; i < n; ++i) { in >> arr[i]; } } template <class T> void sort(T arr[], int n) { for (int i = 0; i < n - 1; ++i) { for (int j = 0; j < n - 1 - i; ++j) { if (arr[j] > arr[j + 1]) { T temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } template <class T> void output(T arr[], int n, ofstream& out) { for (int i = 0; i < n; ++i) { if (i != 0) out << " "; out << arr[i]; } out << endl; } void sort(char data[][M], int n) { for (int i = 0; i < n - 1; ++i) { for (int j = 0; j < n - 1 - i; ++j) { if (strcmp(data[j], data[j + 1]) > 0) { char temp[M]; strcpy(temp, data[j]); strcpy(data[j], data[j + 1]); strcpy(data[j + 1], temp); } } } } int main() { // 补齐文件操作 ifstream in("input.txt"); ofstream out("output.txt"); int type, n; while(in >> type && type) { if(type == 1) // 整数类型 { in >> n; int *data = new int[n]; input(data, n, in); // in文件流输入n个数据 sort(data, n); // 排序 output(data, n, out); // 输出n个数据到out文件流 delete []data; } else if(type == 2) // 字符类型 { in >> n; char *data = new char[n]; input(data, n, in); sort(data, n); output(data, n, out); delete []data; } else if(type == 3) // 浮点数类型 { in >> n; double *data = new double[n]; input(data, n, in); sort(data, n); output(data, n, out); delete []data; } else if(type == 4) // C字符串类型 { in >> n; char (*data)[M] = new char[n][M]; input(data, n, in); sort(data, n); output(data, n, out); delete []data; } } in.close(); out.close(); return 0; }
http://www.gsyq.cn/news/1592181.html

相关文章:

  • 2026年AI大模型API代理网站全维度深度测评:主流服务商性能与成本全场景权威排名指南
  • IntelliJ IDEA安装失败?97%的报错都源于这5个隐藏配置——资深JetBrains认证讲师逐行调试实录
  • 第 14 篇:robots.txt 协议 —— 尊重站长的规则
  • 深度解析:Obsidian Excel表格转换插件的技术架构与实现机制
  • VMware Web服务器安全加固清单:27项CIS基准配置+自动检测脚本,漏配1项即成攻击入口
  • 从数据分析到长期研究,解析中吉安策多因子模型
  • 收藏!小白程序员转战AI大模型,3个月拿高薪Offer的秘密路径
  • Bently Nevada 132306-01 3500/40M 四通道涡流监测后置 I/O PIM 端子板
  • Redis集群性能翻倍实录:在VMware中精准配置6节点Cluster的12个关键参数(附压测对比数据)
  • CMDB 系统:为什么大多数企业建了又废掉,以及怎么才能真正用起来
  • Java程序员轻松入门大模型:保姆级学习路线助你涨薪,速收藏!
  • 4款热门免费论文降重神器实测:避开坑点选对不踩雷
  • 计算机毕业设计之驾校预约管理系统
  • 程序员量化交易实战 16:先把模拟盘账本写清楚
  • 婚姻意义的庖丁解牛
  • 什么是 .gitignore?为什么每个 Git 项目几乎都离不开它?
  • 2026分销系统主流功能盘点!智能化、全渠道成核心标配
  • Apache DolphinScheduler 与 AWS 数据湖仓集成:混合调度与成本优化实战
  • 土建井道完工后,为什么必须先验收再装梯?
  • 北京防水补漏
  • Windows右键菜单终极管理指南:告别臃肿,提升效率的完整方案
  • Java微服务开发环境迁移VMware的生死线:CPU核数、Swap分区与GC日志联动调优的4个硬指标(附Grafana监控模板)
  • 2026年GEO优化服务商综合实力排行榜:从流量收割到心智占领的选型指南
  • 性价比高的风车靶哪个靠谱
  • trending_AI Agent 智能体架构设计
  • IDEA 无法打印Mybatis、Mybatis Plus日志的解决办法
  • 300 个 Agent 一起干活,Claude 负责验收:一次自进化的 Loop Engineering 实践
  • 3分钟学会PS修图:模糊的照片变清晰零基础通用教程
  • 【IDEA极速部署手册】:从下载到运行Hello World仅需137秒——含自动环境检测脚本(GitHub Star 2.4k)
  • 南安普顿大学补考想转国内?这份申请攻略收好