字符串低位优先排序(LSD)和高位优先排序(MSD)原理及C++实现
前言:
原理:
![](/assets/blank.gif)
![](/assets/blank.gif)
/* 低位优先排序:将字符串进行低位优先排序(试用情况: 字符串的长度相同)* 参数: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;
}
![](/assets/blank.gif)
/* 转换函数:返回字符串中对于索引的字符* 参数: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的差集 ③对分行输入的若干字符串按字典序(由小到大)进行排序并输出. ①编写一个程序,从 ...
最新文章
- CVPR 2020 Oral 文章汇总,包括论文解读与代码实现
- python unpack函数_Python numpy.unpackbits函数方法的使用
- ffmpeg + x264+ x265 + libde265 + opengl es display
- python捷豹_图像处理基本工具——Python 环境下的 Pillow( PIL )
- According to TLD or attribute directive in tag file, attribute value does not accept any expressions
- [转]Shell中脚本变量和函数变量的作用域
- 读取config文件中的键值
- diff算法_详解 React 16 的 Diff 策略
- [转载]oracle函数listagg的使用说明
- 解决 Beyond Compare 3 许可证密钥被撤销
- MySQL进阶之SQL优化
- 关于python中字典描述正确的是_python总结七
- 什么是狭义人工智能、通用人工智能和超级人工智能?
- LTE 注网流程log分析
- Qt阅读器-ofd格式
- 【项目记录】雪球网股票组合数据爬虫(包括雪球模拟登录代码)
- 印象码——中国第一款视频广告验证码
- 雅高集团2021年即将开业的新酒店数量强劲增长
- oracle 01405 提取的值为null,ORA-01405 : fetched column value is NULL
- 全基因组选择-GS的技术评估
热门文章
- VS2010+OPENCV3.4.1永久配置
- abaqus6.13+vs2012+ivf2013用户子程序关联步骤
- 综测仪 之 IQxel使用方法介绍
- Java操作Excel三种方式POI、Hutool、EasyExcel
- 一个级数求和:看作二阶导,等比数列求和再求二阶导
- 卡尔曼滤波器简介——多维卡尔曼滤波
- UTC时间与北京时间相互转换
- 麻雀算法SSA优化SVR
- 已加载插件:fastestmirror Loading mirror speeds from cached hostfile
- 抖音企业号抖音智能营销系统源码待开发技术。。。。。