Java 使用DFS查找一组字符串
我们有一个自定义数据结构,具有以下属性: id,它可以访问的id列表(可以为空),字符串(可以为空) e、 g 给定起始id“Donald”,并且我们试图收集的目标字符串集是Java 使用DFS查找一组字符串,java,depth-first-search,Java,Depth First Search,我们有一个自定义数据结构,具有以下属性: id,它可以访问的id列表(可以为空),字符串(可以为空) e、 g 给定起始id“Donald”,并且我们试图收集的目标字符串集是[“a”、“c”、“d”],请列出访问目标集中所有字符串的所有可能方法。每次尝试通过id访问项目时,我们都需要确保此id有效。 对于上面给出的示例,一个可能的路径是[[“Donald”]、[“Sarah”、“d”]、[“Thomas”、“a”]、[“Donald”]、[“Lisa”、“c”] 另一个例子是,给定一个起始id“
[“a”、“c”、“d”]
,请列出访问目标集中所有字符串的所有可能方法。每次尝试通过id访问项目时,我们都需要确保此id有效。
对于上面给出的示例,一个可能的路径是[[“Donald”]、[“Sarah”、“d”]、[“Thomas”、“a”]、[“Donald”]、[“Lisa”、“c”]
另一个例子是,给定一个起始id“Sarah”
,我们试图收集的目标字符串集是[“a”,“d”],一个可能的路径是[[“Sarah”,“d”],[“Thomas”,“a”]
下面是我试图解决这个问题的方法。因为数据库可能非常大,所以我将所有变量作为类变量存储在HashMap中。然后使用DFS搜索目标字符串列表
每次它搜索当前项以及idList中的所有项时,如果找到匹配项,则将此项添加到路径,直到它在目标中找到所有字符串。这个过程是递归完成的
但是,这不是一个典型的DFS,因为它尝试遍历的列表每次都是不同的,而且,无论发生什么情况,都应该始终将第一项添加到路径中。这就是我被卡住的原因
我在代码中犯了一个粗心的错误,谢谢@Mil4n指出它。以下是修改后的代码:
import java.util.*;
public class TestFinder {
Map<String, Item> map = new HashMap<String, Item>();
public void finder(List<String> targets, String startid){
List<List<String>> path = new ArrayList<List<String>>();
List<List<List<String>>> result = new ArrayList<List<List<String>>>();
dfs(startid, targets, path, result);
// print out result
System.out.println(result.size());
for(int i=0; i<result.size(); i++){
for(int j=0; j<result.get(i).size(); j++){
for(int k=0; k<result.get(i).get(j).size(); k++){
System.out.println(result.get(i).get(j).get(k) + " ");
}
}
System.out.println();
}
}
public void dfs(String id, List<String> targets, List<List<String>> path, List<List<List<String>>> pathList){
if(targets.size() == 0){
pathList.add(new ArrayList<List<String>>(path));
return;
}
if(!map.containsKey(id)){
System.out.println("This is doesn't exist!");
return;
}
List<String> list = new ArrayList<String>();
list.add(id); // add current item id to the head of list
list.addAll(map.get(id).idList);
int size = list.size();
for(int i=0; i<size; i++){
if(i==0){
Item cur = map.get(list.get(i));
List<String> l = new ArrayList<String>();
l.add(cur.id);
if(targets.contains(cur.str)){
l.add(cur.str);
targets.remove(cur.str);
}
path.add(l);
}
// else if i is greater than 0, set this id in idList as visited by removing it from idList
else if(map.containsKey(list.get(i))){
System.out.println("i is greater than 0");
Item curTemp = map.get(list.get(i));
List<String> idListTemp = curTemp.idList;
idListTemp.remove(list.get(i));
map.remove(id);
map.put(curTemp.id, new Item(curTemp.id, idListTemp, curTemp.str));
List<String> l = new ArrayList<String>();
l.add(map.get(curTemp.id).id);
if(targets.contains(map.get(curTemp.id).str)){
l.add(map.get(curTemp.id).str);
targets.remove(map.get(curTemp.id).str);
}
path.add(l);
if(i<size-1){
dfs(list.get(i+1), targets, path, pathList);
path.remove(path.size()-1);
}
}
} // end for
}
public void buildInput(){
List<String> temp1 = new ArrayList<String>();
temp1.add("Donald");
temp1.add("Barbara");
Item it1 = new Item("Thomas", temp1, "a");
map.put("Thomas", it1);
List<String> temp2 = new ArrayList<String>();
temp2.add("Sarah");
temp2.add("Lisa");
Item it2 = new Item("Donald", temp2, "");
map.put("Donald", it2);
List<String> temp3 = new ArrayList<String>();
Item it3 = new Item("Lisa", temp3, "c");
map.put("Lisa", it3);
List<String> temp4 = new ArrayList<String>();
temp4.add("Lisa");
temp4.add("Thomas");
temp4.add("Barbara");
Item it4 = new Item("Sarah", temp4, "d");
map.put("Sarah", it4);
List<String> temp5 = new ArrayList<String>();
temp5.add("Sarah");
Item it5 = new Item("Barbara", temp5, "e");
map.put("Barbara", it5);
}
public static void main(String[] args) {
TestFinder tf = new TestFinder();
tf.buildInput();
List<String> targets = new ArrayList<String>();
targets.add("a");
targets.add("c");
targets.add("d");
tf.finder(targets, "Donald");
}
}
class Item{
String id;
List<String> idList;
String str;
Item(String i, List<String> il, String s){
id = i;
idList = il;
str = s;
}
}
import java.util.*;
公共类TestFinder{
Map Map=newhashmap();
公共无效查找器(列出目标,字符串startid){
列表路径=新的ArrayList();
列表结果=新建ArrayList();
dfs(起始、目标、路径、结果);
//打印结果
System.out.println(result.size());
对于(int i=0;i(1)如果块不正确,则可以选择else(假设没有循环引用)
在您第一次通过循环之前,您的列表如下所示:[Donald,Sarah,Lisa]
一旦迭代器达到i=1(Sarah)
在else-if条件中,检查Sarah是否有权访问Sarah,返回false
(2) 这不会将当前项放在列表的顶部:
List<String> list = new ArrayList<String>();
list.add(id); // add current item id to the head of list
List List=new ArrayList();
list.add(id);//将当前项id添加到列表的头部
这将:
List<String> list = new ArrayList<String>();
list.add(id); // add current item id to the head of list
list.addAll(map.get(id).idList);
List List=new ArrayList();
list.add(id);//将当前项id添加到列表的头部
list.addAll(map.get(id.idList));
(3) 如果要遍历所有项,则应为i List<String> list = new ArrayList<String>();
list.add(id); // add current item id to the head of list
list.addAll(map.get(id).idList);