c++ - 在给定数组中生成所有元素对的有效方法
问题描述
假设我得到了数组{1, 2, 3, 4}
,其中 n(数组的大小)在 2 到 18 之间。我需要找到成对排列这些元素的所有方法。所以对于这个例子,我会得到:
(1, 2), (3, 4)
(1, 3), (2, 4)
(1, 4), (2, 3)
所以这里的顺序有点重要,因为我不想/不需要生成配对相同的所有排列(我认为?)。((1, 2), (3, 4)
例如(3, 4), (1, 2)
。)
我已经尝试过一种可行的递归回溯方法,但对于较大的数组(14-18)来说,它的时间效率并不高,我需要所有可能的输入的执行时间低于 2 秒。
这是我的代码:
void gen_sol(int k)
{
if(k > n)
{
//do further calculations
}
else
{
for(int i = 1; i <= n; i++)
{
for(int j = i + 1; j <= n; j++)
{
if(k == 1)
{
if(!used[i] && !used[j])
{
sol[k] = v[i];
sol[k + 1] = v[j];
used[i] = true;
used[j] = true;
gen_sol(k + 2);
used[i] = false;
used[j] = false;
}
}
else
{
if(sol[k - 2] < v[i] && !used[i] && !used[j])
{
sol[k] = v[i];
sol[k + 1] = v[j];
used[i] = true;
used[j] = true;
gen_sol(k + 2);
used[i] = false;
used[j] = false;
}
}
}
}
}
}
现在我知道简短的、不具描述性的名称通常是不受欢迎的,但我认为这在竞争激烈的编程环境中并不算太糟糕。所以k
表示递归级别/我正在使用的当前对,sol
是我正在构建当前排列的数组,并used
用于指示我已经使用的数组的哪些元素。
关于实际的对生成,我将当前可能的对集与前一个进行比较,以查看其是否按字典顺序排列。我知道我可能可以合并循环内的 2 个单独的 if 语句,我应该这样做。
我曾考虑过尝试一种迭代方法,但无论如何,n=18 的执行时间对于这种方法来说太长了,我认为迭代不会有太大帮助。
有没有办法减少一个循环?
解决方案
推荐阅读
- c# - DLL 项目和 GUI 项目 - Caliburn Micro:模型/查看 VM 问题
- purescript - 如何使用 Spago 安装特定的软件包版本?
- android - 应用程序链接 - 应用程序无法从浏览器打开
- android - 设备所有者管理员 / DevicePolicyManager,可以在 Android 上自动打开移动数据和数据漫游吗?
- spring - SqlResultSetMapping 从 NamedNativeQuery 到 POJO 类抛出“找不到适当的构造函数”
- php - 已发布变量中的引号未在下一页显示回显
- list - 是否有一个函数,当 a 和 b 相乘时,结果 x 相同,并且 x 由用户给出
- javascript - bind-html-compile 缺乏适当的拆解
- api - 登录flutter后如何调用get请求?
- mstest - 如何在 github 操作中使用 mstest?