Kav*_*ix0 2 c++ arrays sorting radix-sort
我一直在研究,虽然我已经想出了使用Radix Sort来按字母顺序排列字符串数组的一般想法,但我知道我的方向是错误的.
这是我到目前为止:
void radixSort(string* sortMe, int l)
{
queue<string>* sections = new queue<string>[27]; //Have a-z, and also one for strings that are null terminated.
for(int i = 0; i < numElements; i++)
{
if(!(sortMe[i][l] == 32))
sections[sortMe[i][l]-96].push(sortMe[i]); //-96 because the ascii code for a is 97. If, for example a is the character, it will be placed at 1. 0 is left for null characters
}
for(int i =0; i < 26; i++)
{
while(!sections[i].empty())
{
temp.push_back(sections[i].front());
sections[i].pop();
}
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止我用第一个字符对所有字符串进行排序,我知道然后我必须完成剩余字符的子数组并对它们进行排序,但是如何有效地实现呢?字符串大小可变,可以包含空格,例如:
这是我发现它似乎有用的东西:http: //algs4.cs.princeton.edu/lectures/51DemoKeyIndexedCounting.pdf
你发现的幻灯片很棒!但是这些队列在哪里来自你的代码?
无论如何,你在这里(实例):
template <typename E>
size_t bin(const E& elem, size_t digit)
{
return elem.size() > digit ? size_t(elem[digit]) + 1 : 0;
}
template <size_t R, typename C, typename P>
void radix_sort(P& pos, const C& data, size_t digit)
{
using A = std::array<size_t, R + 1>;
A count = {};
P prev(pos);
for (auto i : prev)
++count[bin(data[i], digit)];
A done = {}, offset = {{0}};
std::partial_sum(count.begin(), count.end() - 1, offset.begin() + 1);
for (auto i : prev)
{
size_t b = bin(data[i], digit);
pos[offset[b] + done[b]++] = i;
}
}
struct shorter
{
template <typename A>
bool operator()(const A& a, const A& b) { return a.size() < b.size(); }
};
template <size_t R, typename C>
std::vector<size_t> radix_sort(const C& data)
{
std::vector<size_t> pos(data.size());
std::iota(pos.begin(), pos.end(), 0);
size_t width = std::max_element(data.begin(), data.end(), shorter())->size();
for (long digit = long(width) - 1; digit >= 0; --digit)
radix_sort<R>(pos, data, size_t(digit));
return pos;
}
Run Code Online (Sandbox Code Playgroud)
你可以这样使用
int main()
{
std::vector<std::string> data = generate();
std::vector<size_t> pos = radix_sort<128>(data);
for (auto i : pos)
std::cout << data[i] << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
其中generate()
包含在实例中并生成问题中给出的字符串.
我不是要解释这是如何工作的,我假设你可以弄清楚,因为你正在研究这个问题.但是有一些评论是有条不紊的.
我们既没有就地输入序列,也没有返回已排序的副本; 我们只是返回排序序列中输入元素的一系列位置.
我们正在从右到左处理字符串.
复杂度O(lw)
,其中l
是输入长度(输入字符串的数目),并w
为最大输入宽度(最大长度的所有输入的字符串).因此,如果字符串宽度变化不大,则此算法有意义.
第一模板参数R
的radix_sort()
是用于在输入每个数字(字母)的可能值的数目.例如,R = 128
意味着可能的值0..127
.这应该适合您的输入.我没有尝试过对ASCII代码做任何聪明的事情,但你可以自定义功能bin()
.
在输出中bin()
,value 0
保留为表示"我们已超过此字符串的结尾".这些字符串放在仍在继续的其他字符串之前.
我试图给变量和函数提供不言自明的名称,并尽可能使用标准库调用来执行常见任务.
代码是通用的,例如,它可以对包含随机访问容器的任何随机访问容器进行排序,而不仅仅是字符串向量.
我在这里和那里使用C++ 11的功能是为了方便,但没有什么是真正必要的:一个人可以很容易地用C++ 03做同样的事情.
归档时间: |
|
查看次数: |
8357 次 |
最近记录: |