字符串低位优先排序(LSD)和高位优先排序(MSD)原理及C++实现
前言:
原理:
/* 低位优先排序:将字符串进行低位优先排序(试用情况: 字符串的长度相同)* 参数:a:参与排序的字符串数组,N:字符串中元素的个数* 返回值:无*/
void LSD(string *a, int N) {int W = a[0].length(), R = 256;string *Aux = new string[N];int *Count = new int[R + 1];for (int k = W - 1; k >= 0; k--) {// 初始化索引数组for (int i = 0; i < R + 1; i++)Count[i] = 0;// 计算位置k上字符频数for (int i = 0; i < N; i++)Count[a[i][k] + 1]++;// 将频数转换为索引for (int i = 0; i < R; i++)Count[i + 1] += Count[i];// 将元素分类for (int i = 0; i < N; i++)Aux[Count[a[i][k]]++] = a[i];// 回写for (int i = 0; i < N; i++)a[i] = Aux[i];}Aux = NULL;delete Aux;Aux = NULL;delete Count;Count = NULL;
}
/* 转换函数:返回字符串中对于索引的字符* 参数:s:想要进行转换的字符串,i:字符索引* 返回值:对应索引的字符,若超出字符串长度返回-1*/
char CharAt(string s, int i) {if (i < s.length())return s[i];elsereturn -1;
}
这样我们就可以把字符串结尾的情况同其余情况一起处理,同时保证了已结尾的字符串会在未结尾的字符串之前!
/* 高位优先排序驱动* 参数:a:进行排序的数组,Aux:用于储存本次排序结果的中间数组,Count:用于储存索引的数组,lo:排序的起始位置,hi:排序终止位置,d:进行排序的字符下标* 返回值:无*/
void MSD(string *a, string *Aux, int *Count,int lo, int hi, int d) {int const M = 3, R = 256;// 小的子数组进行插入排序// 与快速排序相同if (hi <= lo + M) {InsertionSort(a, lo, hi, d);return;}// 初始化索引数组for (int i = 0; i < R + 2; i++)Count[i] = 0;// 统计频数// 特别说明:Count[0]:无用;Count[1]:长度为d的字符串个数;for (int i = lo; i <= hi; i++)Count[CharAt(a[i], d) + 2]++;// 转换频数为索引for (int i = 0; i < R + 1; i++)Count[i + 1] += Count[i];// 数组分类for (int i = lo; i <= hi; i++)Aux[Count[CharAt(a[i], d) + 1]++] = a[i];// 回写for (int i = lo; i <= hi; i++)a[i] = Aux[i - lo];// 递归排序// 特别说明:Count[0]:长度为d的字符串索引的终止坐标for (int i = 0; i < R; i++)MSD(a, Aux, Count, lo + Count[i], lo + Count[i + 1] - 1, d + 1);
}/* 高位优先排序:将目标字符串进行高位优先排序* 参数:a:想要进行高位优先排序的数组,N:数组中元素的个数* 返回值:无*/
void MSD(string *a, int N) {int R = 256;int *Count = new int[R + 2];string *Aux = new string[N];MSD(a, Aux, Count, 0, N - 1, 0);Aux = NULL;delete Aux;Aux = NULL;delete Count;Count = NULL;
}
C++实现:
#ifndef STRINGSORT_H
#define STRINGSORT_H#include <iostream>
#include <string>
using namespace std;/* 交换函数:交换两个字符串* 参数:s1:进行交换的字符串1,s2:进行交换的字符串2* 返回值:无*/
void exch(string &s1, string &s2) {string tmp = s1;s1 = s2;s2 = tmp;
}/* 小于函数:判断前d位相等的字符串的大小* 参数:s1:进行比较的字符串1,s2:进行比较的字符串2,d:不同字符开始出现的索引* 返回值:若s1<s2返回true,否则返回false*/
bool Less(string s1, string s2, int d) {return s1.substr(d).compare(s2.substr(d)) < 0;
}/* 转换函数:返回字符串中对于索引的字符* 参数:s:想要进行转换的字符串,i:字符索引* 返回值:对应索引的字符,若超出字符串长度返回-1*/
char CharAt(string s, int i) {if (i < s.length())return s[i];elsereturn -1;
}/* 插入排序:将前d位相同的字符串进行插入排序* 参数:a:想要进行插入排序的字符串数组,lo:排序的开始位置,hi:排序的终止位置,d:不同字符出现的索引* 返回值:无*/
void InsertionSort(string *a, int lo, int hi, int d) {for (int i = lo; i <= hi; i++)for (int j = i; j > lo && Less(a[j], a[j - 1], d); j--)exch(a[j], a[j - 1]);
}/* 低位优先排序:将字符串进行低位优先排序(试用情况: 字符串的长度相同)* 参数:a:参与排序的字符串数组,N:字符串中元素的个数* 返回值:无*/
void LSD(string *a, int N) {int W = a[0].length(), R = 256;string *Aux = new string[N];int *Count = new int[R + 1];for (int k = W - 1; k >= 0; k--) {// 初始化索引数组for (int i = 0; i < R + 1; i++)Count[i] = 0;// 计算位置k上字符频数for (int i = 0; i < N; i++)Count[a[i][k] + 1]++;// 将频数转换为索引for (int i = 0; i < R; i++)Count[i + 1] += Count[i];// 将元素分类for (int i = 0; i < N; i++)Aux[Count[a[i][k]]++] = a[i];// 回写for (int i = 0; i < N; i++)a[i] = Aux[i];}Aux = NULL;delete Aux;Aux = NULL;delete Count;Count = NULL;
}/* 高位优先排序驱动* 参数:a:进行排序的数组,Aux:用于储存本次排序结果的中间数组,Count:用于储存索引的数组,lo:排序的起始位置,hi:排序终止位置,d:进行排序的字符下标* 返回值:无*/
void MSD(string *a, string *Aux, int *Count,int lo, int hi, int d) {int const M = 3, R = 256;// 小的子数组进行插入排序// 与快速排序相同if (hi <= lo + M) {InsertionSort(a, lo, hi, d);return;}// 初始化索引数组for (int i = 0; i < R + 2; i++)Count[i] = 0;// 统计频数// 特别说明:Count[0]:无用;Count[1]:长度为d的字符串个数;for (int i = lo; i <= hi; i++)Count[CharAt(a[i], d) + 2]++;// 转换频数为索引for (int i = 0; i < R + 1; i++)Count[i + 1] += Count[i];// 数组分类for (int i = lo; i <= hi; i++)Aux[Count[CharAt(a[i], d) + 1]++] = a[i];// 回写for (int i = lo; i <= hi; i++)a[i] = Aux[i - lo];// 递归排序// 特别说明:Count[0]:长度为d的字符串索引的终止坐标for (int i = 0; i < R; i++)MSD(a, Aux, Count, lo + Count[i], lo + Count[i + 1] - 1, d + 1);
}/* 高位优先排序:将目标字符串进行高位优先排序* 参数:a:想要进行高位优先排序的数组,N:数组中元素的个数* 返回值:无*/
void MSD(string *a, int N) {int R = 256;int *Count = new int[R + 2];string *Aux = new string[N];MSD(a, Aux, Count, 0, N - 1, 0);Aux = NULL;delete Aux;Aux = NULL;delete Count;Count = NULL;
}/* 三向快速排序驱动* 参数:a:进行排序的数组,lo:排序的起始位置,hi:排序的终止位置,d:进行排序的字符下标* 返回值:无*/
void Quick3Sort(string *a, int lo, int hi, int d) {// 排序终止条件if (hi <= lo)return;// lt:小子串的结束位置,gt:大子串的开始位置// v:枢纽元int lt = lo, gt = hi;int v = CharAt(a[lo], d);int i = lo + 1;// 以枢纽元为界进行区分while (i <= gt) {int t = CharAt(a[i], d);if (t < v)exch(a[lt++], a[i++]);else if (t > v)exch(a[i], a[gt--]);elsei++;}// 对小子串进行排序Quick3Sort(a, lo, lt - 1, d);// 对当前字符串进行进一步排序if (v >= 0)Quick3Sort(a, lt, gt, d + 1);// 对大子串进行排序Quick3Sort(a, gt + 1, hi, d);
}/* 三向快速排序:对目标数组进行三向快速排序* 参数:a:进行排序的字符串数组,N:字符串的个数* 返回值:无*/
void Quick3Sort(string *a, int N) {Quick3Sort(a, 0, N - 1, 0);
}#endif // !STRINGSORT_H
字符串低位优先排序(LSD)和高位优先排序(MSD)原理及C++实现相关推荐
- 算法-22-字符串的排序算法(四种排序)
目录 1.字符串 1.1.属性 1.2.字母表 2.字符串排序方法 3.键索引计数法 3.1.第一步:频率统计 3.2.第二步:将频率转换为索引 3.3.第三步:数据分类排序 3.4.第四步:回写排序 ...
- 各种排序笔记---基于非比较排序部分
在计算机科学中,排序是一门基础的算法技术,许多算法都要以此作为基础,不同的排序算法有着不同的时间开销和空间开销.排序算法有非常多种,如我们最常用的快速排序和堆排序等算法,这些算法需要对序列中的数据进行 ...
- 字节顺序:高位优先(big-endian)和低位优先(little-endian)
字节顺序:高位优先(big-endian)和低位优先(little-endian) 网络字节序: MSB 高字节前存法 Most Significant Bit (Big Edian) 主机字节序 ...
- 排序算法10——图解基数排序(次位优先法LSD和主位优先法MSD)
排序算法1--图解冒泡排序及其实现(三种方法,基于模板及函数指针) 排序算法2--图解简单选择排序及其实现 排序算法3--图解直接插入排序以及折半(二分)插入排序及其实现 排序算法4--图解希尔排序及 ...
- mysqlorderby数字字符串排序_Python中的元组排序和深度比较
比较Python中的东西.这听起来几乎是不需要教的,但是我发现Python的比较运算符经常被Python新手误解和低估. 我们来回顾一下Python的比较运算符如何处理不同类型的对象,然后看看如何使用 ...
- boost::sort模块实现使用字符串键和索引函子对结构进行排序的示例
boost::sort模块实现使用字符串键和索引函子对结构进行排序的示例 实现功能 C++实现代码 实现功能 boost::sort模块实现使用字符串键和索引函子对结构进行排序的示例 C++实现代码 ...
- C语言编程>第二十三周 ③ 下列给定程序中,函数fun的功能是:利用插入排序法对字符串中的字符按从小到大的顺序进行排序。插入法的基本算法是:先对字符串中的头两个元素进行排序;然后把第三字符插入
例题:下列给定程序中,函数fun的功能是:利用插入排序法对字符串中的字符按从小到大的顺序进行排序.插入法的基本算法是:先对字符串中的头两个元素进行排序:然后把第三字符插入到前两个字符中,插入后前三个字 ...
- 算符优先系列之(二)算符优先关系表
算符优先系列之(二)算符优先关系表 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 学 ...
- ①编写一个程序,从键盘接收一个字符串,然后按照字符顺序从小到大进行排序,并删除重复的字符。②集合A、B的差集③对分行输入的若干字符串按字典序(由小到大)进行排序并输出。
文章目录 ①编写一个程序,从键盘接收一个字符串,然后按照字符顺序从小到大进行排序,并删除重复的字符 ②集合A.B的差集 ③对分行输入的若干字符串按字典序(由小到大)进行排序并输出. ①编写一个程序,从 ...
最新文章
- win7,windowsXP安装mysql-5.1.49-win32,中文版、英文版,通吃
- PTA 基础编程题目集 7-16 求符合给定条件的整数集 C语言
- vc中常用文件操作(二) Ini文件操作
- SSH port forwarding: bind: Cannot assign requested address
- 宇瞻U盘出现无法格式化 写保护的完美解决办法 厂家提供的
- 本地存储localStorage用法详解
- spring boot mybatis 整合_MyBatis学习:MyBatis和Spring整合
- 关于.NET微服务最热门的问题解答
- Storm精华问答 | 遇到这些错误日志该如何解决?
- 【报告分享】2020新中国人才报告:共赢人力资本新生态-哈佛商业评论.pdf(附下载链接)...
- asp网上书店的代码_使用Helm将ASP.NET Core应用程序部署到Kubernetes容器集群
- Bettertouchtool for Mac(鼠标增强软件)
- windows下python调用C/C++以及使用C扩展python python通过pythonnet调用C# dll
- 远程服务器mstsc命令,远程桌面连接命令mstsc怎么用
- 谷歌火狐等浏览器Flash安装失败,安装后进入网站仍提示未安装Flash
- 在网易咔哒上面制作SCRATCH小程序
- 简单聊聊为什么说外包不好?
- 什么可以代替pencil?pencil代替品推荐
- 我讨厌计算机作文500,我讨厌谎言作文500字(精选5篇)
- win10在BIOS开启Intel VT-x
热门文章
- 大学生综测评分计算管理系统
- 网页 变黑白网页(灰色)
- 卡尔曼滤波理论小释之卡尔曼增益
- 一张图解析FastAdmin中的FormBuilder表单生成器
- 图像基本处理——图像阈值和平滑
- @Component和@ComponentScan
- 阿里大人都在读的10本Java实战书籍,Java开发进阶必备书单
- BUUCTF·[WUSTCTF2020]大数计算·WP
- php1.6t发动机机油选择,1.6t用什么机油选择啊!?
- MySql 中 varchar 和varchar 的区别