Отключить сортировку в этом скрипте

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by ttt0z, 1 Sep 2010.

  1. ttt0z

    ttt0z Member

    Joined:
    18 Nov 2007
    Messages:
    60
    Likes Received:
    10
    Reputations:
    -5
    Вот скрипт удаляет дубликаты строк.
    Но проблема что он их сортирует!
    Как отключить?
    если удаляю строчку buffer.Sorted := True; то скрипт перестает работать((

    PHP:
    procedure RemoveDuplicates(const stringList TStringList) ;
    var
      
    bufferTStringList;
      
    cntInteger;
    begin
      buffer 
    := TStringList.Create;
      try
        
    buffer.Sorted := True;
        
    buffer.Duplicates := dupIgnore;
        
    buffer.BeginUpdate;
        for 
    cnt := 0 to stringList.Count do
          
    buffer.Add(stringList[cnt]) ;
        
    buffer.EndUpdate;
        
    stringList.Assign(buffer) ;
      finally
        
    FreeandNil(buffer) ;
      
    end;
    end;
    всем спасибо
     
  2. roxblnfk

    roxblnfk Elder - Старейшина

    Joined:
    6 Feb 2010
    Messages:
    189
    Likes Received:
    42
    Reputations:
    19
    что то мне подсказывает, что нужно в строке
    buffer.Sorted := True;
    поставить False...
     
  3. ttt0z

    ttt0z Member

    Joined:
    18 Nov 2007
    Messages:
    60
    Likes Received:
    10
    Reputations:
    -5
    пробовал , после этого скрипт перестает работать
     
  4. b3

    b3 Moderator

    Joined:
    5 Dec 2004
    Messages:
    2,041
    Likes Received:
    933
    Reputations:
    199
    удалить эту строку
     
    _________________________
  5. ttt0z

    ttt0z Member

    Joined:
    18 Nov 2007
    Messages:
    60
    Likes Received:
    10
    Reputations:
    -5
    мда.
    это пробовал. скрипт перестает работать.

    кто нибудь реально знает в чем дело?
     
  6. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Это особенность работы TStringList, dupIgnore работает только вместе с Sorted = True
    Так что пишите свою реализацию удаления дублей.
     
  7. ttt0z

    ttt0z Member

    Joined:
    18 Nov 2007
    Messages:
    60
    Likes Received:
    10
    Reputations:
    -5
    Redeemer, я так и думал(

    кто нибудь может набросать аналог?
     
  8. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    пишите одну функцию которая строит дерево и все
    быстро и эффективно в месте добавления узла сохраняете указатель на него в массиве чтоб потом вывести в истинном порядке а не в отсортированном ну и все в принципе
     
  9. ttt0z

    ttt0z Member

    Joined:
    18 Nov 2007
    Messages:
    60
    Likes Received:
    10
    Reputations:
    -5
    greki_hoy, если все так просто напиши код?
     
  10. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    набросал пишет без дублей без сортировки и очень быстро фактически может миллионы перемалывать достаточно быстро
    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;
    }
    
    
     
  11. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    можно к дельфи прилинковать .obj на другом языке ? если да то скомпиль и слинкуй

    2all кстати интересно возможно ли правда это ?
    например сишный .obj слинковать с дельфей ?
     
  12. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Можно.
    Такой метод даже в VCL используется
     
  13. ttt0z

    ttt0z Member

    Joined:
    18 Nov 2007
    Messages:
    60
    Likes Received:
    10
    Reputations:
    -5
    надо обычный нормальный код на делфи! кто знает??
     
  14. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    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;
    Держи. Код тормозной и не оптимальный, но если ты сам для себя стараться не хочешь, то я для тебя стараться тем более не буду.
     
  15. ttt0z

    ttt0z Member

    Joined:
    18 Nov 2007
    Messages:
    60
    Likes Received:
    10
    Reputations:
    -5
    Redeemer, я хочу стараться. но забыл многое в делфи.
    код нужен что бы обрабатывал базы в миллион строк
     
  16. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Тогда возьми код greki_hoy и перепиши на дельфи
     
  17. ttt0z

    ttt0z Member

    Joined:
    18 Nov 2007
    Messages:
    60
    Likes Received:
    10
    Reputations:
    -5
    Redeemer, можешь помочь в этом? в с++ не силен
     
  18. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    PHP:
    procedure RemoveDuplicates(const stringList TStrings) ;
    var
      
    bufferTStringList;
      
    cntcnt2Integer;
    begin
      buffer 
    := TStringList.Create;
      try
        
    buffer.Sorted := True;
        
    buffer.Duplicates := dupIgnore;
        
    buffer.BeginUpdate;
        
    cnt2 := 0;
        for 
    cnt := 0 to stringList.Count 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 do
          
    stringList[Integer(buffer.Objects[cnt])] := buffer[cnt];
      finally
        
    FreeandNil(buffer) ;
      
    end;
    end;
    Временная сложность O(n).
    У решения выше - O(n в квадрате)
     
  19. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Ошибаетесь. Ваш код будет работать дольше потому что:
    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: К тому же, чем ближе к концу массива, тем ваш алгоритм будет работать медленнее, за счет того что надо просмотреть большее число строк. А мой быстрее - потому что число строк только уменьшается.
     
    #19 Redeemer, 2 Sep 2010
    Last edited: 2 Sep 2010
  20. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    PHP:
    function TStringList.IndexOf(const Sstring): Integer;
    begin
      
    if not Sorted then Result := inherited IndexOf(S) else
        if 
    not Find(SResultthen Result := -1;
    end;
    function 
    TStringList.Find(const Sstring; var IndexInteger): Boolean;
    var
      
    LHICInteger;
    begin
      Result 
    := False;
      
    := 0;
      
    := FCount 1;
      while 
    <= do
      
    begin
        I 
    := (Hshr 1;
        
    := CompareStrings(FList^[I].FStringS);
        if 
    0 then L := else
        
    begin
          H 
    := 1;
          if 
    0 then
          begin
            Result 
    := True;
            if 
    Duplicates <> dupAccept then L := I;
          
    end;
        
    end;
      
    end;
      
    Index := L;
    end;
    Этим я думаю вопрос исчерпан