import java.util.*; import java.io.*; /* Implementation of the Ladders program November 15, 2004 Greg Nichols Modified by Sriram Pemmaraju. 2/3/2007 Modified again by Sriram Pemmaraju. 9/15/2007 Modified again by Sriram Pemmaraju. 9/23/2007 */ public class connectedComponents{ // returns true if the words are different by only one letter public static boolean differentByOne( String a, String b ) { int diffCount = 0; // make sure the two strings are both 5 letters long if( a.length() != 5 || b.length() != 5 ) return false; // check the letters of the strings for( int i = 0; i < a.length(); i++ ) { if( a.charAt(i) != b.charAt(i) ) if( ++diffCount > 1 ) return false; } return (diffCount == 1); } public static void main(String args[]) { String[] wordList; myGraph mg; mg = new myGraph(); wordList = new String[5800]; int counter = 0; try { // This is one way to read from a file. The list of all 5-letter words // is in a file called words.dat BufferedReader in = new BufferedReader(new FileReader("words.dat")); String word; // read all the words from the file System.out.println( "Reading words.dat..." ); while( (word = in.readLine()) != null ) { // make a new vertex w/ this word mg.addVertex( word ); // see what words it's one letter different from for( int i = 0; i < counter; i++ ) if( differentByOne(word, wordList[i])) mg.addEdge( word, wordList[i]); wordList[counter++] = word; } in.close(); } catch (IOException e) {} System.out.println("Done constructing the graph...."); // Put vertices of degree 1 and vertices of degree 2 in two separate arrays int countDegree2 = 0; int countDegree1 = 0; // Array for vertices of degree 2 String[] degree2Words = new String[mg.numberOfVertices()]; // Array for vertices of degree 1 String[] degree1Words = new String[mg.numberOfVertices()]; // Scan all words and pick up those with degree 1 and those with degree 2 for(int i = 0; i < mg.numberOfVertices(); i++) { if(mg.degree(wordList[i]) == 2) degree2Words[countDegree2++] = wordList[i]; if(mg.degree(wordList[i]) == 1) degree1Words[countDegree1++] = wordList[i]; } System.out.println("The number vertices of degree one is " + countDegree1); System.out.println("The number vertices of degree two is " + countDegree2); // Find all size-2 connected components int count2CC = 0; for(int i = 0; i < countDegree1; i++) { String a = mg.getNeighbors(degree1Words[i])[0]; if((mg.degree(a) == 1) && (degree1Words[i].compareTo(a) < 0)) { System.out.println("Size 2 CC "+ degree1Words[i] + " " + a); count2CC++; } } System.out.println("The number of size-2 connected components is " + count2CC); // Find all paths and triangles int countPaths = 0; int countTriangles = 0; // Find all paths and triangles for(int i = 0; i < countDegree2; i++) { String[] nbrsI = mg.getNeighbors(degree2Words[i]); String a = nbrsI[0]; String b = nbrsI[1]; // This condition tests to see if the neighbors are both degree 1 vertices // If so we have found a size-3 connected component that is a path // The comparison between a and b is to avoid double counting if((mg.degree(a) == 1) && (mg.degree(b) == 1) && (a.compareTo(b) < 0)) { System.out.println("Size 3 CC: path " + degree2Words[i] + " " + a + " " + b); countPaths++; } // This condition tests to see if the two neighbors are both degree 2 vertices and there is an edge between them // Again, the string comparisons are to avoid overcounting if((mg.degree(a) == 2) && (mg.degree(b) == 2) && (mg.isEdge(a, b)) && (degree2Words[i].compareTo(a) < 0) && (degree2Words[i].compareTo(b) < 0)) { System.out.println("Size 3 CC: triangle " + degree2Words[i] + " " + a + " " + b); countTriangles++; } } System.out.println("The number of paths is " + countPaths); System.out.println("The number of triangles is " + countTriangles); } }