【问题标题】:Get each object within depth object获取深度对象内的每个对象
【发布时间】:2018-05-24 06:08:25
【问题描述】:

我有这个 Person 对象。每个人都有一个人对象列表等,并且可以是无限的

    public class Person {

        private List<Person> people = new ArrayList<>();

        public Person() {
        }

        ...

        public List<Person> getPeople() {
            return people;
        }

        public void setPeople(List<Person> people) {
            this.people = people;
        }

        public int maxDepth() {
            int maxChildrenDepth = 0;
            for (Person prs: people) {
                maxChildrenDepth = Math.max(maxChildrenDepth, prs.maxDepth());
            }
            return 1 + maxChildrenDepth;
        }

        public static Set<Person> getPersonLevel(Person person, int depth) {
            Set<Person> ppl= new HashSet<>();
            if (depth > 0) {
                 person.getPeople().forEach(prs -> ppl.addAll(getPersonLevel(prs, depth - 1)));
    }
      return ppl;
    } 

问题 1:方法 --> maxDepth 不起作用。在该图像中,正确的最大深度为 3(请参见圆圈),但该方法给我的值为 4。

问题 2:根据 maxDepth,我想获取列表中的所有人。例如,如果我通过 maxdept 3 的人对象,如果我通过深度为 2,我应该得到所有 person 1person 2NOT person 3 在该图表的列表中。我通过编写该方法尝试了努力——> public static Set getPersonLevel(Person person, int depth) 但这不起作用,因为它一直返回空集。

感谢任何帮助

【问题讨论】:

  • 在 maxDepth 你返回 n+1 问题 2 可以使用递归来完成。
  • @Nathan 你是什么意思?
  • 你做return 1 + maxChildrenDepth; ...如果这个太多了,尽量不要加一个。
  • @Nathan 我确实删除了,它返回 0 而不是 2 并且不添加。关于问题2,我试过了,但是不行
  • 天哪,对不起,忽略我说的话。在移动应用上且滚动不足。

标签: java recursion collections java-8 depth


【解决方案1】:

我修改了你的代码如下:

public class Person {
        private List<Person> people = new ArrayList<>();
        private String name;
        public Person() {
        }
        public Person(String name) {
            this.name = name;
        }
        public List<Person> getPeople() {
            return people;
        }
        public void setPeople(List<Person> people) {
            this.people = people;
        }

        public int maxDepth() {
            if (people.isEmpty()) {
                return 0;
            }
            int maxChildrenDepth = 0;
            for (Person prs: people) {
                maxChildrenDepth = Math.max(maxChildrenDepth, prs.maxDepth());
            }
            return 1+maxChildrenDepth;
        }

       public static void getPersonLevel(Person person, int depth, Set<Person> ppl) {
            if (depth <= 0) {
                return;
            } else {
                for (Person prs : person.getPeople()) {
                    getPersonLevel(prs, depth - 1, ppl);
                }
            }
            ppl.addAll(person.getPeople());
       }

      //just for logging
       @Override
       public String toString() {
            return "Person [name=" + name + "]";
      }
}

问题 1 的客户端代码:p0 -> 人 0

System.out.println(p0.maxDepth());

问题 2 的客户端代码: p0 -> 人 0

Set<Person> ppl= new HashSet<>();
int depth = 2;
System.out.println(p0.getPersonLevel(p0, depth, ppl));

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    在你的方法中

        public int maxDepth() {
            int maxChildrenDepth = 0;
            for (Person prs: people) {
                maxChildrenDepth = Math.max(maxChildrenDepth, prs.maxDepth());
            }
            return 1 + maxChildrenDepth;
        }
    

    很明显,单个Person 对象,在其列表中没有任何元素,已经返回1(一)的深度。所以每增加一个关卡就会增加一个,在你的图片中,你有四个关卡,所以你得到四个结果。

    你的方法

    public static Set<Person> getPersonLevel(Person person, int depth) {
        Set<Person> ppl= new HashSet<>();
        if (depth > 0) {
             person.getPeople().forEach(prs -> ppl.addAll(getPersonLevel(prs, depth - 1)));
        }
        return ppl;
    }
    

    正在遍历整个Person 树,通过所有级别,但在任何时候,它实际上都没有向Set 添加任何元素。它所做的只是使用此递归方法的另一个结果的addAll,但只要没有实际添加发生,结果就是一个空集,并且使用带有空集的addAll 再次不会添加任何元素。

    主要障碍是您显然不想包含/计算您正在评估/调用方法的Person 实例。我建议直接将此行为设为可选,因此在遍历树时,您可以指示方法始终计算子元素。然后,您可以提供具有不计算根元素的默认行为的其他方法:

    public class Person {
        private List<Person> people = new ArrayList<>();
    
        public Person() {
        }
        public List<Person> getPeople() {
            return people;
        }
        public void setPeople(List<Person> people) {
            this.people = people;
        }
    
        public Stream<Person> people() {
            return people.stream();
        }
    
        public Stream<Person> peopleLevel(int depth, boolean includeThis) {
            if(depth<0) throw new IllegalArgumentException();
            if(depth==0) return includeThis? Stream.of(this): Stream.empty();
            Stream<Person> sub = people();
            if(depth > 1) sub = sub.flatMap(p -> p.peopleLevel(depth-1, true));
            return includeThis? Stream.concat(Stream.of(this), sub): sub;
        }
    
        public static Set<Person> getPersonLevel(Person person, int depth) {
            return person.peopleLevel(depth, false).collect(Collectors.toSet());
        }
    
        public int maxDepth() {
            return maxDepth(false);
        }
        public int maxDepth(boolean includeThis) {
            int chDepth = people().mapToInt(p -> p.maxDepth(true)).max().orElse(0);
            if(includeThis) chDepth++;
            return chDepth;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 2013-10-11
      • 2022-01-20
      • 2016-12-11
      • 2012-05-18
      • 2013-12-19
      相关资源
      最近更新 更多