《算法第四版第五章》
在高位优先的字符串排序算法中,要特别注意到达字符串末尾的情况。合理的做法是将 所有字符都已经被检查过的字符串 排在 所有子数组的前面。
高位优先排序对于待排序的字符串没有什么要求
高位优先排序的过程中使用了键索引计数算法
高位优先排序要特别注意字符串达到末尾的情况,因为当字符串达到末尾时,比其本身加上任意字符都要小,如app小于apple。为了判断字符串是否已达到末尾的情况,编写字符索引函数int charAt(const string& str, int d),当字符索引大于字符长度即字符串达到结尾时,返回-1,否则返回索引字符对应的ASCII码。
在高位优先的字符串排序算法中,要特别注意到达字符串末尾的情况。合理的做法是将 所有字符都已经被检查过的字符串 排在 所有子数组的前面。
高位优先排序对于待排序的字符串没有什么要求
高位优先排序的过程中使用了键索引计数算法
高位优先排序要特别注意字符串达到末尾的情况,因为当字符串达到末尾时,比其本身加上任意字符都要小,如app小于apple。为了判断字符串是否已达到末尾的情况,编写字符索引函数int charAt(const string& str, int d),当字符索引大于字符长度即字符串达到结尾时,返回-1,否则返回索引字符对应的ASCII码。
如下三张图可帮助理解:
C++代码如下:
#include<iostream>
#include<fstream>
#include <string>
#include <vector>
const int R = 256; //字母表基数
const int M = 0; //小数组的切换阈值
using namespace std;
int charAt(const string& str, int d) //返回字符串str下标为d的字符,如果超出字符串长度则返回-1
{
if (d < str.size())
return str[d];
else
return -1;
}
//参数分别表示,字符串容器,排序字符串开始位置,排序字符串结束位置,以第几个字符为键,辅助存储容器
void MSD_sort(vector<string>& sVec, int lo, int hi, int d,vector<string>& aux)
{
if (hi <= lo + M) {
//Insert_sort(sVec, lo, hi, d);
return;
}
int count[R + 2] = { 0 };
//计算频率
for (int i = lo; i <= hi; i++)
{
count[charAt(sVec[i], d) + 2]++;
}
//将频率转换为索引
for (int r = 0; r < R + 1; r++)
{
count[r + 1] += count[r];
}
//分类
for (int i = lo; i <= hi; i++)
{
aux[count[charAt(sVec[i],d)+1]++] = sVec[i];
}
//回写
for (int i = lo; i <= hi; i++)
{
sVec[i] = aux[i - lo];
}
//递归的以每个字符为键进行排序
for (int r = 0; r < R; r++)
{
MSD_sort(sVec, lo + count[r], lo + count[r + 1] - 1, d + 1, aux);
}
}
int main()
{
string str;
vector<string> sVec;
sVec.push_back("huangpangpang");
sVec.push_back("suanfa");
sVec.push_back("diwu