Interface
interface RestaurantSet {
RestaurantSet[] parents();
RestaurantSet[] children();
/*
* @param allRestaurants RestaurantSet that represent restaurants
* @return map of root RestaurantSet to the list of restaurants under it.
*/
public static Map<RestaurantSet, RestaurantSet[]> organize(RestaurantSet[] allRestaurants) {
Map<RestaurantSet, RestaurantSet[]> result = new HashMap<RestaurantSet, RestaurantSet[]>();
for(RestaurantSet rest : allRestaurants) {
if(rest.parents().length == 0) {
ArrayList<RestaurantSet> rlist = new ArrayList<RestaurantSet>();
organizeRoot(rlist, rest);
result.put(rest, rlist.toArray(new RestaurantSet[0]));
}
}
return result;
}
private static void organizeRoot(ArrayList<RestaurantSet> rlist, RestaurantSet root) {
for(RestaurantSet rest : root.children()) {
rlist.add(rest);
organizeRoot(rlist,rest);
}
}
public static Map<RestaurantSet, RestaurantSet[]> organize1(RestaurantSet[] allRestaurants) {
Map<RestaurantSet, RestaurantSet[]> result = new HashMap<RestaurantSet, RestaurantSet[]>();
for(RestaurantSet rest : allRestaurants) {
if(rest.parents().length == 0) {
Set<RestaurantSet> rlist = new HashSet<RestaurantSet>();
organizeRoot1(rlist, rest, 0);
result.put(rest, rlist.toArray(new RestaurantSet[0]));
}
}
return result;
}
private static void organizeRoot1(Set<RestaurantSet> rlist, RestaurantSet root, int level) {
for(RestaurantSet rest : root.children()) {
// if(!rlist.contains(rest)) {
rlist.add(rest);
organizeRoot1(rlist,rest, level+1);
// }
}
if(level > 1) {
for(RestaurantSet rest : root.parents()) {
if(!rlist.contains(rest) && !rest.equals(root)) {
rlist.add(rest);
organizeRoot1(rlist,rest, level-1);
}
}
}
}
}
Implementations
public class RestaurantBranch implements RestaurantSet {
private String name;
private ArrayList<RestaurantSet> parents;
private ArrayList<RestaurantSet> children;
public RestaurantBranch(String newName) {
parents = new ArrayList<RestaurantSet>();
children = new ArrayList<RestaurantSet>();
name = newName;
}
@Override
public RestaurantSet[] parents() {
return parents.toArray(new RestaurantBranch[0]);
}
@Override
public RestaurantSet[] children() {
// TODO Auto-generated method stub
return children.toArray(new RestaurantBranch[0]);
}
public void addChild(RestaurantBranch child) {
children.add((RestaurantBranch) child);
child.addParent(this);
}
public void addParent(RestaurantBranch child) {
parents.add((RestaurantBranch) child);
}
public void search(RestaurantBranch node) {
if (node == null)
return;
int n = node.children().length;
for(int i = 0; i < n; i++) {
search((RestaurantBranch) node.children()[i]);
}
// Traverse root
System.out.print(node.getName() + "->");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
///////////////// Try to print tree
public String printPreOrder(RestaurantBranch root) {
if (root == null) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append(root.getName());
if(root.children().length > 0) {
String pointerRight = "+--";
String pointerLeft = (root.children().length > 1) ? "|--" : "+--";
for(int i=0; i < root.children().length; i++) {
String pointer = (i < root.children().length - 1) ? "|--" : "+--";
traverseNodes(sb, "", pointer, (RestaurantBranch) root.children.get(i), i < root.children().length-1);
}
}
return sb.toString();
}
public void traverseNodes(StringBuilder sb, String padding, String pointer, RestaurantBranch node,
boolean hasRightSibling) {
if (node != null) {
sb.append("\n");
sb.append(padding);
sb.append(pointer);
sb.append(node.getName());
StringBuilder paddingBuilder = new StringBuilder(padding);
if (hasRightSibling) {
paddingBuilder.append("| ");
} else {
paddingBuilder.append(" ");
}
if(node.children().length > 0) {
String paddingForBoth = paddingBuilder.toString();
String pointerRight = "+--";
String pointerLeft = (node.children().length > 1) ? "|--" : "+--";
for(int i=0; i < node.children().length; i++) {
String nodepointer = (i < node.children().length - 1) ? "|--" : "+--";
traverseNodes(sb, paddingForBoth, nodepointer, (RestaurantBranch) node.children.get(i), i < node.children().length-1);
}
}
}
}
}
Runner
import static org.junit.jupiter.api.Assertions.*;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.Assert;
public class RestaurantBranchTest {
private static RestaurantBranch[] restSet;
public RestaurantBranchTest() {
RestaurantBranch rest1 = new RestaurantBranch("EC");
RestaurantBranch rest2 = new RestaurantBranch("MA");
RestaurantBranch rest3 = new RestaurantBranch("NH");
RestaurantBranch rest4 = new RestaurantBranch("US");
RestaurantBranch rest5 = new RestaurantBranch("T");
RestaurantBranch rest6 = new RestaurantBranch("WC");
RestaurantBranch rest7 = new RestaurantBranch("CA");
RestaurantBranch rest8 = new RestaurantBranch("OR");
RestaurantBranch rest9 = new RestaurantBranch("TS");
rest1.addChild(rest2);
rest1.addChild(rest3);
rest1.addChild(rest9);
rest5.addChild(rest3);
rest5.addChild(rest7);
rest6.addChild(rest7);
rest6.addChild( rest8);
rest4.addChild( rest1);
rest4.addChild( rest6);
this.restSet = new RestaurantBranch[] {rest1, rest2, rest3, rest4, rest5, rest6, rest7, rest8};
}
public static void main(String[] args) {
RestaurantBranchTest restTest = new RestaurantBranchTest();
restTest.givenRestSet_OrganizeAndPrint();
restTest.givenRestSetAndRoot_PrintTree(restSet[3]);
}
@Test
public void givenRestSet_OrganizeAndPrint() {
// Actually We should assert if result is equals to some predefined Map
// But since MAp contains arrays we cannot compare arrays in different orders
// Therefore we can iterate Map, sort arrays and then check each value.
// Quite complicated
RestaurantBranch rest;
Map<RestaurantSet, RestaurantSet[]> restMap = RestaurantSet.organize(this.restSet);
for (Map.Entry<RestaurantSet, RestaurantSet[]> entry : restMap.entrySet()) {
rest = (RestaurantBranch) entry.getKey();
System.out.print(rest.getName()+"->");
if(entry.getValue() != null) {
for(RestaurantSet child : entry.getValue()) {
rest = (RestaurantBranch) child;
System.out.print(rest.getName()+",");
}
}
System.out.println();
}
}
@Test
public void givenRestSetAndRoot_PrintTree(RestaurantBranch root) {
System.out.println(root.printPreOrder(root));
}
}