在 C++ 中验证给定集合中是否存在元素的最有效方法
Most performant way to verify an element exists in a given set in C++
我一直在尝试编写一个代码,找出所有与倒置对应的数字相加会产生奇数,例如“12 + 21 = 33”,“605839 + 938506 = 1544345”,等等……
我遇到了访问给定 unordered_set 的值并检查值是否在其中的问题。问题是上述“检查”的性能,由于某种我无法确定的原因,这种验证以我的方式慢得离谱,似乎时间呈指数增长,给定集合中的元素数量越大是。
我想创建一个集合,或者一个不重复其值的元素列表,它可以以最高效的方式访问和插入元素,而不管元素的顺序,因为顺序不会'对于这个实现来说真的很重要。
这是 a 想出的代码
#include <iostream>
#include <bits/stdc++.h>
#include <string>
using namespace std;
string invertSequence(string sequence);
int main()
{
unordered_set <int> control;
for(int i = 0; i < 1000000; i++)
{
string number = std::to_string(i);
string invertedSequence = invertSequence(number);
int invertedNumber = stoi(invertedSequence);
int sumValue = i + invertedNumber;
if (!control.count(invertedNumber) && number.at(number.length() - 1) != '0') {
control.insert(i);
if (sumValue % 2 != 0) {
cout << i << " + " << invertedNumber << " = " << i + invertedNumber << endl;
}
}
}
return 0;
}
string invertSequence(string sequence)
{
char inverted[sequence.length()];
const char* charSequence = sequence.c_str();
for (int i = 0; i < sequence.length(); i++)
{
inverted[sequence.length() -i - 1] = charSequence[i];
}
return inverted;
}
我在 Java 中编写了相同的代码,它 运行 非常好,它在大约 3800 毫秒内计算了 0 到 1 百万之间的所有出现次数,而在我的 C++ 代码中我从来没有真的让它 运行 到最后,因为它太慢了,会花很长时间。
Java 有 HashSet class 可以很好地完成这项工作。这是我的 java 代码 Impl.
我在网上搜索了一下,发现 C++ 中的 unordered_set 类似于 Java 中的 HashSet,但也许我遗漏了什么,因为两者的性能太差了我做事的方式不同。
对于此事,我将不胜感激!
正如@JaMiT 所认识到的,问题不在于布景;它是可能未终止的 C 字符串。如果你转换成另一个知道它的长度的 std::string
,你就不会 运行 进入那个问题:
string invertSequence(string sequence)
{
string inverted(' ', sequence.size());
for (int i = 0; i < sequence.length(); i++)
{
inverted[sequence.length() - i - 1] = sequence[i];
}
return inverted;
}
至少在我的电脑上,它 运行 只需要大约 0.6 秒。
最后,当然,std::reverse
更短,更安全,甚至更快:
string invertSequence(string sequence)
{
reverse(sequence.begin(), sequence.end());
return sequence;
}
我一直在尝试编写一个代码,找出所有与倒置对应的数字相加会产生奇数,例如“12 + 21 = 33”,“605839 + 938506 = 1544345”,等等……
我遇到了访问给定 unordered_set 的值并检查值是否在其中的问题。问题是上述“检查”的性能,由于某种我无法确定的原因,这种验证以我的方式慢得离谱,似乎时间呈指数增长,给定集合中的元素数量越大是。
我想创建一个集合,或者一个不重复其值的元素列表,它可以以最高效的方式访问和插入元素,而不管元素的顺序,因为顺序不会'对于这个实现来说真的很重要。
这是 a 想出的代码
#include <iostream>
#include <bits/stdc++.h>
#include <string>
using namespace std;
string invertSequence(string sequence);
int main()
{
unordered_set <int> control;
for(int i = 0; i < 1000000; i++)
{
string number = std::to_string(i);
string invertedSequence = invertSequence(number);
int invertedNumber = stoi(invertedSequence);
int sumValue = i + invertedNumber;
if (!control.count(invertedNumber) && number.at(number.length() - 1) != '0') {
control.insert(i);
if (sumValue % 2 != 0) {
cout << i << " + " << invertedNumber << " = " << i + invertedNumber << endl;
}
}
}
return 0;
}
string invertSequence(string sequence)
{
char inverted[sequence.length()];
const char* charSequence = sequence.c_str();
for (int i = 0; i < sequence.length(); i++)
{
inverted[sequence.length() -i - 1] = charSequence[i];
}
return inverted;
}
我在 Java 中编写了相同的代码,它 运行 非常好,它在大约 3800 毫秒内计算了 0 到 1 百万之间的所有出现次数,而在我的 C++ 代码中我从来没有真的让它 运行 到最后,因为它太慢了,会花很长时间。
Java 有 HashSet class 可以很好地完成这项工作。这是我的 java 代码 Impl.
我在网上搜索了一下,发现 C++ 中的 unordered_set 类似于 Java 中的 HashSet,但也许我遗漏了什么,因为两者的性能太差了我做事的方式不同。
对于此事,我将不胜感激!
正如@JaMiT 所认识到的,问题不在于布景;它是可能未终止的 C 字符串。如果你转换成另一个知道它的长度的 std::string
,你就不会 运行 进入那个问题:
string invertSequence(string sequence)
{
string inverted(' ', sequence.size());
for (int i = 0; i < sequence.length(); i++)
{
inverted[sequence.length() - i - 1] = sequence[i];
}
return inverted;
}
至少在我的电脑上,它 运行 只需要大约 0.6 秒。
最后,当然,std::reverse
更短,更安全,甚至更快:
string invertSequence(string sequence)
{
reverse(sequence.begin(), sequence.end());
return sequence;
}