Java递归食物分配

时间:2017-04-30 02:06:19

标签: java recursion

我有以下列表:

动物食物 鲶鱼 狗猪肉             牛肉 我想以尽可能多的方式为动物分配食物,如:

每种不同的动物和食物组合都将存储在地图中。

(猫吃鱼, 狗吃猪肉)

(猫吃鱼, 狗吃牛肉)

(猫吃猪肉, 狗吃鱼)

(猫吃猪肉, 狗吃牛肉)

(猫吃牛肉, 狗吃鱼)

(猫吃牛肉, 狗吃猪肉)

最后,所有地图都会被放入一个集合中并返回。

我正在尝试使用递归函数,以下是我尝试的方法..但是我无法正确使用它,所以请帮助我做到。

提前致谢!!!

private static Set<Map<Animal, Food>> eats(List<Animal> animal, List<Food> food) {
    Set<Map<Animal, Food>> returnSet = new HashSet<Map<Animal, Food>>();
    Map<Animal, Food> map = new HashMap<Animal, Food>();
    if (animal.size() == 0) {
        return null; // There is no animal to feed
    } else {
        animalLoop: for (int i = 0; i < animal.size(); i++) {
            foodLoop: for (int j = 0; j < food.size(); j++) {
                map.put(animal.get(i), food.get(j));
                food.remove(j);
                break venueLoop;
                }
            }
            animal.remove(i);
            returnSet.add(map);
        }

    }
    return returnSet.add(eats(animal, food));
}

2 个答案:

答案 0 :(得分:1)

如果我们需要保留方法指纹并且不运行全局访问跟踪结构,这是一个可供参考的工作程序。

import java.util.*;
import java.util.stream.Collectors;

public class SFO_Recursive {
    public enum Animal {
        CAT, DOG ;
    }
    public enum Food {
        FISH, BEEF, PORK ;
    }

    private static Set<Map<Animal, Food>> eats(List<Animal> animal, List<Food> food) {
        Set<Map<Animal,Food>> fleet = new HashSet();
        for (Animal a: animal){
            for (Food f: food){
                // Take a step with (a, f)
                List<Food> food_left = food.stream().filter(x -> !x.equals(f)).collect(Collectors.toList());
                List<Animal> animal_left = animal.stream().filter(x -> !x.equals(a)).collect(Collectors.toList());
                if (animal_left.isEmpty() || food_left.isEmpty()){
                    // Terminal state
                    fleet.add(new HashMap<Animal, Food>(){{put(a,f);}});
                }else {
                    eats(animal_left, food_left).stream().forEach(s -> {s.put(a, f); fleet.add(s); });
                }
            }
        }
        return fleet;
    }

    public static void main(String[] args){
        SFO_Recursive.eats(
            Arrays.asList(Animal.CAT, Animal.DOG),
            Arrays.asList(Food.BEEF, Food.FISH, Food.PORK)
        ).stream().forEach(System.out::println);
    }
}

结果是:

{CAT=BEEF, DOG=PORK}
{CAT=PORK, DOG=BEEF}
{CAT=BEEF, DOG=FISH}
{CAT=FISH, DOG=BEEF}
{CAT=FISH, DOG=PORK}
{CAT=PORK, DOG=FISH}

对于递归深度优先搜索,需要注意两件事:终端状态条件,以及如何将当前步骤应用于(未来)终端状态的部分结果。

如果我们必须保持方法指纹返回Set,输入为两个列表。终端条件是停止搜索的任一参数中的明显空列表。要将当前步骤应用于Set,我们可以循环所有地图,只需将新的Animal obj和新的Food obj的组合添加到每个地图,但依赖Set类来检查是否添加了唯一的Map。如果没有全局跟踪表,我们可以从动物和食物列表中删除消耗的元素,以将信息发送到下一个状态。

hashCode()的Java测试相等性。映射计算hashCode作为所有条目的总和,并且每个条目采用hashCode(k)^ hashCode(v)。默认情况下,每个枚举值都有一个唯一的hashCode。因此,可以直接添加Map元素。

答案 1 :(得分:0)

欢迎来到SO。这是让你入门的东西。这不是整个解决方案,只是一个起点。请参阅评论,并毫不犹豫地询问是否需要进一步澄清:

import java.util.ArrayList;
import java.util.List;

public class FoodAllocation{

    private static List<String> foods;

    public static void main(String[] args) {

        //use <Animal> instead of String
        List<String> animals = new ArrayList<>();
        animals.add("Dog");animals.add("Cat");

        //use Food> instead of String
        foods = new ArrayList<>();
        foods.add("Pork"); foods.add("Beef"); foods.add("Fish");

        allocateFood(animals, null);
    }

    //recursively allocate
    private static void allocateFood(List<String> animals, String eaten) {

        //you can't change a list while iterating  over it
        //so make a of animals
        List<String> animalsCopy = new ArrayList<>(animals);

        //loop over animals
        for (String animal : animals) {

            //loop over food
            for( String food : foods) {

                if(food.equals(eaten)) {
                    continue;
                }

                //(add to a collection instead of printing )
                System.out.println(animal +" eats " + food);
                animalsCopy.remove(animal);

                //food has been eaten 
                allocateFood(animalsCopy, food);
            }
        }
    }
}