zeja
Erfahrenes Mitglied
Java:
package de.tutorials.quiz.one;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
/**
* tutorials.de Coding Quiz Nummer 1: Unscharfe Suche
*
* @author zeja
*
*/
public class UnsharpSearch {
/**
* Für unmarkiertes und markiertes Suchergebnis in einem Objekt.
*/
private static final class SearchResult {
final String plain;
final String marked;
private final boolean ignoreCase;
public SearchResult(final String plain, final String marked, final boolean ignoreCase) {
this.plain = plain;
this.marked = marked;
this.ignoreCase = ignoreCase;
}
// Equals und hashCode von eclipse generiert. Plain reicht aus,
// da es vom Inhalt her identisch mit marked ist.
// Sofern bei der Suche Groß- und Kleinschreibung ignoriert wurde,
// wird diese auch hier ignoriert. So erhält man
// keine doppelten Ergebnisse.
@Override
public int hashCode() {
final String compare = ignoreCase && plain != null ? plain.toUpperCase() : plain;
final int prime = 31;
int result = 1;
result = prime * result + ((compare == null) ? 0 : compare.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SearchResult other = (SearchResult) obj;
if (plain == null) {
if (other.plain != null)
return false;
} else {
if(ignoreCase){
if (!plain.equalsIgnoreCase(other.plain)){
return false;
}
}
else{
if (!plain.equals(other.plain)){
return false;
}
}
}
return true;
}
}
/**
* Durchsucht eine Wortliste nach einem gegebenen Suchwort.<br/> <br/>
*
* Dies ist eine unscharfe Suche:<br/>
* Ein Suchwort wird in der Liste gefunden,
* wenn es in einem Wort der Liste in der richtigen Reihenfolge der
* Buchstaben vorkommt.<br/>
*
* Beispiel:<br/>
* John F. Kennedy wird durch die Angabe von JFK gefunden.
*
* @param searchList Die zu durchsuchende Liste.
* @param lookFor Das Suchwort.
* @param ignoreCase <code>true</code> wenn Groß-/Kleinschreibung ignoriert
* werden soll.
* @return Die Ergebnisse der Suche.
*/
private static Set<SearchResult> doSearch(final Set<String> searchList,
final String lookFor, final boolean ignoreCase) {
final Set<SearchResult> resultList = new HashSet<SearchResult>();
//Buchstaben des Suchwortes in ein Array packen.
//Sofern ignoreCase = true, vorher in Großbuchstaben umwandeln.
//toCharArray wird nicht verwendet, da nicht in jedem Encoding jeder
//Buchstabe mit einem Char dargestellt werden kann.
final String[] arr = ignoreCase ? lookFor.toUpperCase().split("")
: lookFor.split("");
//Über die Wörter der Liste iterieren
for (final String possibleResult : searchList) {
int startIndex = 0;
//Sofern ignoreCase = true, zu durchsuchendes Wort
//für die Suche in Großbuchstaben umwandeln.
final String searchString = ignoreCase ? possibleResult
.toUpperCase() : possibleResult;
//Array mit den Buchstaben des Wortes für die Markierung
//des Suchergebnis
String[] marked = possibleResult.split("");
//Über die Buchstaben des Suchwort iterieren.
//Mittels indexOf(String,int) prüfen ob die Buchstaben
//in der richtigen Reihenfolge vorkommen.
//Bei i = 1 starten, da erstes Element im Array leer ist.
for (int i = 1; i < arr.length; i++) {
//Prüfen ob der
int res = searchString.indexOf(arr[i], startIndex);
if (res == -1) {
//Suche für dieses Wort abbrechen wenn Buchstabe nicht gefunden wird.
break;
} else {
//gefundenen Buchstaben markieren
marked[res + 1] = "<" + marked[res + 1] + ">";
//Startindex für indexOf Operation so setzen
//dass der gerade gefundene Buchstabe nicht nochmal
//gefunden wird
startIndex = res + 1;
//Wenn es sich um den letzten zu findenen Buchstaben
//handelt, das Wort der Ergebnisliste hinzufügen.
if (i == arr.length - 1) {
final StringBuilder b = new StringBuilder();
for (final String m : marked) {
b.append(m);
}
resultList.add(new SearchResult(possibleResult, b
.toString(),ignoreCase));
}
}
}
}
return resultList;
}
/**
* Liest die Liste von zu durchsuchenden Wörtern zeilenweise aus einer Datei
* ein und gibt dieser zurück.
*
* Doppelte Wörter werden durch das Set ignoriert.
*
* @param path Der Pfad von welchem die Liste eingelesen werden soll.
* @return Ein Set mit Suchwörtern.
* @throws IOException Wenn die Datei nicht gefunden wird, oder beim
* auslesen ein Fehler auftritt.
*/
private static Set<String> loadFromFile(final String path)
throws IOException {
final Set<String> searchList = new HashSet<String>();
final File f = new File(path);
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(f));
String line = null;
while ((line = reader.readLine()) != null) {
// Leerzeichen am Anfang und Ende entfernen. Sind
// für die Suche nicht relevant
searchList.add(line.trim());
}
} catch (IOException e) {
throw e;
} finally {
reader.close();
}
return searchList;
}
/**
* Gibt eine Hilfe zur Benutzung aus.
*/
private static void usage() {
System.out.println("Usage:");
System.out.println("\t[-i] ignore case");
System.out.println("\tPath to word file");
System.out.println("\tSearch word");
System.out.println("Example:");
System.out.println("java " + UnsharpSearch.class.getName()
+ " -i presidents.txt JFK");
}
public static void main(String[] args) throws IOException {
// -i ist optional, daher entweder 2 oder 3 Argumente erlaubt
if (args.length < 2 || args.length > 3) {
usage();
return;
}
int startIndex = 0;
boolean ignoreCase = false;
// Bei 3 Optionen muss die erste -i sein
if (args.length == 3) {
if (!args[0].equals("-i")) {
usage();
return;
} else {
ignoreCase = true;
startIndex++;
}
}
// Suchliste aus der Datei laden
final Set<String> searchList = loadFromFile(args[startIndex++]);
final String lookFor = args[startIndex++];
// Suche durchführen
final Set<SearchResult> resultList = doSearch(searchList, lookFor,
ignoreCase);
// Ergebnisse ausgeben wenn vorhanden
if (!resultList.isEmpty()) {
System.out.println("Your search for '" + lookFor
+ "' has the following results: ");
for (SearchResult result : resultList) {
System.out.println("\t" + result.plain + " (" + result.marked
+ ")");
}
} else {
System.out.println("Your search for '" + lookFor
+ "' has no results.");
}
}
}