Substringsuche + Ersetzung

hury

Erfahrenes Mitglied
Hi,

ich habe ein Problem:
Gegeben sind 2 Dateien A und B.

Datei A ist ein Export aus einer Datenbank, Datensätze sind durch ";" getrennt.
In Datei B stehen Integer drin - 1 pro Zeile.

Datei A soll nun nach allen Strings aus Datei B durchsucht werden. Bei Übereinstimmung sollen alle Integer, die sowohl in A und B vorkommen in einer Liste ausgegeben werden. Ebenfalls sollen auch Integer ausgegeben werden, die zB in 5 Stellen übereinstimmen.

Wie kriegt man das hin?

Grüße
Alex
 
Dein Stichwort lautet hier "Frequenzliste". Da könnte ich dir schon was coden, weil ich als Computerlinguist oft mit sowas konfrontiert werde. Allerdings bräuchte ich dazu noch ein paar Informationen.

Wenn du sagst, die Datensätze in Datei A seien durch ';' voneinander getrennt, willst du dann darauf aufmerksam machen, dass du nur bestimmte Spalten analysieren willst? Sprich: Wenn du Integer aus B mit Integern aus A vergleichen willst, dann müssen diese ja in einer bestimmten Spalte stehen.

Am besten wär's wohl, wenn du hier ein paar Zeilen aus A und ein paar Zeilen aus B angeben könntest. Dann könnte ich dir da was basteln.
 
Hi,

ja, der Suchinteger befindet sich in Datei A an einer bestimmten Stelle. Ich habe beides mal angehangen.

Gruss
Alex
 

Anhänge

  • datei_a.txt
    967 Bytes · Aufrufe: 39
  • datei_b.txt
    23 Bytes · Aufrufe: 33
Das hier sollte all das abdecken, was ich aus deiner Beschreibung herauslesen konnte. Aufruf: java GiveMeAName <fileA> <fileB>

Java:
import java.io.*;
import java.util.*;

public class GiveMeAName {
  public GiveMeAName(String fileA, String fileB) {
    A = new File(fileA);
    B = new File(fileB);
    if (A.isFile() && B.isFile())
      createLists();
  }
  
  private void createLists() {
    listA = hashFile(A);
    listB = hashFile(B);
    printEqualities();
    printSimilarities();
  }
  
  private HashMap<String, Integer> hashFile(File file) {
    HashMap<String, Integer> list = new HashMap<String, Integer>();
    try {
      BufferedReader reader = new BufferedReader(new FileReader(file));
      String line;
      while ((line = reader.readLine()) != null) {
        String[] parts = line.trim().replaceAll("\"", "").split(";");
        
        /*
         * Handelt es sich um File A, so sind an dieser Stelle die ein-
         * zelnen Spalten einer Zeile über Indices ansprechbar. Du kannst
         * hier also festlegen, welche Spalte analysiert werden soll.
         * Weil ich nicht weiß, um welche Spalte es sich handelt, überprüfe
         * ich einfach jede Spalte, die nur aus Integern besteht.
         */
         for (String col : parts) {
           if (col.matches("[0-9]+")) {
             if (!list.containsKey(col))
              list.put(col, 1);
             else
              list.put(col, list.get(col) + 1);
           }
         }
      }
      reader.close();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    return list;
  }
  
  /**
   * Gibt gleiche Integer aus
   */
  private void printEqualities() {
    System.out.println("EQUALITIES:");
    for (String keyB : listB.keySet())
      if (listA.containsKey(keyB))
        System.out.printf("%s: %d\t%s\t%s: %d\t%s\n",
          "List A", listA.get(keyB), keyB,
          "List B", listB.get(keyB), keyB);
  }
  
  /**
   * Gibt Integer aus, die von vorne in mind. 3 Stellen
   * miteinander übereinstimmen
   */
  private void printSimilarities() {
    System.out.println("\nSIMILARITIES:");
    int startCnt = 0;
    int similCnt = 3;
    for (String intA : listA.keySet()) {
      for (String intB : listB.keySet()) {
        if (intA.substring(startCnt, similCnt).equals(intB.substring(startCnt, similCnt)))
          System.out.println(intA + "\t'" + intA.substring(startCnt, similCnt) + "'");
      }
    }
  }

  public static void main(String[] args) {
    new GiveMeAName(args[0], args[1]);
  }
  
  private File A, B;
  private HashMap<String, Integer> listA, listB;
}
 
Zuletzt bearbeitet:
Hey,

wow, das ist stark - wie könnte man das Programm denn abändern, damit nicht nur die ersten X Stellen verglichen werden, sondern diese Suche auch ab der 1sten, 2ten etc Stelle wiederholt wird, bis die ganze Zahl durchgegangen ist.

Gruss
Alex
 
Nun, startCnt habe ich ja mit 0 initialisiert und similCnt mit 3. Bau da doch einfach 'ne Schleife rum. Beispielsweise so:

Java:
/* Mind. 5 Übereinstimmungen */
int similCnt = 5;

/* Es sollen Übereinstimmungen ab der 1. bis max. zur 5. Position von vorne gesucht werden */
int lastStartingPoint = 4;
for (int startCnt = 0; startCnt <= lastStartingPoint; startCnt++) {
  /* Jetzt müssen Substrings nach folgendem Muster erzeugt werden */
  if ((startCnt + similCnt) <= string.length)
    String substring = string.substring(startCnt, startCnt + similCnt);
  (...)
}

Da kannst du dich dann richtig austoben.
 
Ach, ich hatte überlesen, dass du ja die ganze Zahl durchforsten willst. Hier also eine entsprechende Version:

Java:
String toAnalyze = "08154711";
String toCompare = "0813471";
int substrLength = 2;
int startPoint = 0;
while (true) {
	if ((startPoint + substrLength) > toAnalyze.length() ||
     (startPoint + substrLength) > toCompare.length())
		break;
	else {
    	String substrA = toAnalyze.substring(startPoint, startPoint + substrLength);
    	String substrB = toCompare.substring(startPoint, startPoint + substrLength);
    	if (substrA.equals(substrB))
      		System.out.println(substrA);
  	}

  	startPoint++;
}

Dieser Code vergleicht immer jeweils die ersten beiden Zahlen/Zeichen des einen mit den ersten beiden Zahlen/Zeichen des zweiten Strings, dann die zweiten beiden, dann die dritten… Sobald 'startPoint + substrLength' größer als die Länge des kürzesten Strings ist, wird die Schleife abgebrochen.

Das lässt sich vielleicht noch elegenater coden, aber zumindest kann es dir als Anregung dienen.

Gruß,
Matthias
 
Das hier sollte all das abdecken, was ich aus deiner Beschreibung herauslesen konnte. Aufruf: java GiveMeAName <fileA> <fileB>

Java:
import java.io.*;
import java.util.*;

public class GiveMeAName {
  public GiveMeAName(String fileA, String fileB) {
    A = new File(fileA);
    B = new File(fileB);
    if (A.isFile() && B.isFile())
      createLists();
  }
  
