Вот скрипт удаляет дубликаты строк. Но проблема что он их сортирует! Как отключить? если удаляю строчку buffer.Sorted := True; то скрипт перестает работать(( PHP: procedure RemoveDuplicates(const stringList : TStringList) ; var buffer: TStringList; cnt: Integer; begin buffer := TStringList.Create; try buffer.Sorted := True; buffer.Duplicates := dupIgnore; buffer.BeginUpdate; for cnt := 0 to stringList.Count - 1 do buffer.Add(stringList[cnt]) ; buffer.EndUpdate; stringList.Assign(buffer) ; finally FreeandNil(buffer) ; end; end; всем спасибо
Это особенность работы TStringList, dupIgnore работает только вместе с Sorted = True Так что пишите свою реализацию удаления дублей.
пишите одну функцию которая строит дерево и все быстро и эффективно в месте добавления узла сохраняете указатель на него в массиве чтоб потом вывести в истинном порядке а не в отсортированном ну и все в принципе
набросал пишет без дублей без сортировки и очень быстро фактически может миллионы перемалывать достаточно быстро p.s после функций выделения памяти на ошибку не проверял (лень) а так все цивильно Code: #include <conio.h> #include <stdio.h> #include <stdlib.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <time.h> #include <assert.h> #include <headutil.h> static char ** vector; static size_t all_elements; typedef struct _node node; struct _node { char *str; node *right, *left; }; node * add_string(node **root, const char *str) { node *new; if (!*root) { vector = realloc(vector, sizeof(char*) * (all_elements+1)); new = malloc(sizeof(node)); new->str = vector[all_elements++] = strdup(str); new->left = new->right = NULL; return *root = new; } if (strcmp((*root)->str, str) < 0) return add_string(&(*root)->left, str); else if (strcmp((*root)->str, str) > 0) return add_string(&(*root)->right, str); return NULL; } void show_or_save_to_file(void) { size_t i; for (i = 0; i < all_elements; i++) puts(vector[i]); all_elements = 0; } void free_tree(node *root) { if (root->left) free_tree(root->left); if (root->right) free_tree(root->right); free(root->str); free(root); } void free_tree_and_vector(node **root) { node *dup_root = *root; free_tree(dup_root); free(vector); *root = NULL; vector = NULL; } int main(void) { node *tree = NULL; add_string(&tree, "zombie"); add_string(&tree, "paradox"); add_string(&tree, "paranoia"); add_string(&tree, "paranoia"); show_or_save_to_file(); free_tree_and_vector(&tree); return 0; }
можно к дельфи прилинковать .obj на другом языке ? если да то скомпиль и слинкуй 2all кстати интересно возможно ли правда это ? например сишный .obj слинковать с дельфей ?
Code: procedure KillDuplicates(Source: TStringList); var I, J: Integer; begin for I := Source.Count-1 downto 1 do if I<Source.Count then begin for J := I-1 downto 0 do if Source.Strings[I]=Source.Strings[J] then Source.Delete(J); end; end; Держи. Код тормозной и не оптимальный, но если ты сам для себя стараться не хочешь, то я для тебя стараться тем более не буду.
Redeemer, я хочу стараться. но забыл многое в делфи. код нужен что бы обрабатывал базы в миллион строк
PHP: procedure RemoveDuplicates(const stringList : TStrings) ; var buffer: TStringList; cnt, cnt2: Integer; begin buffer := TStringList.Create; try buffer.Sorted := True; buffer.Duplicates := dupIgnore; buffer.BeginUpdate; cnt2 := 0; for cnt := 0 to stringList.Count - 1 do if buffer.IndexOf(stringList[cnt]) < 0 then begin buffer.AddObject(stringList[cnt], TObject(cnt2)); Inc(cnt2); end; buffer.EndUpdate; stringList.Assign(buffer); for cnt := 0 to buffer.Count - 1 do stringList[Integer(buffer.Objects[cnt])] := buffer[cnt]; finally FreeandNil(buffer) ; end; end; Временная сложность O(n). У решения выше - O(n в квадрате)
Ошибаетесь. Ваш код будет работать дольше потому что: 1. IndexOf ищет простым перебором 2. При использовании сортировки, лист сделает еще один поиск при добавлении Таким образом, вычислительная сложность моего кода: O=SUM{0, n}(n*(n-1)), а вашего: O=SUM{0, n}(n*2(n-1))+n, где SUM{x, y}(z) - сумма функций z в интервале x..y Add: К тому же, чем ближе к концу массива, тем ваш алгоритм будет работать медленнее, за счет того что надо просмотреть большее число строк. А мой быстрее - потому что число строк только уменьшается.
PHP: function TStringList.IndexOf(const S: string): Integer; begin if not Sorted then Result := inherited IndexOf(S) else if not Find(S, Result) then Result := -1; end; function TStringList.Find(const S: string; var Index: Integer): Boolean; var L, H, I, C: Integer; begin Result := False; L := 0; H := FCount - 1; while L <= H do begin I := (L + H) shr 1; C := CompareStrings(FList^[I].FString, S); if C < 0 then L := I + 1 else begin H := I - 1; if C = 0 then begin Result := True; if Duplicates <> dupAccept then L := I; end; end; end; Index := L; end; Этим я думаю вопрос исчерпан