java - 将方案翻译成java

标签 java scheme lisp sicp code-translation

在阅读 SICP 期间,我通过练习 2.32 进行鼓励。

We can represent a set as a list of distinct elements, and we can represent the set of all subsets of the set as a list of lists. For example, if the set is (1 2 3 4), then the set of all subsets is (() (4) (3) (3 4) (2) (2 4) (2 3) (2 3 4) (1) (1 4) (1 3) (1 3 4) (1 2) (1 2 4) (1 2 3) (1 2 3 4)). Complete the following definition of a procedure that generates the set of subsets of a set and give a clear explanation of why it works:

(define (subsets s)
  (if (null? s)
      (list nil)
      (let ((rest (subsets (cdr s))))
        (append rest (map ⟨??⟩ rest)))))
(define (subset s)
     (if (null? s)
         (list '())
         (let ((rest (subset (cdr s))))
             (append
                  rest (map (lambda (x) (cons (car s) x)) rest)
             )
         )))

(subset '(1 2 3 4))
1 ]=> 
;Value 15: (() (4) (3) (3 4) (2) (2 4) (2 3) (2 3 4) (1) (1 4) (1 3) (1 3 4) (1 2) (1 2 4) (1 2 3) (1 2 3 4))

我可以用模式来做到这一点,但之后我想知道:“我可以用java做什么?”。我思考这个问题是因为我无法理解为什么如果我们在每个递归中都获得前一个递归的子列表,它会起作用。

当然我可以用其他方式解决。 例如,使用这种方法:所有可能的组合 2^N-1,对于我们的例子,这是 2^4-1

number binary result
1      0001    (4)
2      0010    (3)
3      0011    (3,4)
4      0100    (2)
5      0101    (2,4)
6      0110    (2,3)
7      0111    (2,3,4)
8      1000    (1)
9      1001    (1,4)
10     1010    (1,3)
11     1011    (1,3,4)
12     1100    (1,2)
13     1101    (1,2,4)
14     1110    (1,2,3)
15     1111    (1,2,3,4)

我重写了一些方案代码以与java代码相似

(define (subset s)
     (if (null? s)
         (list '())
         ((lambda (rest)
                 (append rest (map (lambda (x) (cons (car s) x)) rest))
         )(subset (cdr s)))
     )
)
(subset '(1 2 3))
1 ]=> 
;Value 19: (() (4) (3) (3 4) (2) (2 4) (2 3) (2 3 4) (1) (1 4) (1 3) (1 3 4) (1 2) (1 2 4) (1 2 3) (1 2 3 4))

我编写了我的java实现

import java.util.*;
import java.util.function.UnaryOperator;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.*;

public class A {
    public static void main(String[] args) {
        List<Integer> l = new ArrayList<>(asList(1,2,3));

        System.out.println(subset(l));
    }

    private static List<List<Integer>> subset(final List<Integer> s) {
        if (s.isEmpty()) return new ArrayList<>();

        final UnaryOperator<List<List<Integer>>> f = (final List<List<Integer>> rest) -> {
            final List<List<Integer>> collect = rest.stream()
                    .map(x -> {
                        List<Integer> r = new ArrayList<>();
                        r.add(s.get(0));
                        r.addAll(x);

                        return r;
                    })
                    .collect(toList());

            rest.addAll(collect);

            return rest;
        };

        return f.apply(subset(new ArrayList<>(s.subList(1, s.size()))));
    }

}

在java中我有一个空列表(我将Set更改为List以便无需任何技巧即可获得索引0)。正如我之前提到的,我理解为什么我的 java 返回空列表,但我不明白如何修复我的 java 代码,使其行为与方案匹配。

最佳答案

您的基本情况是错误的。方案表达式 (list '())不计算为空列表:它计算为单元素列表,其元素是空列表。在 Java 中,您编写了 new ArrayList<>()作为基本情况,这是一个空列表。相反,使用类似 Arrays.asList(new ArrayList<>()) 的内容.

关于java - 将方案翻译成java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57119564/

相关文章:

java - 将 JAR 文件放在哪里以避免冲突?

java - 通过类加载器加载 Maven Artifact

scheme - 计算列表和子列表的元素

具有 2 个参数的计划过程

lisp - 通过 CFFI 传递获取结果的指针

loops - 为什么我的 Common Lisp 循环只适用于普通代码?

java - 使用 Java 8 迭代 Map<String,Object> 数组并返回 Map<Long,Long>

java - MovableObject java语法错误

scheme - 列表中的相对质数

Lisp:高级字符串比较