有几万个IP在一个文本文件中,我想提出里面出现2次的,还有出现3次,还有仅仅出现一次的IP,分别存储.IP是一行一个.

解决方案 »

  1.   

    出现4次,5,6,7...N次的呢??如何处理提出来后存在那里?存在文本?分别存储,是一个IP存一个文本吗?那不是要几万个了?
      

  2.   

    用stringlist载入,然后排序。再循环一下就行了。
      

  3.   

    数据少,用TLIST这样的单性列表和哈希比,哈希的效率体现不出来
    几万用哈希存储比较合适,查找也方便,以后加数据也不错
      

  4.   

    yshuui 能说的具体点吗?我才学delphi不久.
      

  5.   

    有几万个IP在一个文本文件中,是每行一个吗?
    看一下stringlist类的方法,就知道了。
      

  6.   


    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      PPHashItem = ^PHashItem;
      PHashItem = ^THashItem;
      THashItem = record
        Next: PHashItem;
        Key: string;
        Value: Integer;
      end;  TStringHashEx = class
      private
        Buckets: array of PHashItem;
      protected
        function Find(const Key: string): PPHashItem;
      public
        function HashOf(const Key: string): Cardinal; virtual;
        constructor Create(Size: Cardinal = 256);
        destructor Destroy; override;
        procedure Add(const Key: string; Value: Integer);
        procedure Clear;
        procedure Remove(const Key: string);
        function Modify(const Key: string; Value: Integer): Boolean;
        function ValueOf(const Key: string): Integer;
        function GetIpNum(const ACount: Integer): Integer;
      end;  TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Memo2: TMemo;
        Memo3: TMemo;
        Memo4: TMemo;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      Test: TStringHashEx;
      Ip: string;
      I, J: Integer;
    begin
      Test := TStringHashEx.Create(200000); //首先创建一个足够大的
      for I := 0 to 20 do
      begin
        Ip := IntToStr(Random(9)) + IntToStr(Random(9)) ;
        Test.Add(Ip, I);  // 这里加入IP,另外保证VALUE没有重复
        Memo1.Lines.Add(Ip);
      end;  for I := 2 to 6 do
      begin
        Memo1.Lines.Add(Format('出现重复%d 的有 %d 个', [I, Test.GetIpNum(I)]));
      end;
    end;{ TStringHashEx }procedure TStringHashEx.Add(const Key: string; Value: Integer);
    var
      Hash: Integer;
      Bucket: PHashItem;
    begin
      Hash := HashOf(Key) mod Cardinal(Length(Buckets));
      New(Bucket);
      Bucket^.Key := Key;
      Bucket^.Value := Value;
      Bucket^.Next := Buckets[Hash];
      Buckets[Hash] := Bucket;
    end;procedure TStringHashEx.Clear;
    var
      I: Integer;
      P, N: PHashItem;
    begin
      for I := 0 to Length(Buckets) - 1 do
      begin
        P := Buckets[I];
        while P <> nil do
        begin
          N := P^.Next;
          Dispose(P);
          P := N;
        end;
        Buckets[I] := nil;
      end;
    end;constructor TStringHashEx.Create(Size: Cardinal);
    begin
      inherited Create;
      SetLength(Buckets, Size);
    end;destructor TStringHashEx.Destroy;
    begin
      Clear;
      inherited Destroy;
    end;function TStringHashEx.Find(const Key: string): PPHashItem;
    var
      Hash: Integer;
    begin
      Hash := HashOf(Key) mod Cardinal(Length(Buckets));
      Result := @Buckets[Hash];
      while Result^ <> nil do
      begin
        if Result^.Key = Key then
          Exit
        else
          Result := @Result^.Next;
      end;
    end;function TStringHashEx.GetIpNum(const ACount: Integer): Integer;
    var
      I, Sum: Integer;
      P, N: PHashItem;
      TempKey: string;
    begin
      Result := 0;
      Sum := 0;
      for I := 0 to Length(Buckets) - 1 do
      begin
        Sum := 0;
        TempKey := '';    P := Buckets[I];
        if Assigned(P) then
           TempKey := p^.Key;  // 记录首个KEY值    while P <> nil do
        begin
          if (CompareStr(p^.Key, TempKey) = 0) then // 在这里做了个KEY判断,VCL自带HASHOF好象有点问题
            Inc(Sum);
          P := P^.Next;
          if Sum >= ACount then
          begin
            Inc(Result);
            Break;
          end;
        end;
      end;end;function TStringHashEx.HashOf(const Key: string): Cardinal;
    var
      I: Integer;
    begin
      Result := 0;
      for I := 1 to Length(Key) do
        Result := ((Result shl 2) or (Result shr (SizeOf(Result) * 8 - 2))) xor
          Ord(Key[I]);
    end;function TStringHashEx.Modify(const Key: string; Value: Integer): Boolean;
    var
      P: PHashItem;
    begin
      P := Find(Key)^;
      if P <> nil then
      begin
        Result := True;
        P^.Value := Value;
      end
      else
        Result := False;
    end;procedure TStringHashEx.Remove(const Key: string);
    var
      P: PHashItem;
      Prev: PPHashItem;
    begin
      Prev := Find(Key);
      P := Prev^;
      if P <> nil then
      begin
        Prev^ := P^.Next;
        Dispose(P);
      end;
    end;function TStringHashEx.ValueOf(const Key: string): Integer;
    var
      P: PHashItem;
    begin
      P := Find(Key)^;
      if P <> nil then
        Result := P^.Value
      else
        Result := -1;
    end;end.
      

  7.   

    上边哈希算法是VCL自带的算发,我COPY出来,另外自己加了个GetIpNum函数,
    另外主要自己加了判断KEY,如果有需要你可以再对VALUE做一次判断,因为我看前边写了VALUE不重复,所以没判断了
    调用就象BUTTONCLICK那样调用就好了,另外忘记释放了,不好意思。。
      

  8.   

    for I := 2 to 6 do
      begin
        Memo1.Lines.Add(Format('出现重复%d 的有 %d 个', [I, Test.GetIpNum(I)]));
      end;
    重复次数查询 改I的最大值就可以