mic_checker hat gesagt.:Zu deiner Idee :
Wer sagt denn das die Variante mit den wenigsten Fehlern die richtige ist? In manchen Fällen ist ja vielleicht die mit den meisten Fehlern korrekt, dann mal wieder die mit den wenigsten etc.
Soll heissen: Nicht nur das es zu rechenintensiv ist, es ist auch praktisch nicht brauchbar.
mic_checker hat gesagt.:Würde empfehlen ein paar Regeln aufzustellen nachdenen Fehler berechnet werden, in manchen Fällen muss der User halt in den sauren Apfel beissen und kriegt evtl. mehr Fehler angezeigt als er eigentlich gemacht hat.
http://www.levenshtein.de/levenshtein_search.htmLongest-Common-Subsequence (LCS)
Dieses gilt als eine vereinfachte Variante des Levenshtein-Algorithmuses. Dieser Ansatz findet in der Diskussion um approximative Suchtechnologien Bedeutung, da hier direkt zusammenliegende Buchstaben-Sequenzen die gleiche Bedeutung zugewiesen bekommenen, wie Buschstaben-Sequenzen, die innerhalb des Wortes verteilt sind. In Fällen, in denen ein direktes Verhältnis zwischen der Länge der Suchanfrage und der Länge der Wörterbucheinträge nicht gegeben werden kann, ist es ein geeigneter Algorithmus für approximative Suchanfragen. Aber genauso wie beim Bipartiten Matching, gelang bisher nur der Firma Exorbyte eine performante Implementierung kaum möglich.
public class diffTest {
public static void main(String[] args) {
String str1 = "Fehlt";
String str2 = "Fehlt";
int fehler = 0;
int stelle = 1;
int[][] check = new int[str1.length() + 1][str2.length() + 1];
for (int a = 0; a < str1.length() + 1; a++) {
check[a][0] = 0;
}
for (int a = 0; a < str2.length() + 1; a++) {
check[0][a] = 0;
}
for (int a = 1; a < str1.length() + 1; a++) {
for (int b = a; b < str2.length() + 1; b++) {
if (str1.charAt(a - 1) == str2.charAt(b - 1)) {
for (int c = b; c < str2.length() + 1; c++) {
check[a][c] = b - (stelle - 1);
}
for (int c = a; c < str1.length() + 1; c++) {
check[c][a] = b - (stelle - 1);
}
}
else {
for (int c = b; c < str2.length() + 1; c++) {
check[a][c] = b - stelle;
}
for (int c = a; c < str1.length() + 1; c++) {
check[c][a] = b - stelle;
}
stelle++;
}
b = str2.length() + 1;
}
}
for (int a = str1.length(); a >= 0; a--) {
for (int b = 0; b < str2.length() + 1; b++) {
System.out.print(check[a][b]);
}
System.out.println();
}
}
}
import java.applet.Applet;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;
public class LCSApplet extends Applet
implements ActionListener, Runnable
{
public LCSApplet()
{
pos_i = 1;
pos_j = 1;
backcount = 0;
calc_length_done = false;
status = 1;
}
public void run()
{
setButtons();
while(status == 0)
{
lcs_next();
waitDelay(100);
}
setButtons();
}
public synchronized void stop()
{
if(runner != null && runner.isAlive())
{
status = 1;
notify();
runner = null;
}
setButtons();
}
public void init()
{
y_label = getImage(getDocumentBase(), "label_y.gif");
x_label = getImage(getDocumentBase(), "label_x.gif");
setBackground(Color.lightGray);
Panel panel = new Panel();
Panel panel1 = new Panel();
Panel panel2 = new Panel();
outputPanel = new OutputPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints gridbagconstraints = new GridBagConstraints();
y_input = new String("ABCBDAB");
x_input = new String("BDCABA");
length_output = 0;
lcs_output = new String("");
btnPlay = new Button("Play");
btnStop = new Button("Stop");
btnPrev = new Button("Prev");
btnNext = new Button("Next");
btnReset = new Button("Init / Reset");
yField = new TextField("ABCBDAB", 14);
xField = new TextField("BDCABA", 14);
btnHelp = new Button("Help");
canvas = new LCSCanvas(y_input, x_input, y_label, x_label);
label1 = new Label("String 1:", 2);
label2 = new Label("String 2:", 2);
btnPlay.addActionListener(this);
btnStop.addActionListener(this);
btnPrev.addActionListener(this);
btnNext.addActionListener(this);
btnReset.addActionListener(this);
xField.addActionListener(this);
yField.addActionListener(this);
btnHelp.addActionListener(this);
btnPlay.setFont(new Font("SansSerif", 0, 12));
btnStop.setFont(new Font("SansSerif", 0, 12));
btnPrev.setFont(new Font("SansSerif", 0, 12));
btnNext.setFont(new Font("SansSerif", 0, 12));
btnReset.setFont(new Font("SansSerif", 0, 12));
xField.setFont(new Font("SansSerif", 0, 12));
yField.setFont(new Font("SansSerif", 0, 12));
label1.setFont(new Font("SansSerif", 0, 12));
label2.setFont(new Font("SansSerif", 0, 12));
gridbagconstraints.insets = new Insets(2, 0, 4, 1);
panel.add(btnPlay, gridbagconstraints);
gridbagconstraints.insets = new Insets(2, 0, 4, 1);
panel.add(btnStop, gridbagconstraints);
gridbagconstraints.insets = new Insets(2, 0, 4, 1);
panel.add(btnPrev, gridbagconstraints);
gridbagconstraints.insets = new Insets(2, 0, 4, 1);
panel.add(btnNext, gridbagconstraints);
gridbagconstraints.insets = new Insets(2, 0, 4, 2);
panel.add(btnReset, gridbagconstraints);
gridbagconstraints.insets = new Insets(2, 0, 4, 2);
panel.add(label1, gridbagconstraints);
gridbagconstraints.insets = new Insets(2, 0, 4, 2);
panel.add(yField, gridbagconstraints);
gridbagconstraints.insets = new Insets(2, 0, 4, 2);
panel.add(label2, gridbagconstraints);
panel.add(xField, gridbagconstraints);
panel1.add(btnHelp);
panel2.add(canvas);
BorderLayout borderlayout = new BorderLayout();
setLayout(borderlayout);
add("North", panel);
add("Center", canvas);
add("South", outputPanel);
setButtons();
canvas.setPos(pos_i, pos_j);
outputPanel.SetContent(Integer.toString(canvas.getLength(pos_i, pos_j)), "");
}
public void start()
{
}
public Insets getInsets()
{
return new Insets(3, 3, 3, 3);
}
public void actionPerformed(ActionEvent actionevent)
{
Object obj = actionevent.getSource();
if(obj instanceof TextField)
lcs_reset();
if(actionevent.getActionCommand() == "Play")
{
if(inputHasChanged())
lcs_reset();
lcs_play();
}
if(actionevent.getActionCommand() == "Stop")
lcs_stop();
if(actionevent.getActionCommand() == "Prev")
lcs_prev();
if(actionevent.getActionCommand() == "Next")
{
if(inputHasChanged())
lcs_reset();
lcs_next();
}
if(actionevent.getActionCommand() == "Init / Reset")
lcs_reset();
}
public boolean inputHasChanged()
{
return !x_input.equals(xField.getText()) || !y_input.equals(yField.getText());
}
public synchronized void lcs_play()
{
runner = new Thread(this);
status = 0;
runner.start();
setButtons();
}
public synchronized void lcs_stop()
{
stop();
setButtons();
setButtons();
}
public synchronized void lcs_prev()
{
int i = y_input.length();
int j = x_input.length();
if(calc_length_done)
{
if(backcount == 1)
calc_length_done = false;
backcount--;
canvas.setPos(calc_length_done, backcount);
if(canvas.isDone_LCS())
canvas.isDone_LCS(false);
} else
{
if(pos_j > 1)
pos_j--;
else
if(pos_i > 1)
{
pos_i--;
pos_j = j;
}
canvas.setPos(pos_i, pos_j);
}
canvas.setStatus(status);
canvas.setPos(calc_length_done, backcount);
canvas.repaint();
int k = canvas.getLength(pos_i, pos_j);
outputPanel.SetContent(Integer.toString(k), canvas.getLCS(k, backcount));
setButtons();
}
public synchronized void lcs_next()
{
int i = y_input.length();
int j = x_input.length();
if(pos_j < j)
pos_j++;
else
if(pos_i < i)
{
pos_i++;
pos_j = 1;
} else
{
calc_length_done = true;
}
if(calc_length_done)
{
if(!canvas.isDone_LCS())
backcount++;
canvas.setPos(calc_length_done, backcount);
} else
{
canvas.setPos(pos_i, pos_j);
}
if(canvas.isDone_LCS())
status = 1;
canvas.setStatus(status);
canvas.setPos(calc_length_done, backcount);
canvas.repaint();
int k = canvas.getLength(pos_i, pos_j);
outputPanel.SetContent(Integer.toString(k), canvas.getLCS(k, backcount));
setButtonsPre();
}
public synchronized void lcs_reset()
{
x_input = xField.getText();
y_input = yField.getText();
if(x_input.length() > 14)
{
x_input = x_input.substring(0, 14);
xField.setText(x_input);
}
if(y_input.length() > 14)
{
y_input = y_input.substring(0, 14);
yField.setText(y_input);
}
pos_j = 1;
pos_i = 1;
calc_length_done = false;
backcount = 0;
canvas.isDone_LCS(false);
canvas.setPos(pos_i, pos_j);
canvas.setPos(calc_length_done, backcount);
canvas.LCSReset(y_input, x_input);
outputPanel.SetContent(Integer.toString(canvas.getLength(pos_i, pos_j)), "");
setButtons();
}
public synchronized void setButtons()
{
if(status == 0)
{
btnPlay.setEnabled(false);
btnStop.setEnabled(true);
btnPrev.setEnabled(false);
btnNext.setEnabled(false);
btnReset.setEnabled(false);
} else
if(canvas.isDone_LCS())
{
btnPlay.setEnabled(false);
btnStop.setEnabled(false);
btnPrev.setEnabled(true);
btnNext.setEnabled(false);
btnReset.setEnabled(true);
} else
if(pos_i == 1 && pos_j == 1)
{
btnPlay.setEnabled(true);
btnStop.setEnabled(false);
btnPrev.setEnabled(false);
btnNext.setEnabled(true);
btnReset.setEnabled(true);
} else
{
btnPlay.setEnabled(true);
btnStop.setEnabled(false);
btnPrev.setEnabled(true);
btnNext.setEnabled(true);
btnReset.setEnabled(true);
}
}
public synchronized void setButtonsPre()
{
if(status == 0)
{
btnPlay.setEnabled(false);
btnStop.setEnabled(true);
btnPrev.setEnabled(false);
btnNext.setEnabled(false);
btnReset.setEnabled(false);
} else
if(canvas.isPreDone_LCS())
{
btnPlay.setEnabled(false);
btnStop.setEnabled(false);
btnPrev.setEnabled(true);
btnNext.setEnabled(false);
btnReset.setEnabled(true);
} else
if(pos_i == 1 && pos_j == 1)
{
btnPlay.setEnabled(true);
btnStop.setEnabled(false);
btnPrev.setEnabled(false);
btnNext.setEnabled(true);
btnReset.setEnabled(true);
} else
{
btnPlay.setEnabled(true);
btnStop.setEnabled(false);
btnPrev.setEnabled(true);
btnNext.setEnabled(true);
btnReset.setEnabled(true);
}
}
public synchronized void waitDelay(int i)
{
try
{
wait(i);
}
catch(InterruptedException interruptedexception) { }
}
public static final int UP = 1;
public static final int LEFT = 2;
public static final int DIAGONAL = 3;
public static final String Y_DEFAULT = "ABCBDAB";
public static final String X_DEFAULT = "BDCABA";
public static final int MAX_INPUT_SIZE = 14;
public static final int STEP_SPEED = 100;
public volatile int pos_i;
public volatile int pos_j;
public volatile int backcount;
public volatile boolean calc_length_done;
private static final int GO = 0;
private static final int TERMINATE = 1;
private volatile int status;
Thread runner;
String y_input;
String x_input;
int length_output;
String lcs_output;
TextField yField;
TextField xField;
Button btnPlay;
Button btnStop;
Button btnPrev;
Button btnNext;
Button btnReset;
Button btnHelp;
Label label1;
Label label2;
LCSCanvas canvas;
OutputPanel outputPanel;
Image y_label;
Image x_label;
}
public class diffTest {
public static void main(String[] args) {
String str1 = "Fehler";
String str2 = "Fehler";
int fehler = 0;
int[][] check = new int[str1.length()][str2.length()];
for (int a = 0; a < str1.length(); a++) {
for (int b = 0; b < str2.length(); b++) {
if (str1.charAt(a) == str2.charAt(b)) {
check[a][b] = 1;
}
}
}
for (int a = str1.length() - 1; a >= 0; a--) {
for (int b = 0; b < str2.length(); b++) {
System.out.print(check[a][b]);
}
System.out.println();
}
}
}
mic_checker hat gesagt.:Hab mir jetzt den Algo nicht mehr genau angeschaut, aber warum kontrollierst du dann nicht einfach die Werte in der Hauptdiagonalen (also ob 1) und zählst Unterschiede (wenn das reicht).
mic_checker hat gesagt.:Im andern Fall : Die Anzahl der Spalten und Zeilen ist ja schon unterschiedlich....was gibt er denn aus wenn du nicht "Fler" eingibst sondern "Fder" oder sonst was, was nicht genau übereinstimmt (bis auf Länge)?
Hobbit_Im_Blutrausch hat gesagt.:Wie stellst du dir dass vor?
for (int a = str1.length() - 1, b = str2.length() - 1; a >= 0 && b >= 0;) {
if (check[a][b] == 1) {
a--;
b--;
}
else {
if (a != str1.length() - 1 && check[a + 1][b] == 1) {
fehler++;
a++;
}
}
}
mic_checker hat gesagt.:Ursprung:
Fder
0001
0010
0000
0000
0010
1000
Nachher:
0001
0010
0000
0000
-> Du hast zwei Zeilen gelöscht (Fehler = 2), es fehlen zwei Einsen in der neuen Hauptdiagonalen (Fehler + 2), somit hast du 4 Fehler, was ja stimmen müsste.
arg, wer zählen kann ist klar im vorteilHobbit_Im_Blutrausch hat gesagt.:Aber hier wurden keine 4 Fehler gemacht :bae:
public static void lcs() {
String orig = "Fehler";
String in = "Fder";
int[][] l = new int[orig.length()+1][in.length()+1];
int laenge = 0;
for(int i = 0,c = orig.length()-1;i < orig.length() && c >= 0;i++,c--) {
for(int j = 0,k = 1;j < in.length() && k <= in.length();j++,k++) {
if(orig.charAt(i) == in.charAt(j)) {
l[c][k] = l[c+1][k-1] + 1;
} else {
if(l[c+1][k] > l[c][k-1])
l[c][k] = l[c+1][k];
else
l[c][k] = l[c][k-1];
}
laenge = l[c][k];
}
}
System.out.println("Aktuelle Länge = "+laenge);
for (int a = 0; a < l.length; a++) {
for (int b = 0; b < l[0].length; b++) {
System.out.print(l[a][b]);
}
System.out.println();
}
}
mic_checker hat gesagt.:Es gilt also den längeren Text zu ermitteln und danach das Ergebnis der Methode lcs() davon abzuziehen.
Falls jemand ein Beispiel findet bei dem es nicht funktioniert bitte Original String und eingegebenen String posten.
String orig = "aaabbbb";
String in = "bbbaaa";
:lol:mic_checker hat gesagt.:Ach du mit deinen utopischen Beispielen
Womöglich schon, mich interessiert eher das algemeinere Problem von minimal möglich Transformationen, und ob'smic_checker hat gesagt.:Ich weiss jetzt nicht genau ob der Levenshtein Fälle wie oben erkennen würde, afaik ist der LCS ja "nur" eine vereinfachte Version des Levenshtein.
Ich denke er ist mehr als ausreichend! Klar entwickelt man für DAU's, aber mal eben 20 Buchstaben vergessen und dann 4 vertauschen geht IMHO über einen DAU hinaus und würde mich nicht weiter interessieren.mic_checker hat gesagt.:Denke also das dieser Ansatz vorerst als "eingeschränkte Version" akzeptabel ist.....
Wildcard hat gesagt.:Womöglich schon, mich interessiert eher das algemeinere Problem von minimal möglich Transformationen, und ob's
da einen Algo gibt der nachweislich exakt ist.
Idealfall ist eh: Der Benutzer macht keine Fehler, kriegt nur bestätigt : 0 Fehler und gut isWildcard hat gesagt.:Ich denke er ist mehr als ausreichend! Klar entwickelt man für DAU's, aber mal eben 20 Buchstaben vergessen und dann 4 vertauschen geht IMHO über einen DAU hinaus und würde mich nicht weiter interessieren.
Wenn das tatsächlich real vorkommt ist der entsprechende DAU vermutlich auch ausserstande das Ergebnis zu überprüfen :wink:
if (str1.length() == str2.length()) {
for (int a = str1.length() - 1; a >= 0; a--) {
if (check[a][a] != 1) {
fehler++;
}
}
}
import java.io.*;
public class diffTest {
void diff(String str1, String str2) {
str1 = " " + str1 + " ";
str2 = " " + str2 + " ";
int fehler = 0;
int[][] check = new int[str1.length()][str2.length()];
for (int a = 0; a < str1.length(); a++) {
for (int b = 0; b < str2.length(); b++) {
if (str1.charAt(a) == str2.charAt(b)) {
check[a][b] = 1;
}
}
}
if (str1.length() == str2.length()) {
for (int a = str1.length() - 1; a >= 0; a--) {
if (check[a][a] != 1) {
fehler++;
}
}
}
else {
if (str1.length() < str2.length()) {
fehler = str2.length() - str1.length();
}
for (int a = str1.length() - 1, b = str2.length() - 1; a >= 0 && b >= 0;) {
if (check[a][b] == 1) {
a--;
b--;
}
else {
for (int c = 0; c <= a; c++) {
fehler++;
for (int d = 0; d <= b; d++) {
if (check[a - c][b - d] == 1) {
a = a - c;
b = b - d;
d = b + 1;
c = a + 1;
fehler--;
}
}
}
}
}
}
System.out.println("Fehler: " + fehler);
}
public static void main(String[] args) {
String str1 = null;
String str2 = null;
diffTest test = new diffTest();
while(true) {
try {
str1 = new BufferedReader(new InputStreamReader(System.in)).readLine();
str2 = new BufferedReader(new InputStreamReader(System.in)).readLine();
}
catch (Exception e) {
System.out.println(e.toString());
}
test.diff(str1, str2);
}
}
}
Original Eingabe Fehler Berechnet Bemerkung
Fehler Fehla 2 4 Wenn ich als Original Fehla nehme und als Eingabe Fehler stimmts
Microsoft Microshrot 3 2
Kruzifix Kreuzfix 2 3
Hirsch Hier 4 3
http://www.doublefind.de/technology.htmlDie Damerau-Levenshtein-Metrik gibt nichts Anderes als die Zahl der Unterschiede von 2 Wörtern an. Sie ist also ein Maß für die Ähnlichkeit zweier Wörter.
public static int levenshtein() {
/* Schritt 1 */
String s = "HIRSCH";
String t = "HIER";
int n = s.length();
int m = t.length();
int cost,minimum;
char chs,cht;
if(n == 0 || m == 0)
return 0;
int hoehe = n + 1;
int breite = m + 1;
int[][] matrix = new int[hoehe][breite];
/* Schritt 2 */
for(int i = 0;i < hoehe;i++)
matrix[i][0] = i;
for(int j = 0;j < breite;j++)
matrix[0][j] = j;
/* Schritte 3 - 6 */
for(int i = 1;i < hoehe;i++) {
chs = s.charAt(i-1);
for(int j = 1;j < breite;j++) {
cht = t.charAt(j-1);
if(chs == cht)
cost = 0;
else
cost = 1;
/* Berechnung des Minimums */
minimum = matrix[i-1][j]+1;
if((matrix[i][j-1]+1) < minimum)
minimum = matrix[i][j-1]+1;
if((matrix[i-1][j-1] + cost) < minimum)
minimum = matrix[i-1][j-1] + cost;
matrix[i][j] = minimum;
}
}
/*
* Ausgabe der Matrix
*/
for (int a = 0; a < matrix.length; a++) {
for (int b = 0; b < matrix[0].length; b++) {
System.out.print(matrix[a][b]);
}
System.out.println();
}
return matrix[n][m];
}