class Item { private String name; private int helperInfo; public Item() { this.helperInfo = 0; } public Item(String name) { this.name = name; this.helperInfo = 0; } public Item(Item item) { this.name = item.getName(); this.helperInfo = item.getHelperInfo(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getHelperInfo() { return helperInfo; } public void setHelperInfo(int helperInfo) { this.helperInfo = helperInfo; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Item item = (Item) o; return name != null ? name.equals(item.name) : item.name == null; } @Override public int hashCode() { return name.hashCode(); } } public static ArrayList<Item> vertex = new ArrayList<>(); public void genVertex() { Item a = new Item("A"); Item b = new Item("B"); Item c = new Item("C"); Item d = new Item("D"); Item e = new Item("E"); Item f = new Item("F"); vertex.add(a); vertex.add(b); vertex.add(c); vertex.add(d); vertex.add(e); vertex.add(f); } //public ArrayList<ArrayList<Item>> edgeArr = new ArrayList<>(); public static int[][] arr = new int[6][6]; public static int circleCount = 0; public static Map<Item, Set<Item>> itemMap = new HashMap<>(); public void genCircleEdge() { for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { arr[i][j] = 0; } } arr[0][1] = 1; arr[1][2] = 1; arr[2][4] = 1; arr[3][4] = 1; arr[4][0] = 1; arr[4][5] = 1; arr[5][1] = 1; arr[5][3] = 1; } public void genNoCircleGraph() { for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { arr[i][j] = 0; } } arr[0][1] = 1; //arr[1][2] = 1; arr[2][4] = 1; //arr[3][4] = 1; arr[4][0] = 1; arr[4][5] = 1; arr[5][1] = 1; arr[5][3] = 1; } public int getVertexIndex(Item item) { int ret = -1; int size = vertex.size(); for (int i = 0; i < size; i++) { if (vertex.get(i).getName().equals(item.getName())) { ret = i; break; } } return ret; } public void trimStringBuffer(StringBuffer stringBuffer) { int lastIndexOfArray = stringBuffer.lastIndexOf("->"); int maxIndexOfString = stringBuffer.length(); stringBuffer.delete(lastIndexOfArray, maxIndexOfString); } public void depthTraverse(ArrayList<Item> bussinessList, ArrayList<Item> workStack, Item curItem, StringBuffer stringBuffer, Set<Item> dependencySet) { if (workStack.size() == 0) { return; } int row = bussinessList.indexOf(curItem); System.out.println("row:" + row); int childrenCount = 0; int businessSize = bussinessList.size(); for (int i = 0; i < businessSize; i++) { if (arr[row][i] == 1) { workStack.add(bussinessList.get(i)); childrenCount++; } } System.out.print("top "); for (int i = workStack.size() - 1; i >= 0; i--) { System.out.print(workStack.get(i).getName() + ","); } System.out.println(" bottom"); if (childrenCount == 0) { System.out.println("dependecyChain: " + stringBuffer.toString()); String dependencyChain = stringBuffer.toString(); String[] dependecyItems = dependencyChain.split("->"); int length = dependecyItems.length; for(int i = 0; i < length; i++ ) { Item item = new Item(dependecyItems[i]); dependencySet.add(item); } } for (int j = 0; j < childrenCount; j++) { int lastIndex = workStack.size() - 1; Item priorItem = workStack.get(lastIndex); workStack.remove(priorItem); if (priorItem.helperInfo == 0) { priorItem.helperInfo = 1; stringBuffer.append("->" + priorItem.getName()); depthTraverse(bussinessList, workStack, priorItem, stringBuffer, dependencySet); trimStringBuffer(stringBuffer); } else if (priorItem.helperInfo == 1) { stringBuffer.append("->" + priorItem.getName()); int beginIndex = stringBuffer.indexOf(priorItem.getName()); int tailIndex = stringBuffer.lastIndexOf(priorItem.getName()); if (tailIndex > beginIndex) { String circleBegin = stringBuffer.substring(beginIndex); System.out.println("circle:" + circleBegin); circleCount++; } else { depthTraverse(bussinessList, workStack, priorItem, stringBuffer, dependencySet); } trimStringBuffer(stringBuffer); } } curItem.helperInfo = 1; } public int checkCircle() { int size = vertex.size(); ArrayList<Item> bussinessList = new ArrayList<>(); for (int i = 0; i < size; i++) { Item item = vertex.get(i); Item newItem = new Item(item); bussinessList.add(newItem); } ArrayList<Item> workStack = new ArrayList<>(); StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < size; i++) { Item item = bussinessList.get(i); workStack.clear(); stringBuffer.delete(0, stringBuffer.capacity()); Set<Item> dependencySet = new HashSet<>(); if (item.helperInfo != 1) { workStack.add(item); stringBuffer.append(item.getName()); depthTraverse(bussinessList, workStack, item, stringBuffer, dependencySet); } } System.out.println("all circle:" + circleCount); return circleCount; } public void genDependencyChain() { circleCount = 0; checkCircle(); if(circleCount != 0) { return; } int size = vertex.size(); ArrayList<Item> bussinessList = new ArrayList<>(); for (int i = 0; i < size; i++) { Item item = vertex.get(i); Item newItem = new Item(item); bussinessList.add(newItem); } ArrayList<Item> workStack = new ArrayList<>(); StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < size; i++) { Item item = bussinessList.get(i); workStack.clear(); stringBuffer.delete(0, stringBuffer.capacity()); Set<Item> dependencySet = new HashSet<>(); workStack.add(item); stringBuffer.append(item.getName()); depthTraverse(bussinessList, workStack, item, stringBuffer, dependencySet); dependencySet.remove(item); itemMap.put(item, dependencySet); } } public void downloadBussiness(Set<Item> itemHashSet) { Iterator<Item> iterator = itemHashSet.iterator(); while (iterator.hasNext()) { Item it = iterator.next(); boolean dependencyOk = true; Set<Item> dependencySet = itemMap.get(it); if(dependencySet != null) { Iterator<Item> diter = dependencySet.iterator(); while(diter.hasNext()) { Item dependencyItem = diter.next(); if(!itemHashSet.contains(dependencyItem)) { System.out.println("item:" + it.getName() + " need " + dependencyItem.getName()); dependencyOk = false; } } } if(dependencyOk) { System.out.println("item:" + it.getName() + " can be download"); } } } @Test public void testCircle() { genVertex(); genCircleEdge(); checkCircle(); } @Test public void testDownLoadBusiness() { genVertex(); genNoCircleGraph(); genDependencyChain(); Set<Item> itemHashSet = new HashSet<Item>(); itemHashSet.add(new Item("A")); itemHashSet.add(new Item("D")); itemHashSet.add(new Item("C")); downloadBussiness(itemHashSet); } 检查环使用的时候每个子孩子的深度遍历,使用模拟的栈testCircle 结果输出:
row:0
top B,A, bottom
row:1
top C,A, bottom
row:2
top E,A, bottom
row:4
top F,A,A, bottom
row:5
top D,B,A,A, bottom
row:3
top E,B,A,A, bottom
circle:E->F->D->E
circle:B->C->E->F->B
row:0
top B,A, bottom
circle:B->C->E->A->B
all circle:3
Process finished with exit code 0
testDownLoadBusiness 输出结果:
row:0
top B,A, bottom
row:1
top A, bottom
dependecyChain: A->B
row:2
top E,C, bottom
row:4
top F,A,C, bottom
row:5
top D,B,A,C, bottom
row:3
top B,A,C, bottom
dependecyChain: C->E->F->D
row:1
top A,C, bottom
dependecyChain: C->E->F->B
row:0
top B,C, bottom
row:1
top C, bottom
dependecyChain: C->E->A->B
all circle:0
row:0
top B,A, bottom
row:1
top A, bottom
dependecyChain: A->B
row:1
top B, bottom
dependecyChain: B
row:2
top E,C, bottom
row:4
top F,A,C, bottom
row:5
top D,B,A,C, bottom
row:3
top B,A,C, bottom
dependecyChain: C->E->F->D
row:1
top A,C, bottom
dependecyChain: C->E->F->B
row:0
top B,C, bottom
row:1
top C, bottom
dependecyChain: C->E->A->B
row:3
top D, bottom
dependecyChain: D
row:4
top F,A,E, bottom
row:5
top D,B,A,E, bottom
row:3
top B,A,E, bottom
dependecyChain: E->F->D
row:1
top A,E, bottom
dependecyChain: E->F->B
row:0
top B,E, bottom
row:1
top E, bottom
dependecyChain: E->A->B
row:5
top D,B,F, bottom
row:3
top B,F, bottom
dependecyChain: F->D
row:1
top F, bottom
dependecyChain: F->B
item:A need B
item:C need B
item:C need E
item:C need F
item:D can be download
Process finished with exit code 0