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;
+ }
+}