如何在我的Java代码中替代递归?

huangapple go评论97阅读模式
英文:

How to replace recursion in my code on Java?

问题

这段代码计算了四个点中选择三个点的排列数(无重复)。原始的递归方法是这样的:

  1. import java.util.*;
  2. public class Main {
  3. static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
  4. static int[] temp = new int[POINTS_ON_LINE];
  5. public static void main(String[] args) {
  6. int[] points = new int[]{1,2,3,4};
  7. System.out.println("no repetitions:");
  8. p1(0,0, points);
  9. }
  10. static void p1(int nowPosition, int sizeArray, int[] points) {
  11. if (nowPosition == POINTS_ON_LINE) {
  12. System.out.println("Output:");
  13. System.out.println(Arrays.toString(temp));
  14. } else {
  15. for(int i = sizeArray + 1; i <= TOTAL_POINTS; i++) {
  16. temp[nowPosition] = points[i-1];
  17. p1(nowPosition + 1, i, points);
  18. }
  19. }
  20. }
  21. }

你想要去除递归调用,但是你的尝试没有成功。这里是一个替代方法:

  1. import java.util.*;
  2. import java.util.stream.Collectors;
  3. import java.util.stream.IntStream;
  4. public class Main {
  5. static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
  6. static int[] temp = new int[POINTS_ON_LINE];
  7. public static void main(String[] args) {
  8. int[] points = new int[]{1, 2, 3, 4};
  9. System.out.println("no repetitions:");
  10. p1(points, POINTS_ON_LINE);
  11. }
  12. public static void p1(int[] arr, int base) {
  13. int SIZE_ARRAY = arr.length;
  14. List<Integer> indices = IntStream.range(0, base).boxed().collect(Collectors.toList());
  15. for(Integer i : indices) {
  16. System.out.println("- " + i);
  17. }
  18. if (base < SIZE_ARRAY) {
  19. System.out.println("first");
  20. System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
  21. boolean flag;
  22. int i;
  23. while (true) {
  24. flag = false;
  25. for (i = base - 1; i >= 0; i--)
  26. if (indices.get(i) != i + SIZE_ARRAY - base) {
  27. flag = true;
  28. break;
  29. }
  30. if (!flag)
  31. return;
  32. indices.set(i, indices.get(i) + 1);
  33. for (int j = i + 1; j < base; j++)
  34. indices.set(j, indices.get(j - 1) + 1);
  35. System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
  36. for(Integer x : indices) {
  37. System.out.println("- " + x);
  38. }
  39. }
  40. }
  41. }
  42. }

这个替代方法使用了一个while循环来生成排列,而不是递归调用。

英文:

This code calculates the number of permutations for four points by 3 (no repetitions).
Arranged with recursion, but this is awkward for me.

  1. import java.util.*;
  2. public class Main {
  3. static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
  4. static int[] temp = new int[POINTS_ON_LINE];
  5. public static void main(String[] args) {
  6. int[] points = new int[]{1,2,3,4};
  7. System.out.println(&quot;no repetitions:&quot;);
  8. p1(0,0, points);
  9. }
  10. static void p1(int nowPosition, int sizeArray, int[] points) {
  11. if (nowPosition == POINTS_ON_LINE) {
  12. System.out.println(&quot;Output:&quot;);
  13. System.out.println(Arrays.toString(temp));
  14. } else {
  15. for(int i = sizeArray + 1; i &lt;= TOTAL_POINTS; i++) {
  16. temp[nowPosition] = points[i-1];
  17. p1(nowPosition + 1, i, points);
  18. }
  19. }
  20. }
  21. }

Output:

  1. no repetitions:
  2. Output:
  3. [1, 2, 3]
  4. Output:
  5. [1, 2, 4]
  6. Output:
  7. [1, 3, 4]
  8. Output:
  9. [2, 3, 4]

It is necessary to get rid of the recursive method call p1.
I tried to do so:

  1. import java.util.*;
  2. public class Main {
  3. static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
  4. static int[] temp = new int[POINTS_ON_LINE];
  5. public static void main(String[] args) {
  6. int[] points = new int[]{1,2,3,4};
  7. System.out.println(&quot;no repetitions:&quot;);
  8. p1(points);
  9. }
  10. static void p1(int[] points) {
  11. int sizeArray = points.length;
  12. for(int i = sizeArray + 1; i &lt; TOTAL_POINTS; i++, sizeArray = i) {
  13. int nowPosition = 0;
  14. if(nowPosition == POINTS_ON_LINE) {
  15. System.out.println(&quot;Output: &quot; + Arrays.toString(temp));
  16. } else {
  17. temp[nowPosition] = points[i-1];
  18. nowPosition++;
  19. }
  20. }
  21. }
  22. }

