如何优化代码以返回最接近给定整数的数字,但给定列表中不存在?
How do I optimise the code to return the number closest to a given integer, not present in the given list?
我解决了这个问题陈述(是的,是的,我知道,我把问题陈述放在下面(。
给定一个整数 X 和一个长度为 N 的整数序列:p1, ..., pN。 在序列 p1 中不包含的整数中,...,pN(不一定为正(, 找到最接近 X 的整数,即与 X 的绝对差为最小的整数。 如果有多个这样的整数,则报告最小的此类整数
这是我使用的代码:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
int x = 0;
int n = 0;
std::cin >> x >> n;
std::vector<decltype(x)> vect(n);
bool vect_contains_x = false;
for (auto& elem : vect) {
std::cin >> elem;
if (elem == x) {
vect_contains_x = true;
}
}
int num = 0;
if (!vect_contains_x) {
num = x;
}
else {
std::sort(vect.begin(), vect.end());
while (1) {
static int i = 1;
if (std::find(vect.begin(), vect.end(), x - i) == vect.end()) {
num = x - i;
break;
}
else if (std::find(vect.begin(), vect.end(), x + i) == vect.end()) {
num = x + i;
break;
}
else {
i += 1;
}
}
}
std::cout << num << "n";
return 0;
}
此代码以13-18ms
格式呈现结果。
我能够使用以下优化的代码将其降低到8-10ms
:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
int x = 0;
int n = 0;
std::cin >> x >> n;
std::vector<decltype(x)> vect(n);
bool vect_contains_x = false;
for (auto& elem : vect) {
std::cin >> elem;
if (elem == x) {
vect_contains_x = true;
}
}
int num = 0;
if (!vect_contains_x) {
num = x;
}
else {
std::sort(vect.begin(), vect.end());
auto isPresent = [=](auto num) {
for (const auto& elem : vect) {
if (num == elem) {
return true;
}
}
return false;
};
while (1) {
static int i = 1;
if (!isPresent(x - i)) {
num = x - i;
break;
}
else if (!isPresent(x + i)) {
num = x + i;
break;
}
else {
i += 1;
}
}
}
std::cout << num << "n";
return 0;
}
但是,这两个代码的问题(因为它们都使用相同的方法(是, 如果给定列表中有大量连续的整数流,如下所示:
1,2,3,4,5,6,7,8,9,10,...,1501
给出的 X 是
751
代码将需要 750 次迭代for loop
,这是很多。我们可以使用更好的算法来找到最接近的整数吗?
编辑:
通过使用binary_search
将其归结为6ms
(谢谢@Sebastian(,但算法仍然保持不变......
你可以看到这个"作弊"算法。这是作弊,因为_Find_next
方法仅在GCC
编译器中。此外,在printf
和scanf
的帮助下,我加快了输入和输出,因此程序运行得更快。我多次发送它执行并收到 4、6 和 8 毫秒(最常见的是 6 毫秒(:
#include <bitset>
#include <algorithm>
using namespace std;
int main()
{
const int MAX_VALUES = 101;
bitset<MAX_VALUES> bits;
bitset<MAX_VALUES> reversed;
bits.flip();
reversed.flip();
int x, n, t;
scanf("%d %d", &x, &n);
if (n == 0) {
printf("%d", x);
exit(0);
}
for (int i = 0; i < n; i++) {
scanf("%d", &t);
bits.reset(t);
reversed.reset(MAX_VALUES - 1 - t);
}
if (bits[x]) {
printf("%d", x);
exit(0);
}
int rV = bits._Find_next(x);
int lV = MAX_VALUES - 1 - reversed._Find_next(MAX_VALUES - 1 - x);
int d1 = abs(rV - x);
int d2 = abs(lV - x);
if (d1 < d2) {
printf("%d", rV);
} else if (d2 < d1) {
printf("%d", lV);
} else {
printf("%d", min(rV, lV));
}
return 0;
}
我并不是说这个"算法"比你的更好。但是,据我了解,您要求其他一些解决方案,这是可能的一种。
根据您的链接,整数总数最多为 100。 因此,100 位足以容纳标志,哪些数字出现在序列中。这些可以保存在处理器寄存器中。
以下代码仅显示存储,后记您必须选择合适的位扫描操作:
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <limits>
#include <bitset>
using namespace std;
int main() {
bitset<100> flags;
int x = 0;
int n = 0;
int min = std::numeric_limits<int>::max();
int num = 0;
std::cin >> x >> n;
for (int i = 0; i < n; i++) {
int elem;
std::cin >> elem;
flags.set(elem);
}
// then you can shift the result by x bits and do bit scan operations
// there are built-ins depending on the compiler and processor architecture or the portable De Bruijn with multiplications
}
// alternatively (to the shift) you can use two bitsets, and for one set all the elements (elem - x) or for the other (x - elem)
相关文章:
- 试图在c++中对数字列表进行排序
- 如果我不知道每个列表中有多少个数字,我如何将给定数量的数字列表作为输入?
- 按唯一标识符描述数字列表
- 从小于或等于某个 N 的数字列表中最小化或找到 n 个理想的子集和
- 用于筛子的最佳数据结构是什么(即一些被划掉的数字列表)?
- 从(排序的)数字列表中获取数字范围
- 如何在C++中创建 2d 数组,其中一部分包含循环计数器,另一部分包含数字列表?
- 如何在C++中创建数字列表,以便它可以选择一个随机数?
- 使用数字列表和算术运算获取目标数字
- 如何通过C 从数字列表中以3位数字生成数字
- 如何使用C 中的printf打印数字列表
- 排序从最高到最低的数字列表
- 从文件读取数字列表到动态数组
- 生成加起来为1的随机数字列表
- 将元组传递给函数并让它返回数字列表的最佳方法
- 如何将数字列表从字符串复制到C++向量
- 数组和 For 循环:创建从大到小的数字列表
- 阅读数字列表并C++排序
- 将整数列表打印为逗号分隔的数字列表,每行最多 10 个
- 使用语义操作分析逗号分隔的范围和数字列表