gpt4 book ai didi

c++ - 递归到迭代的转换

转载 作者:行者123 更新时间:2023-11-28 08:17:25 29 4
gpt4 key购买 nike

我一直在尝试将我的代码从递归函数重写为迭代函数。

我想我会问是否有任何一般性的事情需要考虑/技巧/指南等...关于从递归代码到迭代代码。

例如我无法理解如何迭代以下代码,主要是由于递归内部的循环进一步依赖并调用下一个递归。

struct entry
{
uint8_t values[8];
int32_t num_values;
std::array<entry, 256>* next_table;

void push_back(uint8_t value) {values[num_values++] = value;}
};

struct node
{
node* children; // +0 right, +1 left
uint8_t value;
uint8_t is_leaf;
};

void build_tables(node* root, std::array<std::array<entry, 8>, 255>& tables, int& table_count)
{
int table_index = root->value; // root is always a non-leave, thus value is the current table index.

for(int n = 0; n < 256; ++n)
{
auto current = root;

// Recurse the the huffman tree bit by bit for this table entry
for(int i = 0; i < 8; ++i)
{
current = current->children + ((n >> i) & 1); // Travel to the next node current->children[0] is left child and current->children[1] is right child. If current is a leaf then current->childen[0/1] point to the root.
if(current->is_leaf)
tables[table_index][n].push_back(current->value);
}

if(!current->is_leaf)
{
if(current->value == 0) // For non-leaves, the "value" is the sub-table index for this particular non-leave node
{
current->value = table_count++;
build_tables(current, tables, table_count);
}

tables[table_index][n].next_table = &tables[current->value];
}
else
tables[table_index][n].next_table = &tables[0];
}
}

最佳答案

由于 tablestable_count 总是引用相同的对象,您可以通过使用 tablestable_count 来获得小的性能提升build_tables 的参数列表中取出,方法是将它们存储为临时结构的成员,然后执行如下操作:

struct build_tables_struct
{
build_tables_struct(std::array<std::array<entry, 8>, 255>& tables, int& table_count) :
tables(tables), table_count(table_count) {}
std::array<std::array<entry, 8>, 255>& tables;
int& table_count;
build_tables_worker(node* root)
{
...
build_tables_worker(current); // instead of build_tables(current, tables, table_count);
...
}
}

void build_tables(node* root, std::array<std::array<entry, 8>, 255>& tables, int& table_count)
{
build_tables_struct(tables, table_count).build_tables_worker(root);
}

当然,这仅适用于您的编译器不够智能,无法自行进行此优化的情况。

唯一可以使这个非递归的方法是自己管理堆栈。我怀疑这是否比递归版本快得多。

综上所述,我怀疑这里的性能问题是递归造成的。将三个引用参数压入堆栈并调用一个函数,与您的函数所做的工作相比,我认为这不是一个巨大的负担。

关于c++ - 递归到迭代的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7248760/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com