我正在一个项目上工作,目前有三个盒子,每个盒子都会有一些彩色的小球。
因此,我将它们存储在下面所示的字符串和字符串列表Map中。
Map<String, List<String>> boxBallMap = new LinkedHashMap<String, List<String>>();
上述地图中的数据可能是这样的 -
{box1=[blue, red, orange]}
{box2=[blue, red]}
{box3=[blue, red, orange]}
可能的球在盒子里的组合方式可以是 -
(点A) :: 所有盒子都有相同数量的球 -
{box1=[blue, red, orange]}
{box2=[blue, red, orange]}
{box3=[blue, red, orange]}
or
(B点) :: 任何一个盒子都没有球。假设盒子3里没有球 -
{box1=[blue, red, orange]}
{box2=[blue, red, orange]}
{box3=[]}
or
(点C) :: 有些盒子里的球数量较少。比如说,假设盒子2只有两个球 -
{box1=[blue, red, orange]}
{box2=[blue, red]}
{box3=[blue, red, orange]}
or
(点D) :: 任何一个盒子都没有任何球。假设盒子3和盒子2没有任何球 -
{box1=[blue, red, orange]}
{box2=[]}
{box3=[]}
问题陈述:-
根据上述输入,我需要返回一个映射,它将是 List<Map<String, String>>,假设对于(A点),下面的映射将作为输出返回 -
[{box1=blue, box2=red, box3=orange},
{box1=red, box2=orange, box3=blue},
{box1=orange, box2=blue, box3=red}]
在这里,如果您看到,每一行的每个盒子都有不同颜色的球 - 意思是盒子1为蓝色,盒子2为红色,盒子3为橙色。我不能在每一行中使用相同颜色的球。因此,这种组合是不可能的,因为它在两个盒子中有相同颜色的球。
{box1=blue, box2=blue, box3=orange}
并且,在第二行中,我不会使用那些已经在第一行中使用过的球放入该盒子。
输出组合是基于输入传递而生成的,如(A点)所示。
现在,假设对于(B点)作为输入,其中box3没有任何球,我将返回另一个映射,如下所示,它也将是List<Map<String,String>>类型。
[{box1=blue, box2=red},
{box1=red, box2=orange},
{box1=orange, box2=blue}]
在上面的输出中,您可以看到没有box3,因为没有输入,但是每行中的box1和box2都有交替颜色的球。
现在,假设对于输入(点C),其中box2仅有两种球的颜色,我将返回另一个映射,如下所示,它也将是List<Map<String, String>> -
[{box1=blue, box2=red, box3=orange},
{box1=red, box3=blue},
{box1=orange, box2=blue, box3=red}]
在上面的输出中,您可以看到第二行没有 box2,因为 box2 只有红色和蓝色的球,为了使组合正确,将 box2 安排在第一行和第三行,以保持每一行球颜色交替的规则。
现在我不明白如何编写这样的方法,该方法可以根据我传递的输入返回映射?
注意:现在盒子始终为三个,但球可能会按上述输入变化。
对此任何建议都将非常有帮助。谢谢。
更新:
我的基本问题是给定球和盒子的输入(如上所示)- 如何返回映射,以确保在每一行中,盒子使用交替/不同颜色的球,并且他们需要确保在前一行中,相同的盒子没有使用那些颜色的球。
对于 (C 点) 作为一个输入,其中 box2 只有两种颜色的球,我想返回如下所示的映射,它也将是 List> 类型的 -
[{box1=blue, box2=red, box3=orange},
{box1=red, box3=blue},
{box1=orange, box2=blue, box3=red}]
- 在第一行中,
盒子1是蓝色的,盒子2是红色的,盒子3是橙色的,里面有交替颜色的球。 - 在第二行中,
盒子1是红色的,为什么?因为蓝色已经在第一行的盒子1中使用了,而第二行的盒子3是蓝色的,没有盒子2。 - 第三行同理。
我之前提供的解决方案假设每个盒子里的球的数量总是相同的 -
public List<Map<String, String>> createMappings(List<String> boxes, List<String> balls) {
List<Map<String, String>> result = new ArrayList<Map<String, String>>();
for(int i = 0; i < balls.size(); i++) {
Map<String, String> row = new HashMap<String,String>();
for(int j = 0; j < boxes.size(); j++) {
String box = boxes.get(j);
int ballIndex = (j + i) % balls.size();
String ball = balls.get(ballIndex);
row.put(box, ball);
}
result.add(row);
}
return result;
}
如果我们能修改这个程序,使其开始接受我的输入作为Map,并处理当球的数量可以不同的情况,那么对我来说就会变得非常容易。
更新:
如果我尝试使用下面的输入组合,则输出为空,这是错误的。
List<String> balls1 = Arrays.asList();
List<String> balls2 = Arrays.asList();
List<String> balls3 = Arrays.asList("red", "blue");
Map<String, List<String>> maps = new LinkedHashMap<String, List<String>>();
maps.put("box3", balls3);
maps.put("box2", balls2);
maps.put("box1", balls1);
List<Map<String, String>> mappings = generateMappings(maps);
// below mappings is coming as empty somehow which is wrong
System.out.println(mappings);
但是对于上述输入,输出应该如下所示 -
[{box3=red}, {box3=blue}]
而且,它也不能处理以下输入 -
List<String> balls1 = Arrays.asList("red", "blue", "orange");
List<String> balls2 = Arrays.asList("red", "blue", "orange");
List<String> balls3 = Arrays.asList("red", "blue", "orange", "purple", "pink");
使用上述输入组合,我可以在其他行中看到相同颜色的球,这违反了第三个规则。
更新:
我的规则是:
1. 每一行的框中应该有交替颜色的球。如果您查看上面的内容,每行对于每个框都有交替的球颜色 - 意味着第一行的box1是蓝色,box2是红色,box3是橙色。
2. 其次,我不能在每行中使用同样颜色的球。因此下面的组合是不可能的,因为它在一行中有两个盒子有相同颜色的球。
{box1 = blue,box2 = blue,box3 = orange}
3. 第三,在下一行中,我不会使用早期行中使用过的箱子中的球。因此第二行不能使用blue作为box1,因为它已经由box1在第一行中使用过。
最终代码应该像这样 -
public static List<Map<String, String>> create(Map<String, List<String>> input) {
List<Map<String, String>> output = new ArrayList<Map<String, String>>();
// find all boxes
List<String> boxes = new ArrayList<String>(input.keySet());
// find all colors
Set<String> distinctColors = new LinkedHashSet<String>();
for (List<String> e : input.values()) {
for (String color : e) {
if (!distinctColors.contains(color)) {
distinctColors.add(color);
}
}
}
List<String> colors = new ArrayList<String>(distinctColors);
Set<String> generationHistory = new LinkedHashSet<String>();
int colorIndex = 0;
for(int i = 0; i < colors.size(); i++) {
Map<String, String> row = new LinkedHashMap<String, String>();
output.add(row);
colorIndex = i;
for(int j = 0; j < colors.size(); j++) {
int boxIndex = j;
if(boxIndex >= boxes.size()) {
boxIndex = 0;
}
String box = boxes.get(boxIndex);
List<String> boxColors = input.get(box);
if(colorIndex >= colors.size()) {
colorIndex = 0;
}
String color = colors.get(colorIndex++);
// a combination is generated only if the actual
// colors does exist in the actual box
// and it has not already been generated i all previous rows
if(boxColors.contains(color) && isNotYetGenerated(box, color, generationHistory)) {
row.put(box, color);
}
}
}
return output;
}
private static boolean isNotYetGenerated(String box, String color, Set<String> generationHistory) {
String key = box + "=" + color;
boolean notYetGenerated = !generationHistory.contains(key);
if (notYetGenerated) {
generationHistory.add(key);
}
return notYetGenerated;
}