Christoph Zurnieden: Unterschiede zwei Strings in HTML darstellen

Beitrag lesen

Hi,

Mir ist vollkommen klar, daß es einen vollkommenen Automatismus nicht geben kann. Es reicht mir, wenn ich eine automatische Hilfe habe -allein schon das Rausfinden, was sich geändert hat gegenüber dem Vorgängertext ist schon eine große Erleichterung.

Ja. Mehr kannst Du auch gar nicht tun. (Zumindest in absehbarer Zeit nicht).
Aber weil der Nutzen eines Triggers "Obacht: es hat sich sprunghaft sehr viel in Artikel XZ geändert!" über etwas Bequemlichkeit kaum hinausgeht (falls Du nicht gerade einige tausend oder mehr Artikel zu verwalten hast, dann ist sowas natürlich unabdingbar) darf es auch nicht viel kosten. Damit fallen alle komplexen Algorithmen hinten raus, es muß etwas einfaches sein.

Leider bin ich da noch nicht wesentlich weiter gekommen. Und wahrscheinlich werde ich erst morgen eine Routine haben, die zwei Texte miteinander vergleichen kann, das ganze wird eine HTML-Seite sein mit eingebauten JS.

Mit Javascript? Na, da hätte ich doch 'was für Dich.

Bis auf die beiden ersten Funktionen ist alles sehr komplex und damit recht lahm. Das ist aber nur natürlich und läßt sich nach aktuellem Stand der Forschung auch nicht verbessern.

Die oben erwähnten unscharfen Prüfsummen (nur Latin-1, reicht aber normalerweise):

function whitesum(_Value){
  var val    = _Value;
  var sumstr = "";
  var regex  = /[ \t\v\r\n]/; // fehlt  

for(var i=0;i<val.length;i++){
    if(regex.test(val[i])){
      sumstr += val[i];
    }
  }
  return sumstr;
}

function punctsum(_Value){
  var val = _Value;
  var sumstr = "";
  var regex  = /[.,;!?¡¿]/; // fehlt so einiges

for(var i=0;i<val.length;i++){
    if(regex.test(val[i])){
      sumstr += val[i];
    }
  }
  return sumstr;
}

Und einmal eine Edit-Distanz (Damerau-Levenshtein):
Basierend auf dem C-code von Lorenzo Seidenari, Portierung nach Javascript ist von mir.

function Minimum(a, b, c) {
  var minimum = a;
  if(b < minimum)
    minimum = b;
  if(c < minimum)
    minimum = c;
  return minimum;
}
function levenshtein(s, t) {
  var n = s.length
  var m = t.length;
  var i,j,cost;
  var d = new Array();

if((n+m) == 0) return -1;
  // Step 1
  if( (n*m) == 0){
    return ((n == 0)?n:m);
  }
  for(i=0; i <= n; i++){
    d[i] = new Array();
  }
  // Step 2
  for(i = 0; i <= n; i++) {
    d[i][0] = i;
  }
  for(j = 0; j <= m; j++) {
    d[0][j] = j;
  }
  // Step 3
  for(i = 1; i <= n; i++) {
    // Step 4
    for(j = 1; j <= m; j++) {
      cost = ((s.charAt(i - 1) ==  (t.charAt(j - 1)))?0:1);
      // Step 6
      d[i][j] = Minimum (d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);
    }
  }

// Step 7
  return d[n][m];
}

Gibt's auch in Gewichtet, falls das benötigt wird. Die gewichtete Version ist auch nicht nur ganz von mir (Die Implementation natürlich nur, nicht die Idee ;-) sondern auch noch auf die übliche Methode Speicheroptimiert.

Die folgende Implementation des Ratcliff/Obershelp Algorithmus ist eine 1:1 Übersetzung aus C. Er ist deswegen höchstwahrscheinlich noch schneckenartiger in der Ausführung als die Komplexität eh schon beschreibt!

/*
  Ratcliff/Obershelp Pattern Recognition
  Algorithm as described in the July 1988 issue
  of Dr. Dobbs Journal.

Translation of the C-code of Steve Grubb <linux_4ever@yahoo.com>
  (The original program ist from 1999, thus the email address might
   be not the one you are looking for) by me czurnieden@gmx.de

The original C-code is GPL, so is this.

This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published  by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA

*/
function memcmp(s,slen,t,tlen,size){

if(s.substring(slen,(slen + size)) < t.substring(tlen,(tlen + size))){
     return -1;
   }
   if(s.substring(slen,(slen + size)) > t.substring(tlen,(tlen + size))){
     return 1;
   }
   else{
     return 0;
   }
}
// some global variables

var tcnt = 0.0;

function longest_substring(s,slen,t,tlen,SubString){
  var i,j,size=1;

SubString["o2"] = -1;
  for(i=0;i<=(slen-size);i++){
    for(j=0; j<=(tlen-size); j++){
      var test_size = size;
      while(1){
        if((test_size<=(slen-i))&&(test_size<=(tlen-j))){
   if(memcmp(s,i,t,j, test_size) == 0){
     if((test_size > size) || (SubString["o2"] < 0)){
       SubString["o1"] = i;
       SubString["o2"] = j;
       size = test_size;
     }
     test_size++;
   }
   else
     break;
}
else
   break;
      }
    }
  }
  if(SubString["o2"] < 0){
    SubString["len"] = 0;
  }
  else{
    SubString["len"] = size;
  }
}

function rsimil(s,slen,t,tlen){

if(slen == 0 || tlen == 0){
    return;
  }

var SubString = new Object();
  SubString["o1"]  = 0;
  SubString["o2"]  = 0;
  SubString["len"] = 0;

longest_substring(s,slen,t,tlen, SubString);

if(SubString["len"] != 0){
    var delta1, delta2;
    tcnt += SubString["len"] << 1;

rsimil(s,SubString["o1"],t,SubString["o2"]);

delta1 = SubString["o1"] + SubString["len"] ;
    delta2 = SubString["o2"] + SubString["len"] ;

if((delta1<slen)&&(delta2<tlen)){
      rsimil(s.substring(delta1, s.length), slen - delta1,
             t.substring(delta2, t.length), tlen - delta2);
    }
  }
}

function simil(s,t){
  var tlen = 0.0;
  var slen = s.length;
  var tlen = t.length;

if((!s || slen <= 0) || (!t || tlen <= 0)){
    return 0.0
  }

tcnt = 0.0;
  tlen = slen + tlen;

rsimil(s,slen,t,tlen);

return (tcnt/tlen);

}

Würde dich die Seite interessieren ? Ich könnte sie hier als Textfile einstellen.

Höchstens als Link bitte, danke.

so short

Christoph Zurnieden