2013-07-27 2 views
9

я должен сравнить 2 StringList, интересно, если искать первый StringList внутри второй StringList является единственным или рекомендуемая версия выполнить эту проблемуСравните StringList

Мой код будет идти, как это

var 
    aFirstStrList: TStringList ; 
    aSecondStringList: TStringList; 
    MissingElement_firstElement_not_inside_second: TStringList; 
    MissingElement_SecondElement_not_inside_First: TStringList; 

... 

for i := 0 to aFirstStrList.Count - 1 do 
begin 
    if aSecondStringList.IndexOf(aFirstStrList[i] < 0) then 
    begin 
    // react on not found elements 
    .... 
    MissingElement_firstElement_not_inside_second.add(...); 
    end; 
end; 
// and now same code just opposite search direction .... 
.... 
+0

Это зависит от ... пожалуйста, определите «разницу». Просто подумайте о 'a; b' и' a; a'. Какой результат вы хотели бы получить в этом случае? –

ответ

10

Вместо того, чтобы использовать IndexOf, сначала выполните сортировку обоих списков, чтобы избежать поиска по всему списку за каждый цикл. Кроме того, это можно достичь в одном цикле.

Предполагая, что вы хотите, чтобы результаты в двух отдельных строках списков, попробуйте следующее:

procedure CompareStringLists(List1, List2: TStringList; 
    Missing1, Missing2: TStrings); 
var 
    I: Integer; 
    J: Integer; 
begin 
    List1.Sort; 
    List2.Sort; 
    I := 0; 
    J := 0; 
    while (I < List1.Count) and (J < List2.Count) do 
    begin 
    if List1[I] < List2[J] then 
    begin 
     Missing2.Add(List1[I]); 
     Inc(I); 
    end 
    else if List1[I] > List2[J] then 
    begin 
     Missing1.Add(List2[J]); 
     Inc(J); 
    end 
    else 
    begin 
     Inc(I); 
     Inc(J); 
    end; 
    end; 
    for I := I to List1.Count - 1 do 
    Missing2.Add(List1[I]); 
    for J := J to List2.Count - 1 do 
    Missing1.Add(List2[J]); 
end; 

Использование:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    List1: TStringList; 
    List2: TStringList; 
begin 
    List1 := TStringList.Create; 
    List2 := TStringList.Create; 
    try 
    List1.CommaText := 'A, C, F, G, H, K, L, M, N, O, Q, R'; 
    List2.CommaText := 'C, D, E, F, J, P, Q, S, T, U, V, W'; 
    Memo1.Lines.Assign(List1); 
    Memo2.Lines.Assign(List2); 
    CompareStringLists(List1, List2, Memo3.Lines, Memo4.Lines); 
    finally 
    List2.Free; 
    List1.Free; 
    end; 
end; 
0

лучшее исполнение:
Сортировка строк ввода списков
Сравнение с алгоритмом, аналогичным merge sorted lists (там вы найдете то, что отсутствует в каждом списке)

Упрощенные, но медленнее:
Копирование stringlists Привести stringlists
Одна петля для первого списка строк (использование обратной петли для этого for Count-1 downto 0 do)
Поиск ту же строку в второй, если он найден - удалить из обоих списков
Различия останутся в строковых списках

0

Вы должны быть осторожны с этой реализацией CompareStringLists. По умолчанию процедура сортировки TStringList будет сортировать регистр без учета регистра, но используемое сравнение является чувствительным к регистру, а если у вас есть смешанный случай в ваших списках, вы получите размывание предполагаемых промахов.

Либо нужно установить сорта быть случай чувствителен по

List1.CaseSensative := true ; 
List1.Sort ; 
List2.CaseSensative := true ; 
List2.Sort ; 

ИЛИ

Сделать сравнения корпусных insensative

если прописной (List1 [I]) < прописных (List2 [J]) затем

и

else if UpperCase(List1[I]) > UpperCase(List2[J]) then 

соответственно.