【问题标题】:Referring to an instance that refers to an instance引用实例引用实例
【发布时间】:2021-10-07 15:52:10
【问题描述】:

我不确定这个问题的标题是否正确。

我有这个学校作业,我们必须创建两个班级。

在一个类中,我们定义了人与人之间的关系,例如A 知道 B,在另一堂课上我们会问一些问题,例如A认识B吗?

下面的第一个类定义关系并给出方法,第二个类查询它们。

我确信我的错误在于公共布尔值“knowsWithDegree”中的某个地方。你能帮忙吗?

public class SocialGraph {

    private HashMap<String, List<String>> map = new HashMap<String, List<String>>();
    
    public SocialGraph() {   // empty constructor
        map = new HashMap<String, List<String>>();
    }
    
    public void addIndividual(String a) {
        if (!map.containsKey(a)) {
            map.put(a, new ArrayList<String>());
        } else {
    
        }
    }
    
    public boolean hasKnowsArrow(String a, String b) {
        if (map.containsKey(a)) {
            return map.get(a).contains(b);
        } else {
            return false;
        }
    }
    
    public void addKnowsArrow(String a, String b) {
    
        if ((!map.containsKey(a) || !map.containsKey(b)) || (hasKnowsArrow(a, b))) {
        } else {
            map.get(a).add(b);
        }
    }
    
    public void removeKnowsArrow(String a, String b) {
    
        if ((!map.containsKey(a) || !map.containsKey(b)) || (!hasKnowsArrow(a, b))) {
        } else {
            map.get(a).remove(b);
        }
    }
    
    public boolean knowsWithDegree(String a, String b, int x) {
        Object[] keys = map.keySet().toArray();
    
        int y;
        y = 0;
    
        if (map.get(a).contains(b)) {
            y = 1;
        } else {
    
            if ((map.get(a).contains(map.get(keys[0]).contains(b))) || (map.get(a).contains(map.get(keys[1]).contains(b))) ||
                    (map.get(a).contains(map.get(keys[2]).contains(b))) || (map.get(a).contains(map.get(keys[3]).contains(b)))) {
                y = 2;
            }
        }
        if (x == y) {
            return true;
        } else
            return false;
        }
    }
    
    
    public class SocialGraphTest {
    
        public static void main(String[] args) {
            SocialGraph socialGraph = new SocialGraph();
            socialGraph.addIndividual("Anne");
            socialGraph.addIndividual("Daisy");
            socialGraph.addIndividual("Bob");
            socialGraph.addIndividual("Charlie");
        
        
            socialGraph.addKnowsArrow("Anne", "Bob");
            socialGraph.addKnowsArrow("Anne", "Daisy");
            socialGraph.addKnowsArrow("Bob", "Daisy");
            socialGraph.addKnowsArrow("Bob", "Charlie");
        
            System.out.println(socialGraph.hasKnowsArrow("Anne", "Bob")); //should be true
            System.out.println(socialGraph.hasKnowsArrow("Anne", "Daisy"));//should be true
            System.out.println(socialGraph.hasKnowsArrow("Bob", "Daisy"));//should be true
            System.out.println(socialGraph.hasKnowsArrow("Bob", "Charlie"));//should be true
            System.out.println(socialGraph.hasKnowsArrow("Anne", "Charlie")); //should be false
        
            System.out.println ();
        
            System.out.println (socialGraph.knowsWithDegree ("Anne", "Daisy", 1));
            System.out.println (socialGraph.knowsWithDegree ("Anne", "Charlie", 2));
            System.out.println (socialGraph.knowsWithDegree ("Anne", "Daisy", 3));
        
        }
    }
}

【问题讨论】:

  • 通过所有 map.get(a) 调用等来跟踪您的代码有点困难。建议以提高可读性:如果它们返回相同的内容,请调用它一次并将返回值分配给一个变量正确的名称。还要改进参数的名称,即 ab 很难遵循 - 也许更好地使用 sourcePersontargetPerson (源是图遍历开始的地方,目标是它应该结束的地方)。
  • 至于你班级的逻辑:尝试一次“跳”一次,即跟随箭头直到你没有选择,达到一个循环(保留一组你已经检查)或找到目标人。然后计算您需要多少跳(如果有不止一种方式,您可能必须为某些“路线”携带值,即 Anne 直接知道 Daisy(1 跳)或通过 Bob(2 跳)。

标签: java class hashmap instance


【解决方案1】:

这是一个使用递归的例子:



        public boolean knowsWithDegree(String a, String b, int x) {
            return knowsWithDegreeRecursive(a, b, x, new HashSet<>());
        }
        
        private boolean knowsWithDegreeRecursive(String a, String b, int x, Set<String> visited) {
            if (x < 1) {
                // x must be at least 1
                return false;
            }
            

            if (map.get(a).contains(b)) {
                // If a knows b, then the number of degrees should be 1
                return x == 1;
            }
            
            if (x == 1) {
                // Since the degree is 1 and a does not know b, then a does not know b to the specified degree
                return false;
            }
            
            // Go through each person that a knows
            for (String c : map.get(a)) {
                
                if (visited.contains(c)) {
                    // We've already checked this person
                    continue;
                }
                
                // Mark c as visited so we don't check them again
                visited.add(c);
                
                // See if this person knows b, with one fewer degree
                // e.g. if we're seeing if a knows b with a degree of 2, then c should know b with a degree of 1
                boolean knowsWithDegree = knowsWithDegreeRecursive(c, b, x - 1, visited);
                
                // If c knows b with the degree minus 1, then a knows b with the specified degree
                if (knowsWithDegree) {
                    return true;
                }
            }
            
            // a does not know b to the specified degree
            return false;
        }
        

如果knowsArrows 的顺序无关紧要,我建议在map 中使用HashSet 而不是ArrayList

【讨论】:

  • 难以置信,谢谢!唯一的问题是一个人可以同时通过 1 级和 2 级认识另一个人,但是这段代码将跳过任何进一步的询问,所以如果 A 认识 B,它仍然会给出 A 是否知道的问题B 通过 C,这应该是真的。不过非常感谢,今晚我会尝试一下,这很有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-14
  • 2013-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多