我使用了3个嵌套循环。现在我想将这些循环转换为递归。 还有一种将循环转换为递归的通用方法吗?
#include <stdio.h>
#define f(x, y, z) ((x + y) * (y + z))
int main()
{
int test_case, p, q, r, i, j, k, a[100001], b[100001], c[100001], sum;
scanf("%d", &test_case);
while (test_case--) {
scanf("%d%d%d", &p, &q, &r);
sum = 0;
for (i = 0; i < p; i++) {
scanf("%d", &a[i]);
}
for (i = 0; i < q; i++) {
scanf("%d", &b[i]);
}
for (i = 0; i < p; i++) {
scanf("%d", &c[i]);
}
for (i = 0; i < q; i++) { // I have convert this to recursion.
for (j = 0; j < p; j++) {
for (k = 0; k < r; k++) {
if (b[i] >= a[j] && b[i] >= c[k]) {
sum += f(a[j], b[i], c[k]);
}
}
}
}
printf("%d\n", sum % 1000000007);
}
return 0;
}
答案 0 :(得分:2)
像这样的循环:
for (int i=0; i<n; i++) {
func(i);
}
可以转换为递归:
void rec_fun(int i,int n) {
if (!(i<n)) return;
func(i);
rec_fun(i+1,n);
}
...
rec_fun(0,n);
所以:
for (i = 0; i < q; i++) { // I have convert this to recursion.
for (j = 0; j < p; j++) {
for (k = 0; k < r; k++) {
if (b[i] >= a[j] && b[i] >= c[k]) {
sum += f(a[j], b[i], c[k]);
}
}
}
}
可翻译为:
void rec_k(int k,int r,int i,int j) { // k-loop
if (!(k<r)) return;
if (b[i] >= a[j] && b[i] >= c[k]) {
sum += f(a[j], b[i], c[k]);
}
rec_k(k+1,r,i,j); // recurse
}
void rec_j(int j,int p,int i,int r) { // j-loop
if (!(j<p)) return;
rec_k(0,r,i,j); // inner loop
rec_j(j+1,p,i,r); // recurse
}
void rec_i(int i,int q,int p,int r) { // i-loop
if (!(i<q)) return;
rec_j(0,p,i,r); // inner loop
rec_i(i+1,q,p,r); // recurse
}
...
rec_i(0,q,p,r);
我不确定这是否更具可读性或有用性,但它符合您的初始需求。
答案 1 :(得分:1)
让我们假设此代码的意图是仅计算总和。
您可以将功能设为
int recurse_sum(int i, int j, int k) {
int res = .... // Logic for calculating sum for these indices i, j, k.
k++;
if (k==r) {
k = 0;
j++;
}
if(j==p){
j=0;
i++;
}
if(i==q){
return res;
}
return res + recurse_sum(i,j,k);
}
现在您只需拨打recurse_sum(0,0,0);
其余参数可以是全局的,也可以只与i,j,k一起传递。
我希望这会有所帮助。
编辑:
正如@dlasalle所提到的,通过将调用放在函数的末尾,可以使这个代码对尾调用递归优化开放。
在这种情况下,您可以使用以下版本。
int recurse_sum(int i, int j, int k, int sum) {
int res = .... // Logic for calculating sum for these indices i, j, k.
k++;
if (k==r) {
k = 0;
j++;
}
if(j==p){
j=0;
i++;
}
if(i==q){
return res + sum;
}
return recurse_sum(i,j,k,res+sum);
}
此处函数以从内部调用返回值结束,因此可以轻松优化。
在这种情况下,它必须被称为recurse_sum(0,0,0,0);
答案 2 :(得分:0)
感谢@ Jean-BaptisteYunès。
我对代码进行了这些更改,将其转换为递归。
#include<stdio.h>
#define f(x, y, z) ((x + y)*(y + z))
int sum=0;
void rec_k(int k,int r,int i,int j,int a[],int b[],int c[]) { // k-loop
if (!(k<r)) return;
if (b[i] >= a[j] && b[i] >= c[k]) {
sum += f(a[j], b[i], c[k]);
}
rec_k(k+1,r,i,j,a,b,c);
}
void rec_j(int j,int p,int i,int r,int a[],int b[],int c[]) { // j-loop
if (!(j<p)) return;
rec_k(0,r,i,j,a,b,c);
rec_j(j+1,p,i,r,a,b,c);
}
void rec_i(int i,int q,int p,int r,int a[],int b[],int c[]) { // i-loop
if (!(i<q)) return;
rec_j(0,p,i,r,a,b,c);
rec_i(i+1,q,p,r,a,b,c);
}
int main() {
int test_case, p, q, r, i, j, k, a[100001], b[100001], c[100001];
scanf("%d", &test_case);
while(test_case--) {
scanf("%d%d%d", &p, &q, &r);
sum=0;
for(i=0;i<p;i++) {
scanf("%d", &a[i]);
}
for(i=0;i<q;i++) {
scanf("%d", &b[i]);
}
for(i=0;i<p;i++) {
scanf("%d", &c[i]);
}
rec_i(0,q,p,r,a,b,c);
printf("%d\n", sum%1000000007);
}
return 0;
}