我正在开展一个项目,其中我有三个盒子(截至目前),每个盒子都有一些颜色的球
所以我将它们存储在Map of String and List of String
中,如下所示。
Map<String, List<String>> boxBallMap = new LinkedHashMap<String, List<String>>();
上面地图中的数据可以是这样的 -
{box1=[blue, red, orange]}
{box2=[blue, red]}
{box3=[blue, red, orange]}
因此,盒子中球的可能组合可以是 -
(POINT A) ::所有具有相同球数的盒子 -
{box1=[blue, red, orange]}
{box2=[blue, red, orange]}
{box3=[blue, red, orange]}
or
(POINT B) ::任何一个盒子都没有球。所以让我们说box3没有任何球 -
{box1=[blue, red, orange]}
{box2=[blue, red, orange]}
{box3=[]}
or
(POINT C) ::有些盒子的球数较少。所以让我们说box2只有两个球 -
{box1=[blue, red, orange]}
{box2=[blue, red]}
{box3=[blue, red, orange]}
or
(POINT D) ::任何一个盒子都没有球。所以让我们说box3和box2没有任何球 -
{box1=[blue, red, orange]}
{box2=[]}
{box3=[]}
ProblemStatement: -
基于上面的输入,我需要返回一个List<Map<String, String>>
的映射,假设对于(POINT A),下面的映射将作为输出返回 -
[{box1=blue, box2=red, box3=orange},
{box1=red, box2=orange, box3=blue},
{box1=orange, box2=blue, box3=red}]
如果你看到,每一行的每一行都有替代颜色的球 - 意思是blue for box1
,red for box2
,orange for box3
。我不能在每一排都有相同颜色的球。所以这种组合是不可能的,因为它有两个盒子的相同颜色的球。
{box1=blue, box2=blue, box3=orange}
而且,在第二行中,我不会使用那个盒子的第一行中使用的那些球。
输出组合是根据传递的输入生成的,如(POINT A)所示。
现在,让我们说(POINT B)作为box3
没有任何球的输入,我将返回另一个映射,如下所示{{ 1}}以及 -
List<Map<String, String>>
在上面的输出中,您可以看到没有[{box1=blue, box2=red},
{box1=red, box2=orange},
{box1=orange, box2=blue}]
,因为没有输入,但每行的box1和box2都有球的替代颜色。
现在,让我们说(POINT C)作为box3
只有两种颜色的球的输入,我将返回另一个映射,如下所示{{ 1}}以及 -
box2
在上面的输出中,您可以在第二行看到没有List<Map<String, String>>
,因为[{box1=blue, box2=red, box3=orange},
{box1=red, box3=blue},
{box1=orange, box2=blue, box3=red}]
只有box2
和box2
颜色的球并且可以组合右边,box2在第一行和第三行,只是为了维持每一行都有交替颜色的球的规则。
现在我无法理解如何编写这样的方法,它可以返回我传递给这个问题的输入的映射基础?
注意: -
这里的盒子现在总是三个,但球可以如输入
中所示变化任何建议对此都有很大帮助。感谢。
更新: -
我的基本问题是给出了如上所示的球和盒的输入 - 我将如何返回映射,使得在每一行中,盒子使用交替/不同颜色的球并且他们需要确保在之前的一排,那些球的颜色没有被同一个盒子使用过。
对于(POINT C)作为red
只有两种颜色的球的输入,我想返回如下所示的映射,blue
为box2
好吧 -
List<Map<String, String>>
[{box1=blue, box2=red, box3=orange},
{box1=red, box3=blue},
{box1=orange, box2=blue, box3=red}]
,box1 has blue
,box2 has red
具有交替颜色的球。 box3 has orange
为什么? bcoz box1 has red
已经在box1的第一行中使用,box3在第二行中没有blue
。我之前遇到的解决方案,但这假设每个方框中的球数总是相同的 -
box2
如果我们可以修改它以开始接受我的输入作为Map并在球的数量可以不同时处理用例,那么它对我来说将变得非常容易
更新
如果我尝试使用下面的输入组合,那么我输出为空,这是错误的。
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;
}
但输出结果应如下所示 -
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");
,blue for box1
,red for box2
。orange for box3
{box1=blue, box2=blue, box3=orange}
的第二行不能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;
}
答案 0 :(得分:2)
基本上你必须将所有盒子与所有可能的颜色组合在一起。在每个新行中,一个框获得分配给它在上一行中的下一个颜色。如果你编写所有可能的盒子/颜色组合并写下所有索引,它会变得更清晰。 PointA 是一个很好的例子:
输入
{box1=[blue, red, orange]}
{box2=[blue, red, orange]}
{box3=[blue, red, orange]}
以上输入的所有组合都是(前面有 boxIndex,colorIndex ):
0,0 {box1=blue}
0,1 {box1=red}
0,2 {box1=orange}
1,0 {box2=blue}
1,1 {box2=red}
1,2 {box2=orange}
2,0 {box3=blue}
2,1 {box3=red}
2,2 {box3=orange}
您正在寻找以下输出:
{box1=blue, box2=red, box3=orange}
{box1=red, box2=orange, box3=blue}
{box1=orange, box2=blue, box3=red}
因此,您正在寻找的指数如下:
row1 0,0 1,1 2,2
row2 0,1 1,2 2,0
row3 0,2 1,0 2,1
现在,当你知道自己在寻找什么时,就可以轻松编写一些循环(免责声明:据我正确理解你的问题/未完全测试!!! ):
public List<Map<String, String>> create(Map<String, List<String>> input) {
List<Map<String, String>> output = new ArrayList<>();
// find all boxes
List<String> boxes = new ArrayList<>(input.keySet());
// find all colors
Set<String> distinctColors = new LinkedHashSet<>();
for(List<String> e : input.values()) {
for(String color : e) {
if(! distinctColors.contains(color)) {
distinctColors.add(color);
}
}
}
List<String> colors = new ArrayList<String>(distinctColors);
int colorIndex = 0;
for(int i = 0; i < boxes.size(); i++) {
Map<String, String> row = new LinkedHashMap<>();
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
if(boxColors.contains(color)) {
row.put(box, color);
}
}
}
return output;
}
以下是使用您提供的一些输入的一些测试:
<强>点A 强>
@Test
public void createFromPointA() {
// {box1=[blue, red, orange]}
// {box2=[blue, red, orange]}
// {box3=[blue, red, orange]}
// [{box1=blue, box2=red, box3=orange},
// {box1=red, box2=orange, box3=blue},
// {box1=orange, box2=blue, box3=red}]
// 0,0 {box1=blue}
// 0,1 {box1=red}
// 0,2 {box1=orange}
// 1,0 {box2=blue}
// 1,1 {box2=red}
// 1,2 {box2=orange}
// 2,0 {box3=blue}
// 2,1 {box3=red}
// 2,2 {box3=orange}
// 0,0 1,1 2,2
// 0,1 1,2 2,0
// 0,2 1,0 2,1
Map<String, List<String>> input = new LinkedHashMap<>();
input.put("box1", Arrays.asList("blue", "red", "orange"));
input.put("box2", Arrays.asList("blue", "red", "orange"));
input.put("box3", Arrays.asList("blue", "red", "orange"));
List<Map<String, String>> output = create(input);
for(Map<String, String> e : output) {
System.out.println(e);
}
}
<强> PointB 强>
@Test
public void createFromPointB() {
// {box1=[blue, red, orange]}
// {box2=[blue, red, orange]}
// {box3=[]}
// [{box1=blue, box2=red},
// {box1=red, box2=orange},
// {box1=orange, box2=blue}]
// 0,0 {box1=blue}
// 0,1 {box1=red}
// 0,2 {box1=orange}
// 1,0 {box2=blue}
// 1,1 {box2=red}
// 1,2 {box2=orange}
// 2,x {box3=blue}
// 2,x {box3=red}
// 2,X {box3=orange}
// 0,0 1,1 2,x
// 0,1 1,1 2,x
// 0,2 1,0 2,x
Map<String, List<String>> input = new LinkedHashMap<>();
input.put("box1", Arrays.asList("blue", "red", "orange"));
input.put("box2", Arrays.asList("blue", "red", "orange"));
input.put("box3", Collections.<String>emptyList());
List<Map<String, String>> output = create(input);
for(Map<String, String> e : output) {
System.out.println(e);
}
}
<强> PointC 强>
@Test
public void createFromPointC() {
// {box1=[blue, red, orange]}
// {box2=[blue, red]}
// {box3=[blue, red, orange]}
// [{box1=blue, box2=red, box3=orange},
// {box1=red, box3=blue},
// {box1=orange, box2=blue, box3=red}]
// 0,0 {box1=blue}
// 0,1 {box1=red}
// 0,2 {box1=orange}
// 1,0 {box2=blue}
// 1,1 {box2=red}
// 1,x {box2=orange}
// 2,0 {box3=blue}
// 2,1 {box3=red}
// 2,2 {box3=orange}
// 0,0 1,1 2,2
// 0,1 1,x 2,0
// 0,2 1,0 2,1
Map<String, List<String>> input = new LinkedHashMap<>();
input.put("box1", Arrays.asList("blue", "red", "orange"));
input.put("box2", Arrays.asList("blue", "red"));
input.put("box3", Arrays.asList("blue", "red", "orange"));
List<Map<String, String>> output = create(input);
for(Map<String, String> e : output) {
System.out.println(e);
}
}
<强> OUTPUTA 强>
{box1=blue, box2=red, box3=orange}
{box1=red, box2=orange, box3=blue}
{box1=orange, box2=blue, box3=red}
<强> OUTPUTB 强>
{box1=blue, box2=red}
{box1=red, box2=orange}
{box1=orange, box2=blue}
<强> OutputC 强>
{box1=blue, box2=red, box3=orange}
{box1=red, box3=blue}
{box1=orange, box2=blue, box3=red}
希望这有助于或至少为您找到解决方案提供一些提示。
修改强>
您可以替换外部for循环
for(int i = 0; i < boxes.size(); i++) {
与
for(int i = 0; i < colors.size(); i++) {
这样,生成的方向是在颜色数量不是方框的颜色数量之后。如果这对其他组合没有帮助,那么您可能需要在向行添加组合之前添加检查:
if(boxColors.contains(color) && notYetGenerated()) {
row.put(box, color);
}
编辑2
以下是isNotYetGenerated
private 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;
}
在create
方法中创建一个集合并将其传递给该方法。
Set<String> generationHistory = new LinkedHashSet<>();
int colorIndex = 0;
int index = boxes.size() > colors.size() ? boxes.size() : colors.size();
for(int i = 0; i < index; i++) {
Map<String, String> row = new LinkedHashMap<>();
output.add(row);
colorIndex = i;
for(int j = 0; j < index; 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);
}
}
}
测试PonitF
@Test
public void createFromPointF() {
// {box1=red, box2=blue, box3=orange}
// {box1=blue, box2=orange, box3=purple}
// {box1=red, box3=pink}
// {box3=red, box1=orange}
// {box3=blue}
// 0,0 {box1=red}
// 0,1 {box1=blue}
// 0,2 {box1=orange}
// 0,x {box1=purple}
// 0,x {box1=pink}
//
// 1,0 {box2=red}
// 1,1 {box2=blue}
// 1,2 {box2=orange}
// 1,x {box2=purple}
// 1,x {box2=pink}
//
// 2,0 {box3=red}
// 2,1 {box3=blue}
// 2,2 {box3=orange}
// 2,3 {box3=purple}
// 2,4 {box3=pink}
// 0,0 1,1 2,2
// 0,1 1,2 2,3
// 0,x 1,x 2,0
// 0,x 1,0 2,1
Map<String, List<String>> input = new LinkedHashMap<>();
input.put("box1", Arrays.asList("red", "blue", "orange"));
input.put("box2", Arrays.asList("red", "blue", "orange"));
input.put("box3", Arrays.asList("red", "blue", "orange", "purple", "pink"));
List<Map<String, String>> output = create(input);
Assert.assertEquals(
"{box1=red, box2=blue, box3=orange}\r\n" +
"{box1=blue, box2=orange, box3=purple}\r\n" +
"{box1=orange, box3=pink}\r\n" +
"{box3=red}\r\n" +
"{box2=red, box3=blue}\r\n", toString(output));
}
private String toString(List<Map<String, String>> output) {
StringWriter sw = new StringWriter();
for(Map<String, String> e : output) {
sw.write(e.toString());
sw.write("\r\n");
}
return sw.toString();
}
<强> OuputF 强>
{box1=red, box2=blue, box3=orange}
{box1=blue, box2=orange, box3=purple}
{box1=orange, box3=pink}
{box3=red}
{box2=red, box3=blue}
答案 1 :(得分:0)
您可能会考虑以下策略(代码未提供,因为这是“家庭作业”):
Ball
类Box
类,其中包含一个球数的计数方法,以及一个addBall方法通过创建列(框中包含最大球数的大小)开始处理输出,然后第1行从框1中拉出一个球,该球没有来自先前拉球的球颜色) 对于第2行从框2中拉出一个没有颜色的球) ...
答案 2 :(得分:0)
如果我正确理解了这个问题,你可以做的是:
希望这会有所帮助。没有密码,不得不睡觉。
编辑:这是伪代码:
arranged_colors = [] // empty list, this is you desired output
sort_the_boxes(boxes) // ascending, by the number of colors in it
while( there_are_more_colors_left() ) { // a method that is easy to implement
current_list = [] // empty list
for( box in boxes ) {
for( color in box ) {
if( not color in current_list ) {
current_list.add(color)
box.remove(color)
break
}
}
}
aranged_colors.add(current_colors)
}