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 字符串不能直接用比较大小对于int、double、char来说arr[j] arr[j1]比较的是数值大小逻辑正确但对于 C 字符串本质是char*指针来说直接用比较的是字符串在内存中的地址大小不是字典序排序结果完全错误。所以必须单独写这个重载版本用 C 标准库函数做字符串专属操作比较用strcmpstrcmp(data[j], data[j1]) 0表示前一个字符串字典序更大需要交换符合从小到大排序的逻辑。交换用strcpyC 字符串不能直接用赋值只会拷贝指针地址不会拷贝内容必须通过strcpy逐个字符拷贝完成交换。cpp里面两种字典序的实现C风格字符串char[]/char*必须用strcmps1,s2函数Cstring 类必须用 运算符即可内部自动按字典序比较strcmp返回0 s1s2;0 s1s2;0 s1s2;不用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; }