// Jeremy Lipschutz // Reads in a .dot file and fills a Map to contain all the friendships in the Map // After reading in the file we can find how many friends 'away' two people are import java.io.*; import java.util.*; public class Friends { public static void main(String[] args) throws FileNotFoundException { System.out.println("Welcome to the cse143 friend finder."); Scanner input = new Scanner(new File("friends.dot")); // Each friend (String) has a corresponding friend group (Set) Map> friendships = readFile(input); Scanner console = new Scanner(System.in); System.out.print("starting name: "); String name1 = console.nextLine(); if(!friendships.containsKey(name1)) { System.out.println("That person is not in the .dot file"); } else { System.out.print("target name? "); String name2 = console.nextLine(); showMatches(friendships, name1, name2); } } // Constructs and returns a Map containing the friendships specified in the // given input. Friendships should be on separate lines with -- between the two names // that are friends with each other. public static Map> readFile(Scanner input) { Map> friendships = new TreeMap>(); while (input.hasNextLine()) { String line = input.nextLine(); if (line.contains("--")) { Scanner lineData = new Scanner(line); String name1 = lineData.next(); lineData.next(); // this skips the "--" token String name2 = lineData.next(); addToMap(friendships, name1, name2); addToMap(friendships, name2, name1); } } return friendships; } // Adds name2 as a friend of name1 in the map "friendships" public static void addToMap(Map> friendships, String name1, String name2) { // These two approaches are equivalent, but the second way is // much more concise /* if(friendships.containsKey(name1)) { Set theirFriends = friendships.get(name1); theirFriends.add(name2); // friendships.put(name1, theirFriends); } else { Set theirFriends = new TreeSet(); theirFriends.add(name2); friendships.put(name1, theirFriends); } */ if(!friendships.containsKey(name1)) { /* Set theirFriends = new TreeSet(); friendships.put(name1, theirFriends); */ friendships.put(name1, new TreeSet()); } /* Set theirFriends = friendships.get(name1); theirFriends.add(name2); */ friendships.get(name1).add(name2); } // Using the friendships stored in the map 'friendships', finds how many freinds // away name2 is from name1. Prints out all the friends and their distances along // the way and prints out if the two cannot reach other through mutual friends. public static void showMatches(Map> friendships, String name1, String name2) { System.out.println("Starting with " + name1); Set currentGroup = new TreeSet(); currentGroup.add(name1); int distance = 0; // We need to keep track of which friends we've already seen so that we // don't have duplicate names Set alreadySeen = new TreeSet(); // Keep expanding our blob of friends until we've reached the person // we are looking for, or we don't find any new people while(!currentGroup.contains(name2) && !currentGroup.isEmpty()) { alreadySeen.addAll(currentGroup); // Update my current blob of friends to be all their friends Set nextGroup = new TreeSet(); for(String person : currentGroup) { Set friends = friendships.get(person); nextGroup.addAll(friends); } currentGroup = nextGroup; // We want to remove all the people we've already seen currentGroup.removeAll(alreadySeen); distance++; System.out.println(" " + distance + " away: " + currentGroup); } if(currentGroup.isEmpty()) { System.out.println("not found"); } else { System.out.println("found at a distance of " + distance); } } }