diff --git a/.idea/misc.xml b/.idea/misc.xml index a165cb3..0c4841a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/db/pdata.txt b/db/pdata.txt new file mode 100644 index 0000000..f93232c --- /dev/null +++ b/db/pdata.txt @@ -0,0 +1,60 @@ +Dwight Joseph djo@gmail.com +Rene Webb webb@gmail.com +Katie Jacobs +Erick Harrington harrington@gmail.com +Myrtle Medina +Erick Burgess erb@mail.com +Romelia Trial +Carmella Thome tc9900@yahoo.com +Romelia Jopal +Paige Fritsche paige@mymail.cn +Charlsie Mendes +Sam Rusk  ruskrusk@msft.com +Joie Lenhart +Romelia Jordal +Tommye Rothfuss +Cassi Gifford  cassig@gmail.com +Ciera Barkley +Attaway Haffordy +Hiedi Slaubaugh f@mail.ru +Kenyetta Attaway +Irma Dunaway  Dunaway@Dunaway.com +Deidre Culotta +Cisco Romelia +Mack Keogh  keogh@bmw.com +Jame Remigio +Zackary Rish   +Berna Leedy +Leatrice Mcmanus   +Sierra Stockwell +Retta Bosh +Louis Nay  +Lesia Leaks +Del Muench +Consuela Choi   +Jalisa Yim +Janise Neighbors +Dorla Bucklin dorlsb@gmail.com +Kylie Manross +Dortha Morrissey +Ester Golding +Dawn Garson   +Stephania Boykins +Hertha Jefferis +Keshia Michna +Geraldine Schrader +Tad Steve tadsteve@mymail.com +Raeann Frese +Laure Burbidge +Maryanna Barnhart MaryannaBarn@gmail.com +Corrinne Hazelip +Monica Harrell +Brenton Lujan +Lisabeth Gress +Mafalda Laurent +Mendy Alcantar +Jackqueline Esteban +Rusty Noakes +Reginia Beltrami +Hanh Houck +Genia Royse diff --git a/src/simpleSearchEngine/Main.java b/src/simpleSearchEngine/Main.java index b8ecb08..5dd450b 100644 --- a/src/simpleSearchEngine/Main.java +++ b/src/simpleSearchEngine/Main.java @@ -1,7 +1,289 @@ package simpleSearchEngine; -public class Main { +import java.util.*; + +interface Searchable { + /** + * Returns values which should be indexed + **/ + List getIndex(); +} + +class Main { public static void main(String[] args) { - System.out.print("Hello world!"); + List persons = new ArrayList<>(); + Finder finder = new Finder<>(); + + try { + persons = Util.getPersonsFromFile("pdata.txt"); + finder.addAll(persons); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + + Scanner sc = new Scanner(System.in); + boolean cont = true; + while (cont) { + System.out.println(" === Menu ==="); + System.out.println(" 1. Find a person "); + System.out.println(" 2. Print all people"); + System.out.println(" 0. Exit "); + String inputLine = sc.nextLine(); + int input = -1; + try { + input = Integer.parseInt(inputLine); + } catch (Exception e) { + System.out.println("Only numeric options allowed."); + } + + switch (input) { + case 1: + System.out.println("Select a matching strategy: ALL, ANY, NONE. Enter /stop to terminate. Case sensitive."); + while (true) { + String strategy = sc.nextLine(); + if (strategy.trim().equals("/stop")) break; + try { + switch (strategy) { + + case "ALL": + System.out.println("Enter seach terms, delimited with whitespace. Programm will return records which contains all terms. Enter /stop to terminate."); + String termAll = sc.nextLine(); + String[] termsAll = termAll.trim().split(" "); + List allPersons = finder.findAll(termsAll); + printPersons(allPersons); + break; + case "ANY": + System.out.println("Enter seach terms, delimited with whitespace. Programm will return records which contains any of terms. Enter /stop to terminate."); + String termAny = sc.nextLine(); + String[] termsAny = termAny.trim().split(" "); + List anyPersons = finder.findAny(termsAny); + printPersons(anyPersons); + break; + case "NONE": + System.out.println("Enter seach terms, delimited with whitespace. Programm will return records which does not contain any of terms. Enter /stop to terminate."); + String noneTerm = sc.nextLine(); + String[] noneTerms = noneTerm.trim().split(" "); + List nonePersons = finder.findNone(noneTerms); + printPersons(nonePersons); + break; + default: + System.out.println("Select a matching strategy: ALL, ANY, NONE. Enter /stop to terminate. Case sensitive."); + break; + } + } catch (Exception e) { + System.out.println("An error occured: "); + e.printStackTrace(); + } + } + break; + + case 2: + System.out.printf("Found %d people: %n", persons.size()); + for (Person p : persons) { + System.out.print(p.toString()); + } + System.out.println(); + break; + + case 0: + cont = false; + System.out.println("Bye!"); + break; + + default: + System.out.println("Incorrect option. Try again."); + } + } + } + + private static void printPersons(List persons) { + if (persons != null) { + System.out.printf("Found %d people: %n", persons.size()); + for (Person person : persons) { + System.out.print(person.toString()); + } + System.out.println(); + } else { + System.out.println("No matching people found."); + } + } + + private static List addPersonsFromCLI(Scanner sc) { + List persons = new ArrayList<>(); + while (true) { + System.out.println("Enter persons data in format: first name | last name | email (optional). Each entry from a new line, delimit with spaces. To terminate enter /stop"); + String input = sc.nextLine(); + if (input.trim().equals("/stop")) break; + if (input.length() > 0) { + String[] words = input.trim().split(" "); + if (words.length >= 2) { + String lastName = words[1]; + String firstName = words[0]; + String email = (words.length == 3) ? words[2] : null; + Person person = new Person(firstName, lastName, email); + persons.add(person); + } else { + System.out.println("First name and last name are requied params"); + } + } + } + return persons; + } +} + +class Finder { + + private final boolean caseSensitive; + private final List elements; + private final Map> mapping; + + public Finder() { + caseSensitive = false; + elements = new ArrayList<>(); + mapping = new HashMap<>(); + } + + public Finder(boolean caseSensitive) { + this.caseSensitive = caseSensitive; + elements = new ArrayList<>(); + mapping = new HashMap<>(); + } + + public List getAll() { + return elements; + } + + public void addAll(List list) throws Exception { + for (T element : list) { + add(element); + } + } + + private void add(T element) throws Exception { + boolean elementAdded = elements.add(element); + int position = elements.lastIndexOf(element); + if (!elementAdded || position == -1) throw new Exception(); + addToIndex(element, position); + } + + private List findElements(Set indexes) { + if (indexes == null || indexes.size() == 0) return null; + List result = new ArrayList<>(); + for (Integer i : indexes) { + result.add(elements.get(i)); + } + return result; + } + + private Set find(String term) { + term = sanitizeIndexValue(term); + return mapping.getOrDefault(term, null); + } + + public List findAll(String[] terms) { + if (terms == null || terms.length == 0) return null; + Set result = new HashSet<>(); + for (String term : terms) { + if (result.size() == 0) { + Set init = find(term); + if (init != null) result.addAll(find(term)); + } else { + Set found = find(term); + if (found != null) { + result.retainAll(found); + } else { + return null; + } + } + } + return findElements(result); + } + + public List findAny(String[] terms) { + if (terms == null || terms.length == 0) return null; + Set result = new HashSet<>(); + for (String term : terms) { + if (result.size() == 0) { + Set init = find(term); + if (init != null) result.addAll(find(term)); + } else { + Set found = find(term); + if (found != null) { + result.addAll(found); + } + } + } + return findElements(result); + } + + public List findNone(String[] terms) throws Exception { + if (terms == null || terms.length == 0) return null; + List anys = findAny(terms); + + if (anys != null) { + List noneElements = new ArrayList<>(elements); + noneElements.removeAll(anys); + return noneElements; + } else return elements; + } + + private void addToIndex(T element, int pos) { + List index = element.getIndex(); + for (String string : index) { + string = sanitizeIndexValue(string); + if (string != null) { + if (mapping.containsKey(string)) { + Set postions = mapping.get(string); + postions.add(pos); + } else { + Set postions = new HashSet<>(); + postions.add(pos); + mapping.put(string, postions); + } + } + } + } + + private String sanitizeIndexValue(String string) { + if (string == null || string.trim().length() == 0) { + return null; + } + if (caseSensitive) { + return string.trim(); + } else { + return string.trim().toLowerCase(); + } + } +} + + +class Person implements Searchable { + private final String firstName; + private final String lastName; + private final String email; + + Person(String firstName, String lastName, String email) { + this.firstName = firstName; + this.lastName = lastName; + this.email = email; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + if (firstName != null) sb.append(firstName).append(" "); + if (lastName != null) sb.append(lastName).append(" "); + if (email != null) sb.append(email); + sb.append("; "); + return sb.toString(); + } + + public List getIndex() { + List result = new ArrayList<>(); + + if (firstName != null) result.add(firstName); + if (lastName != null) result.add(lastName); + if (email != null) result.add(email); + + return result; } } \ No newline at end of file diff --git a/src/simpleSearchEngine/Util.java b/src/simpleSearchEngine/Util.java new file mode 100644 index 0000000..aac5bc2 --- /dev/null +++ b/src/simpleSearchEngine/Util.java @@ -0,0 +1,43 @@ +package simpleSearchEngine; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +class Util { + + private static final String DB_PATH = "db\\"; + + public static List getPersonsFromFile(String filename) throws Exception { + List persons = new ArrayList<>(); + Path file = Paths.get(DB_PATH + filename); + try (InputStream in = Files.newInputStream(file); + BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { + String line; + while ((line = reader.readLine()) != null) { + + String[] words = line.trim().split(" "); + + switch(words.length) { + case 2: + Person p = new Person(words[0], words[1], null); + persons.add(p); + break; + case 3: + Person z = new Person(words[0], words[1], words[2]); + persons.add(z); + break; + + default: + System.out.println("Person entry should contain at least first name and last name delimited with space"); + } + } + } + return persons; + } +}