Result - Output on console - empty.
It didn't work for me.
How to replace recursion?

Method # 1 (thanks for the suggested option - @deadshot)

  1. package com.company;
  2. import java.util.*;
  3. import java.util.stream.Collectors;
  4. import java.util.stream.IntStream;
  5. public class Main {
  6. static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
  7. static int[] temp = new int[POINTS_ON_LINE];
  8. public static void main(String[] args) {
  9. int[] points = new int[]{1, 2, 3, 4};
  10. System.out.println(&quot;no repetitions:&quot;);
  11. p1(points, POINTS_ON_LINE);
  12. }
  13. public static void p1(int[] arr, int base) {
  14. int SIZE_ARRAY = arr.length;
  15. List&lt;Integer&gt; indices = IntStream.range(0, base).boxed().collect(Collectors.toList());
  16. for(Integer i : indices) {
  17. System.out.println(&quot;- &quot; + i);
  18. }
  19. if (base &lt; SIZE_ARRAY) {
  20. System.out.println(&quot;first&quot;);
  21. System.out.println(indices.stream().map(idx -&gt; arr[idx]).collect(Collectors.toList()));
  22. boolean flag;
  23. int i;
  24. while (true) {
  25. flag = false;
  26. for (i = base - 1; i &gt;= 0; i--)
  27. if (indices.get(i) != i + SIZE_ARRAY - base) {
  28. flag = true;
  29. break;
  30. }
  31. if (!flag)
  32. return;
  33. indices.set(i, indices.get(i) + 1);
  34. for (int j = i + 1; j &lt; base; j++)
  35. indices.set(j, indices.get(j - 1) + 1);
  36. System.out.println(indices.stream().map(idx -&gt; arr[idx]).collect(Collectors.toList()));
  37. for(Integer x : indices) {
  38. System.out.println(&quot;- &quot; + x);
  39. }
  40. }
  41. }
  42. }
  43. }

答案1

得分: 0

  1. import itertools
  2. TOTAL_POINTS = 4
  3. POINTS_ON_LINE = 3
  4. temp = [0] * POINTS_ON_LINE
  5. def main():
  6. points = [1, 2, 3, 4]
  7. print("no repetitions:")
  8. p1(points, POINTS_ON_LINE)
  9. def p1(arr, r):
  10. n = len(arr)
  11. indices = list(range(r))
  12. if r < n:
  13. for idx in indices:
  14. temp[idx] = arr[idx]
  15. print(temp)
  16. while True:
  17. flag = False
  18. for i in range(r - 1, -1, -1):
  19. if indices[i] != i + n - r:
  20. flag = True
  21. break
  22. if not flag:
  23. return
  24. indices[i] += 1
  25. for j in range(i + 1, r):
  26. indices[j] = indices[j - 1] + 1
  27. for i in range(r):
  28. temp[i] = arr[indices[i]]
  29. print(temp)
  30. if __name__ == "__main__":
  31. main()
英文:

I have used python itertools.combinations code as reference to implement the method.

  1. public class Main {
  2. static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
  3. static int[] temp = new int[POINTS_ON_LINE];
  4. public static void main(String[] args) {
  5. int[] points = new int[]{1, 2, 3, 4};
  6. System.out.println(&quot;no repetitions:&quot;);
  7. p1(points, POINTS_ON_LINE);
  8. }
  9. public static void p1(int[] arr, int r) {
  10. int n = arr.length, i;
  11. int[] indices = new int[r];
  12. for (i = 0; i &lt; r; i++)
  13. indices[i] = i;
  14. if (r &lt; n) {
  15. for (int idx : indices)
  16. temp[idx] = arr[idx];
  17. System.out.println(Arrays.toString(temp));
  18. boolean flag;
  19. while (true) {
  20. flag = false;
  21. for (i = r - 1; i &gt;= 0; i--)
  22. if (indices[i] != i + n - r) {
  23. flag = true;
  24. break;
  25. }
  26. if (!flag)
  27. return;
  28. indices[i] += 1;
  29. for (int j = i + 1; j &lt; r; j++)
  30. indices[j] = indices[j - 1] + 1;
  31. for (i = 0; i &lt; r; i++)
  32. temp[i] = arr[indices[i]];
  33. System.out.println(Arrays.toString(temp));
  34. }
  35. }
  36. }
  37. }

huangapple
  • 本文由 发表于 2020年8月23日 03:27:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63540279.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定