  private void createLists() {
    listA = hashFile(A);
    listB = hashFile(B);
    printEqualities();
    printSimilarities();
  }
  
  private HashMap<String, Integer> hashFile(File file) {
    HashMap<String, Integer> list = new HashMap<String, Integer>();
    try {
      BufferedReader reader = new BufferedReader(new FileReader(file));
      String line;
      while ((line = reader.readLine()) != null) {
        String[] parts = line.trim().replaceAll("\"", "").split(";");
        
        /*
         * Handelt es sich um File A, so sind an dieser Stelle die ein-
         * zelnen Spalten einer Zeile über Indices ansprechbar. Du kannst
         * hier also festlegen, welche Spalte analysiert werden soll.
         * Weil ich nicht weiß, um welche Spalte es sich handelt, überprüfe
         * ich einfach jede Spalte, die nur aus Integern besteht.
         */
         for (String col : parts) {
           if (col.matches("[0-9]+")) {
             if (!list.containsKey(col))
              list.put(col, 1);
             else
              list.put(col, list.get(col) + 1);
           }
         }
      }
      reader.close();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    return list;
  }
  
  /**
   * Gibt gleiche Integer aus
   */
  private void printEqualities() {
    System.out.println("EQUALITIES:");
    for (String keyB : listB.keySet())
      if (listA.containsKey(keyB))
        System.out.printf("%s: %d\t%s\t%s: %d\t%s\n",
          "List A", listA.get(keyB), keyB,
          "List B", listB.get(keyB), keyB);
  }
  
  /**
   * Gibt Integer aus, die von vorne in mind. 3 Stellen
   * miteinander übereinstimmen
   */
  private void printSimilarities() {
    System.out.println("\nSIMILARITIES:");
    int startCnt = 0;
    int similCnt = 3;
    for (String intA : listA.keySet()) {
      for (String intB : listB.keySet()) {
        if (intA.substring(startCnt, similCnt).equals(intB.substring(startCnt, similCnt)))
          System.out.println(intA + "\t'" + intA.substring(startCnt, similCnt) + "'");
      }
    }
  }

  public static void main(String[] args) {
    new GiveMeAName(args[0], args[1]);
  }
  
  private File A, B;
  private HashMap<String, Integer> listA, listB;
}

Hi,

ich habe versucht das nochmal zu kompilieren, aber es klappt nicht.
Fehler:

Code:
javac GiveMeAName.java
GiveMeAName.java:20: <identifier> expected
  private HashMap<String, Integer> hashFile(File file) {
                 ^
GiveMeAName.java:85: <identifier> expected
  private HashMap<String, Integer> listA, listB;
                 ^
2 errors

Jemand eine Idee woran es liegt?

Gruß
Alex
 
Moin!
Generics (die Dinger mit den <> ) gibt es erst ab 1.5. Ich nehme also mal an, das du eine Java Version < 1.5 nutzt..

*grüssle*
MeinerEiner
 
Hi,

ne eigentlich nicht, ist frisch runtergeladen:

java version "1.6.0_04"
Java(TM) SE Runtime Environment (build 1.6.0_04-b12)
Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode, sharing)

Grüße
Alex
 
Zurück