001package algs13; 002 003import stdlib.StdOut; 004import stdlib.Trace; 005 006/** 007 * MyListAccessor (debugging). 008 * <p> 009 * This homework is intended to give you hands-on experience debugging and testing code. The intent is to give 010 * you more practice with linked lists and develop your intuition about how linked lists work. 011 * <p> 012 * Instructions: 013 * <p> 014 * 1. Make sure you have watched last week's lecture. Read over the main method and the test methods to develop an understanding 015 * of what they are doing. 016 * <p> 017 * 2. Look for the TODO in the code below. 018 * <p> 019 * 3. Utilize the techniques presented (your choice of Inspection, print statements, trace on paper, Trace utility, 020 * or IntelliJ Interactive debugger) to find and fix the bugs. 021 * <p> 022 * This is a "written homework" assignment. You do NOT need to submit this file with solutions as part of this homework. 023 * You DO need to submit your answers to the questions posed below. 024 */ 025public class MyListAccessor { 026 027 private Node first; 028 private int N; 029 030 private static class Node { 031 final double item; 032 Node next; 033 034 Node(double item, Node next) { 035 this.item = item; 036 this.next = next; 037 } 038 } 039 040 public int numFives1() { 041 int result = 0; 042 for (Node x = first; x != null; x = x.next) 043 if (x.item == 5.0) 044 result = result + 1; 045 return result; 046 } 047 048 public int numFives2() { 049 Node x = first; 050 int result = 0; 051 while (x != null) { 052 if (x.item == 5.0) 053 result = result + 1; 054 x = x.next; 055 } 056 return result; 057 } 058 059 public int numFives3() { 060 Node x = first; 061 int result = 0; 062 while (x != null) { 063 if (x.item == 5.0) 064 result = result + 1; 065 x = x.next.next; 066 } 067 return result; 068 } 069 070 public int numFives4() { 071 if (first == null) return 0; 072 int result = 0; 073 if (first.item == 5.0) 074 result = result + 1; 075 Node x = first; 076 while (x.next != null) { 077 if (x.next.item == 5.0) 078 result = result + 1; 079 x.next = x.next.next; 080 } 081 return result; 082 } 083 084 public int numFives5() { 085 int result = 0; 086 for (Node x = first; x.next != null && x.next.item == 5.0; x = x.next) { 087 result += 1; 088 } 089 return result; 090 } 091 092 public int numFives6() { 093 if (first == null) return 0; 094 int result = 0; 095 if (first.item == 5.0) 096 result = result + 1; 097 Node x = first; 098 while (x.next != null) { 099 if (x.item == 5.0) 100 result = result + 1; 101 x = x.next; 102 } 103 return result; 104 } 105 106 public int numFives7() { 107 if (first.next == null) return 0; 108 Node x = first; 109 int result = 0; 110 while (x.next != null) { 111 if (x.item != 5.0) x = x.next; 112 if (x.item == 5.0) { 113 result = result + 1; 114 x = x.next; 115 } 116 } 117 if (x.next == null && x.item == 5.0) { 118 result = result + 1; 119 } 120 return result; 121 } 122 123 public int numFives8() { 124 if (first == null) return 0; 125 Node x = first; 126 Node y = first.next; 127 int result = 0; 128 while (x != null) { 129 if (x.item == 5.0) result = result + 1; 130 x = y; 131 } 132 return result; 133 } 134 135 public int numFives9() { 136 int result = 0; 137 if (first.item == 5.0) 138 result = result + 1; 139 Node x = first; 140 while (x.next != null) { 141 if (x.next.item == 5.0) 142 result = result + 1; 143 x = x.next; 144 } 145 return result; 146 } 147 148 public int numFives10() { 149 int result = 0; 150 for (Node x = first; x != null; x = x.next) { 151 if (x.item == 5.0) 152 result = result + 1; 153 x = x.next; 154 } 155 return result; 156 } 157 158 /** 159 * TODO: Change this to invoke each method, numFives1, numFives2, ... numFives10, 160 * in turn. You can comment out the first line and uncomment the second line. 161 * <p> 162 * For each version of the method, tell me: 163 * <p> 164 * a. Whether there is a bug or not. (Note: There are no compiler errors in this file). 165 * b. What's wrong with the method and how to fix it. 166 * <p> 167 * Fix the code for each method to make it work. Some of the implementations may end up 168 * looking the same, or very similar. 169 * <p> 170 * Write your answers the the questions about each implementation of numFives on paper, 171 * or put them in a Word document. Upload a scan of your handwritten answers or your 172 * Word document to D2L. Do not submit image files directly, although you can paste 173 * photographs of your handwritten answers into the Word document. A better alternative 174 * would be to use a scanning app on your phone, and submit a PDF of your handwritten answers. 175 * <p> 176 * You do not need to hand in this file. 177 */ 178 179 public static int numFives(MyListAccessor list) { 180 return list.numFives1(); 181 // return list.numFives2(); 182 // return list.numFives3(); 183 // return list.numFives4(); 184 // return list.numFives5(); 185 // return list.numFives6(); 186 // return list.numFives7(); 187 // return list.numFives8(); 188 // return list.numFives9(); 189 // return list.numFives10(); 190 } 191 192 /* A main function for testing */ 193 public static void main(String[] args) { 194 195 // TODO: If you want, you can uncomment this line of code and use Trace for visualizing 196 // the execution of the program. 197 // Trace.run(); 198 Trace.drawStepsOfMethod("numFives1"); 199 Trace.drawStepsOfMethod("numFives2"); 200 Trace.drawStepsOfMethod("numFives3"); 201 Trace.drawStepsOfMethod("numFives4"); 202 Trace.drawStepsOfMethod("numFives5"); 203 Trace.drawStepsOfMethod("numFives6"); 204 Trace.drawStepsOfMethod("numFives7"); 205 Trace.drawStepsOfMethod("numFives8"); 206 Trace.drawStepsOfMethod("numFives9"); 207 Trace.drawStepsOfMethod("numFives10"); 208 209 testNumFives(3, listOf(11, 21, 5, 31, 5, 41, 5, 51)); 210 testNumFives(4, listOf(11, 21, 5, 31, 5, 5, 41, 5, 51)); 211 testNumFives(4, listOf(11, 21, 5, 5, 5, 31, 41, 5, 51)); 212 testNumFives(0, listOf(11, 21, 31, 41)); 213 testNumFives(1, listOf(11, 21, 5, 31, 41)); 214 testNumFives(1, listOf(11, 21, 31, 41, 5)); 215 testNumFives(1, listOf(5, 11, 21, 31, 41)); 216 testNumFives(0, listOf(11)); 217 testNumFives(1, listOf(5)); 218 testNumFives(3, listOf(5, 5, 5)); 219 testNumFives(0, listOf()); 220 StdOut.println("Finished tests"); 221 } 222 223 @Override 224 public String toString() { 225 StringBuilder b = new StringBuilder(); 226 Node x = first; 227 b.append("[ "); 228 while (x != null) { 229 if (x != first) b.append(", "); 230 b.append(x.item); 231 x = x.next; 232 } 233 b.append(" ]"); 234 return b.toString(); 235 } 236 237 private static MyListAccessor listOf(double... items) { 238 Node next = null; 239 for (int i = items.length - 1; i >= 0; i--) { 240 next = new Node(items[i], next); 241 } 242 MyListAccessor list = new MyListAccessor(); 243 list.first = next; 244 list.N = items.length; 245 return list; 246 } 247 248 /* This is a test function */ 249 private static void testNumFives(int expected, MyListAccessor list) { 250 int actual = numFives(list); 251 if (expected != actual) { 252 StdOut.format("Failed: Expecting [%d] Actual [%d] with argument %s\n", expected, actual, list.toString()); 253 } 254 checkInvariants(list); 255 } 256 257 private static void showError(String message) { 258 Trace.draw(); 259 StdOut.println(message); 260 throw new Error(); // stops execution 261 } 262 263 private static void checkInvariants(MyListAccessor that) { 264 int N = that.N; 265 Node first = that.first; 266 if (N < 0) throw new Error(); 267 if (N == 0) { 268 if (first != null) { 269 showError("N==0, Expected first == null."); 270 } 271 } else { 272 if (first == null) { 273 showError("N!=0, Expected first != null."); 274 } 275 } 276 if (N > 0) { 277 Node current = first; 278 for (int i = 0; i < N; i++) { 279 if (current == null) { 280 showError(String.format("N==%d, Expected %d next nodes, but got fewer.", N, N)); 281 return; 282 } 283 current = current.next; 284 } 285 if (current != null) { 286 showError(String.format("N==%d, Expected %d next nodes, but got more.", N, N)); 287 } 288 } 289 } 290}