Home > Net >  Referring to an instance that refers to an instance
Referring to an instance that refers to an instance

Time:10-08

I am not sure if the title to this question is correct. I have this school assignment where we have to create two classes. In one class, we define relationships between people e.g. A knows B, and in the other class we ask questions about that, e.g. does A know B?

The first class below defines relationships and gives methods, the second class inquires about them. I am sure that my mistake lies somewhere in the public boolean 'knowsWithDegree'. Are you able to help?

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));

}

}

CodePudding user response:

Here is an example using recursion:



        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;
        }
        

If the order of the knowsArrows doesn't matter, I would recommend using HashSet in your map over ArrayList.

  • Related