Java递归食物分配

Java递归食物分配,java,recursion,Java,Recursion,我有以下清单: 动物食品 猫鱼 狗肉 牛肉 我想以尽可能多的方式为动物分配食物,如: 每种不同的动物和食物组合都将存储在地图中 (猫吃鱼, (狗吃猪肉) (猫吃鱼, (狗吃牛肉) (猫吃猪肉, (狗吃鱼) (猫吃猪肉, (狗吃牛肉) (猫吃牛肉, (狗吃鱼) (猫吃牛肉, (狗吃猪肉) 最后,所有的地图将放在一个集合中并返回 我正在尝试使用递归函数来实现这一点,下面是我如何尝试的。。但是我不能把它做好,所以请帮我把它做好 提前感谢 private static Set<Map<Ani

我有以下清单:

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

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

(猫吃鱼, (狗吃猪肉)

(猫吃鱼, (狗吃牛肉)

(猫吃猪肉, (狗吃鱼)

(猫吃猪肉, (狗吃牛肉)

(猫吃牛肉, (狗吃鱼)

(猫吃牛肉, (狗吃猪肉)

最后,所有的地图将放在一个集合中并返回

我正在尝试使用递归函数来实现这一点,下面是我如何尝试的。。但是我不能把它做好,所以请帮我把它做好

提前感谢

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));
}
private static Set eats(列出动物,列出食物){
Set returnSet=newhashset();
Map Map=newhashmap();
如果(animal.size()==0){
return null;//没有要喂养的动物
}否则{
animalLoop:for(int i=0;i
欢迎来到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);
            }
        }
    }
}
import java.util.ArrayList;
导入java.util.List;
公共类位置{
私人食品;
公共静态void main(字符串[]args){
//使用而不是字符串
列出动物=新建ArrayList();
动物。添加(“狗”);动物。添加(“猫”);
//使用食物>而不是字符串
食品=新ArrayList();
食品。添加(“猪肉”);食品。添加(“牛肉”);食品。添加(“鱼”);
allocateFood(动物,空);
}
//递归分配
私有静态void allocateFood(列出动物、字符串){
//在对列表进行迭代时不能更改列表
//所以,让我们来看看动物
List animalsCopy=新阵列列表(动物);
//环游动物
用于(字符串动物:动物){
//在食物上兜圈子
用于(串食物:食物){
如果(食物等于(吃的)){
继续;
}
//(添加到集合而不是打印)
System.out.println(动物+“吃”+食物);
动物复制。移除(动物);
//食物已经吃了
分配食物(动物、食物);
}
}
}
}

如果我们需要保留方法指纹而不运行全局访问跟踪结构,这里有一个工作程序供参考

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);
    }
}
对于递归深度优先搜索,需要注意两件事:终端状态条件,以及如何将当前步骤应用于来自(未来)终端状态的部分结果

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


通过hashCode()进行Java测试。Map将hashCode计算为所有项目的总和,每个项目都采用hashCode(k)^hashCode(v)。默认情况下,每个枚举值都有一个唯一的哈希代码。因此,可以直接添加地图元素。

动物吃食物,所以你的地图应该是:
Map
。另一个问题是,当元素在循环中使用时,不能将其从列表中删除。我发现缺少组合。你的猫和狗不能同时吃猪肉?谢谢,但如果只吃一只动物,我希望食物吃完。因此,其他动物无法获得同样的食物。不,如果一种食物被一种动物吃了,它就吃完了,而另一种动物需要吃另一种。你好,谢谢你的回答,但我仍然无法继续。更改第60行代码后,FoodCopy=allocateFood(animalsCopy,FoodCopy);to animalsCopy=分配食物(animalsCopy,FoodCopy)<代码>代码每次运行我都能获得分配,但我想要的是所有可能分配的列表。并且该方法应该返回“动物吃食物”的列表。该方法返回
foodCopy
,因此它应该是
foodsCopy=allocateFood(animalsCopy,foodsCopy)。正如我写的,这不是一个完整的解决方案,而是让你开始的东西。您的帖子是关于“递归”食物分配的,但发布的代码不是递归的。“递归解决方案”是需求的一部分吗?谢谢,是的,我想尝试使用递归。当我使用foodCopy时,我得到了三个分配,而不是两个(对于两个动物),我编辑了代码。我想这会让你接近你想要达到的目标。非常感谢。正是我想要的!
{CAT=BEEF, DOG=PORK}
{CAT=PORK, DOG=BEEF}
{CAT=BEEF, DOG=FISH}
{CAT=FISH, DOG=BEEF}
{CAT=FISH, DOG=PORK}
{CAT=PORK, DOG=FISH}