C++:嵌套循环的动态数量(无递归)
c++ : dynamic number of nested for loops (without recursion)
我正在编写一个代码段,它遍历n位数字的每个排列。例如,如果 n = 3,我想遍历以下每个元素:
0, 0, 0
。
0, 1, 0
。
1, 0, 0
。
2、3、4
。
9、9、9
使用嵌套的 for 循环进行编码非常容易:
for(digit1 0 to 9)
for(digit2 0 to 9)
for(digit3 0 to 9)
但我想将其推广为 n 位数字。例如,如果 n = 10,我现在需要 10 个嵌套的循环。
我已经考虑过这个问题,并意识到这个问题可以使用递归来解决(通过树的深度优先搜索,每个节点有 10 个子节点,0 到 10,并在深度 n 处停止)。但我的目标是高性能,所以我不想由于开销而使用递归。我还有哪些其他选择?
如果要在不使用递归的情况下使用单个循环模拟嵌套循环,可以通过为每个循环变量维护一组状态(或插槽)来实现,这可以通过数组轻松完成。然后,循环变成了向该数组"添加 1"的简单问题,根据需要执行进位操作。如果你的嵌套深度是 n,并且每个循环的最大边界是 b,那么它的运行时间是 O(b^n),因为进位操作最多只会花费你 O(b^n)(我将跳过这里的代数)。
以下是工作C++代码(更新以集成 Drew 的评论):
void IterativeNestedLoop(int depth, int max)
{
// Initialize the slots to hold the current iteration value for each depth
int* slots = (int*)alloca(sizeof(int) * depth);
for (int i = 0; i < depth; i++)
{
slots[i] = 0;
}
int index = 0;
while (true)
{
// TODO: Your inner loop code goes here. You can inspect the values in slots
// Increment
slots[0]++;
// Carry
while (slots[index] == max)
{
// Overflow, we're done
if (index == depth - 1)
{
return;
}
slots[index++] = 0;
slots[index]++;
}
index = 0;
}
}
在类型情况下,如果您想将递归替换为平面代码,则应使用堆栈(LIFO)。所以如果你有递归算法:
void print(std::string str, int depth)
{
if (depth == n) {
std::cout << str << std::endl;
return;
}
for (int i = 0; i < 10; ++i) {
char val[2] = { i + '0', 0 };
print(str + val + ", ", depth+1);
}
}
您可以通过保存局部变量(在本例中为 str 和 i)将其转换为基于 LIFO 的变量:
struct StackItem {
StackItem(const std::string& ss, unsigned ii)
: str(ss), i(ii)
{}
std::string str;
int i;
};
void print_norec()
{
std::list< StackItem > stack;
stack.push_back(StackItem("", 0));
while (!stack.empty()) {
StackItem& current = stack.back();
if (stack.size() == n+1) {
std::cout << current.str << std::endl;
stack.pop_back(); // return from "recursive" function
continue;
}
if (current.i < 10) {
char val[2] = { current.i + '0', 0 };
// call "recursive" function
stack.push_back(StackItem(current.str + val + ", ", 0));
current.i++;
} else {
stack.pop_back(); // return from "recursive" function
}
}
}
如果您希望特定
长度的所有数字的排列;如您所示的 3 位数字的示例。与其运行 3 个嵌套循环,不如运行一个 10^3 的循环,这将为您提供所有排列。
如果要将其用于索引,请在每次迭代中将获得的数字拆分为数字。
因此,您将只需要一个循环而不是嵌套循环。
相关文章:
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 了解嵌套循环打印星号图案
- 无法掌握嵌套循环的写作技巧
- 在 c++ 中实现嵌套循环的更短方法吗?
- 为什么在递归中使用循环会产生意想不到的结果?
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 毕达哥拉斯三重嵌套循环误解
- T(n) 表示嵌套循环
- 2 个嵌套循环的时间复杂度
- 嵌套循环背后的逻辑
- 使用 %s C++嵌套循环
- 嵌套循环和重复迭代器
- 如何在 c++ 下使用嵌套循环和正则表达式降低时间复杂度?
- C++在乘法图中放置随机值(嵌套循环)
- 什么是"递归嵌套模板"的实际用法示例?
- 如何在C++中将基本嵌套循环转换为递归循环
- C++ 递归嵌套类型和名称注入
- 基于递归的 N 嵌套循环存在逻辑问题
- C++:嵌套循环的动态数量(无递归)
- 两个嵌套循环的非递归归并排序