问题是要按照给定字符串的字母的频率降序对它们进行排序。
例如:如果string =“tree”输出=“eert”或“eetr”
我使用了unordered_map并计算了每个字母的频率,并将其以频率降序添加到结果字符串中。
这是我尝试过的:
string frequencySort(string s1) {
unordered_map<char,int> temp;
for(char& c: s1)
temp[c]++;
string s = "";
while(!temp.empty()) {
int max = 0;
char c='a';
for(auto it:temp) {
if(it.second > max) {
c = it.first;
max = it.second;
}
}
for(int j=0;j<max;j++)
s = s + c;
temp.erase(temp.find(c));
}
return s;
}
我的代码不适用于大量输入。而将int更改为long long并不能使其工作。因此,最大频率在INT_MAX以内。我收到此错误:
Runtime error: pointer index expression with base 0x000000000000 overflowed to 0xffffffffffffffff
我无法在此处粘贴特定的测试用例,因为它超出了问题允许的大小。
任何帮助表示赞赏。
最佳答案
代码在逻辑上没有错,但是许多低效率的操作可能会使您在低内存计算机上耗尽内存。
首先,您按值传递字符串:
这样,每次调用都会产生一个新的字符串副本,浪费的内存是必要的两倍。
相反,请选择:
string frequencySort(const string & s1) {
字符串所需的重复重新分配可能导致内存管理器中出现碎片,并导致更快的内存不足问题:
为了最大程度地减少重新分配问题,请使用
reserve
string s = "";
s.reserve(s1.length());
以及最大的性能问题:
上面的代码一次又一次地复制相同的字符串。在O(N2)中运行,并在堆上破坏巨大的碎片。
代码中还有一些简单的效率低下的问题,尽管它们不会影响复杂性,但它们可能会对大型输入的运行时产生重大影响。在如此小的集合(26个英文字母)中使用
unordered_map
会花费大量时间。在这种情况下,使用std::map
可能会更有效。对于大输入,保存数组更有效int map[256] = {0};
不幸的是,对于少量输入,它可能会更慢。同样,这对于宽字符(超过216个可能的宽字符)也不是很好。但是对于ASCII,这应该可以很好地工作。
作为基准,我运行了以下命令生成的字符串:
perl -e 'print "abcdefghijklmnopqrstuvwxyza" x 1000000; print "y\n"'
生成一个大小为2600万个字符的字符串。
在我的笔记本电脑上,带有
int map[256]
的代码在不到4秒的时间内完成了。关于c++ - 运行时错误:基数为0x000000000000的指针索引表达式溢出到0xffffffffffffffff以进行频率排序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55259287/