2010-02-12 17 views
6

Potrzebuję znaleźć kilka słów lub pasujący wzór za pomocą kodu Javascript.Łańcuchy tekstowe pasujące do wzorca pomocy

jest to wymagane.

mam ciąg jak ten,

Oto krótki przewodnik dla następnego czasie można dotrzeć do swojego ulubionego oliwek i niektórych innych tematów

i trzeba dopasować ten ciąg na ciąg taki jak ten

favorite oil and some other topics can be based on something blah blah 

Jak uzyskać przecięcie pasujących bloków tekstu?

Próbowałem już przecinać funkcję skryptu JavaScript, dla niektórych ciągów nie działa poprawnie.

Jak rozwiązać ten problem? czy można to zrobić za pomocą Regex?

Proszę o poradę.

Odpowiedz

8

Musisz znaleźć Longest common substring.

Jeśli struny nie są bardzo długie, zalecam stosowanie podejścia Tima. W przeciwnym razie jest to implementacja JavaScript najdłuższego wspólnego algorytmu podciągu z dynamicznym programowaniem. Runtime to O (mn), gdzie m i n są odpowiednio długościami dwóch ciągów.

Przykład użycia:

var first = "Here is a quick guide for the next time you reach for your favorite oil and some other topics"; 
var second = "favorite oil and some other topics can be based on something blah blah"; 

console.log(first.intersection(second)); // ["favorite oil and some other topic"] 

Jest to implementacja algorytmu. Zwraca tablicę najdłuższego wspólnego (-ych) podciągu (-ów). Rozszerzono natywną klasę String, dzięki czemu metoda przecięcia jest dostępna we wszystkich ciągach.

String.prototype.intersection = function(anotherString) { 
    var grid = createGrid(this.length, anotherString.length); 
    var longestSoFar = 0; 
    var matches = []; 

    for(var i = 0; i < this.length; i++) { 
     for(var j = 0; j < anotherString.length; j++) { 
      if(this.charAt(i) == anotherString.charAt(j)) { 
       if(i == 0 || j == 0) { 
        grid[i][j] = 1; 
       } 
       else { 
        grid[i][j] = grid[i-1][j-1] + 1; 
       } 
       if(grid[i][j] > longestSoFar) { 
        longestSoFar = grid[i][j]; 
        matches = []; 
       } 
       if(grid[i][j] == longestSoFar) { 
        var match = this.substring(i - longestSoFar + 1, i); 
        matches.push(match); 
       } 
      } 
     } 
    } 
    return matches; 
} 

Należy również tę funkcję pomocnika stworzyć 2d tablicę ze wszystkimi elementami zainicjować 0.

// create a 2d array 
function createGrid(rows, columns) { 
    var grid = new Array(rows); 
    for(var i = 0; i < rows; i++) { 
     grid[i] = new Array(columns); 
     for(var j = 0; j < columns; j++) { 
      grid[i][j] = 0; 
     } 
    } 
    return grid; 
} 
+0

Dobra odpowiedź. Sam rozważałem wdrożenie tego, ale miałem pracę do wykonania. –

+0

Anurag, wielkie dzięki. działa pięknie! – kakopappa

+0

@Aruna - cieszę się, że zadziałało. @Tim - jest szybki, ale brakuje mu prostoty.istnieje inny algorytm, który używa drzewek przyrostków i zajmuje O (n + m), ale nie dzisiaj :) – Anurag

3

To nie jest bardzo wydajne i są znacznie lepsze sposoby, aby to zrobić w ogóle (patrz @ odpowiedź Anuraga za), ale to proste i działa dobrze na krótkich ciągów:

function stringIntersection(str1, str2) { 
    var strTemp; 

    // Swap parameters if necessary to ensure str1 is the shorter 
    if (str1.length > str2.length) { 
     strTemp = str1; 
     str1 = str2; 
     str2 = strTemp; 
    } 

    // Start with the whole of str1 and try shorter substrings until 
    // we have a common one 
    var str1Len = str1.length, l = str1Len, start, substring; 
    while (l > 0) { 
     start = str1Len - l; 
     while (start >= 0) { 
      substring = str1.slice(start, l); 
      if (str2.indexOf(substring) > -1) { 
       return substring; 
      } 
      start--; 
     } 
     l--; 
    } 
    return ""; 
} 

var s1 = "Here is a quick guide for the next time you reach" 
     + " for your favorite oil and some other topics"; 
var s2 = "favorite oil and some other topics can be based on" 
     + " something blah blah"; 

alert(stringIntersection(s1, s2)); 
+0

Cześć Tim. dziękuję za wysiłek i czas! .. docenione – kakopappa

0

prosty PolyFill filtra string

if (!String.prototype.intersection) { 
    String.prototype.intersection = function(anotherString, caseInsensitive = false) { 
    const value = (caseInsensitive) ? this.toLowerCase()   : this; 
    const comp = (caseInsensitive) ? anotherString.toLowerCase() : anotherString; 
    const ruleArray = comp.split("").reduce((m,v) => {m[v]=true; return m;} ,{}) 
    return this.split("").filter((c, i) => ruleArray[value[i]]).join("") 
    } 
} 

"HelloWorld" .intersection ("HEWOLRLLODo" prawda)

"HelloWorld" - to przypadku odporne

"HelloWorld" .intersection ("HEWOLRLLODo")

"howo" - obudowa wrażliwy

Powiązane problemy