software quality - How would you evaluate the following java solution or how would you solve it? -
how evaluate solution following task in regard of structure, correctness, simplicity, testability(task time approx. 1 hr):
create command-line java program counts unique words text file , lists top 10 occurrences.
english locale , treating hyphen , apostrophe part of word, output should following:
and (514)
the (513)
i (446)
to (324)
a (310)
of (295)
my (288)
you (211)
that (188)
this (185)
solution: wordcalculator.java(main class)
public class wordcalculator { /** * counts unique words text file , lists top 10 occurrences. * * @param args command line arguments. first argument file path. * if omitted, user prompted specify path. * * @throws java.io.filenotfoundexception if file other reason * cannot opened reading. * * @throws java.io.ioexception if i/o error occurs */ public static void main(string[] args) throws filenotfoundexception, ioexception { file file; list<string> listofwords = new arraylist<>(); // if command argument specified, use file path. // otherwise prompt user path. if (args.length > 0) { file = new file(args[0]); } else { scanner scanner = new scanner(system.in); system.out.print("enter path file: "); file = new file(scanner.nextline()); } // reads file , splits input list of words try (bufferedreader br = new bufferedreader(new filereader(file))) { string line; while ((line = br.readline()) != null) { listofwords.addall(wordutil.getwordsfromstring(line)); } } catch (filenotfoundexception ex) { logger.getlogger(wordcalculator.class.getname()).log(level.severe, string.format("access denied reading file '%s'.", file.getabsolutepath()), ex); throw ex; } catch (ioexception ex) { logger.getlogger(wordcalculator.class.getname()).log(level.severe, "i/o error while reading input file.", ex); throw ex; } // retieves top ten frequent words , frequencies. map<object, long> freqmap = frequencyutil.getitemfrequencies(listofwords); list<map.entry<?, long>> toptenwords = frequencyutil.limitfrequency(freqmap, 10); // prints top ten words , frequencies. toptenwords.foreach((word) -> { system.out.printf("%s (%d)\r\n", word.getkey(), word.getvalue()); }); } }
frequencyutil.java
public class frequencyutil { /** * transforms list map elements , frequencies. * * @param list, list parse * @return item-frequency map. */ public static map<object, long> getitemfrequencies(list<?> list) { return list.stream() .collect(collectors.groupingby(obj -> obj,collectors.counting())); } /** * sorts frequency map in descending order , limits list. * * @param objfreq map elements , frequencies. * @param limit limit of returning list * @return list top frequent words */ public static list<map.entry<?, long>> limitfrequency(map<?, long> objfreq, int limit) { return objfreq.entryset().stream() .sorted(map.entry.comparingbyvalue(comparator.reverseorder())) .limit(limit) .collect(collectors.tolist()); } } wordutil.java
public class wordutil { public static final pattern english_word_pattern = pattern.compile("[a-za-z'\\-]+"); /** * * @param s string parse list of words. words not matching * english pattern(a-z a-z ' -) omitted. * * @return list of words * */ public static list<string> getwordsfromstring(string s) { arraylist<string> list = new arraylist<>(); matcher matcher = english_word_pattern.matcher(s); while (matcher.find()) { list.add(matcher.group().tolowercase()); } return list; } }
your solution correct if looking less functional programming solution , more oop. should avoid use utils classes static methods. instead of can use wordcalculator adding instance methods , properties map count words. regex patterns heavy performance op , doing loops (in functional way) add splitted words map. other option read file byte per byte , when found non alphabetical character (it text file simple enough check whitespace) dump word stringbuilder map , add 1 counter. avoid possible problems if file huge 1 line text.
update 1 - read words example added:
private void readwords(file file) { try (bufferedreader bufferedreader = new bufferedreader(new filereader(file))) { stringbuilder build = new stringbuilder(); int value; while ((value = bufferedreader.read()) != -1) { if(character.isletterordigit(value)){ build.append((char)character.tolowercase(value)); } else { if(build.length()>0) { addtowordmap(build.tostring()); build = new stringbuilder(); } } } if(build.length()>0) { addtowordmap(build.tostring()); } } catch(filenotfoundexception e) { //todo manage exception e.printstacktrace(); } catch (ioexception e) { //todo manage exception e.printstacktrace(); } }
Comments
Post a Comment