如何检测数组中的重复项?

chengran1984 2009-10-24 04:07:38
有几万个IP在一个文本文件中,我想提出里面出现2次的,还有出现3次,还有仅仅出现一次的IP,分别存储.

IP是一行一个.
...全文
131 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
chengran1984 2009-10-25
  • 打赏
  • 举报
回复
只爱三国,非常感谢,我在研究你的代码.
sanguomi 2009-10-25
  • 打赏
  • 举报
回复
for I := 2 to 6 do
begin
Memo1.Lines.Add(Format('出现重复%d 的有 %d 个', [I, Test.GetIpNum(I)]));
end;
重复次数查询 改I的最大值就可以
sanguomi 2009-10-25
  • 打赏
  • 举报
回复
上边哈希算法是VCL自带的算发,我COPY出来,另外自己加了个GetIpNum函数,
另外主要自己加了判断KEY,如果有需要你可以再对VALUE做一次判断,因为我看前边写了VALUE不重复,所以没判断了
调用就象BUTTONCLICK那样调用就好了,另外忘记释放了,不好意思。。
sanguomi 2009-10-25
  • 打赏
  • 举报
回复

unit Unit1;

interface

uses
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.

贝隆 2009-10-24
  • 打赏
  • 举报
回复
排序
chengran1984 2009-10-24
  • 打赏
  • 举报
回复
112.66.131.78
112.82.36.135
112.95.246.76
112.112.117.175
112.192.88.109
112.192.232.122
112.193.8.234
113.6.43.169
113.6.43.169
113.7.205.162
113.12.241.114
113.18.152.158
113.65.129.28
113.66.237.52
113.67.124.165
113.67.196.153
113.67.200.61
113.76.29.213
113.76.117.240
113.87.175.128
113.87.212.200
113.91.134.107
113.91.135.127
113.91.135.172
113.91.137.102
113.97.133.110
yshuui 2009-10-24
  • 打赏
  • 举报
回复
有几万个IP在一个文本文件中,是每行一个吗?
看一下stringlist类的方法,就知道了。
chengran1984 2009-10-24
  • 打赏
  • 举报
回复
yshuui 能说的具体点吗?

我才学delphi不久.
sanguomi 2009-10-24
  • 打赏
  • 举报
回复
数据少,用TLIST这样的单性列表和哈希比,哈希的效率体现不出来
几万用哈希存储比较合适,查找也方便,以后加数据也不错
s11ss 2009-10-24
  • 打赏
  • 举报
回复
正则表达式
yshuui 2009-10-24
  • 打赏
  • 举报
回复
用stringlist载入,然后排序。再循环一下就行了。
chengran1984 2009-10-24
  • 打赏
  • 举报
回复
痛苦的等待

艰难的调试

还是没有答案.
chengran1984 2009-10-24
  • 打赏
  • 举报
回复
2楼是什么意思呢?

我是超级大菜鸟.
chengran1984 2009-10-24
  • 打赏
  • 举报
回复
可能是我没描述清楚

我只是要挑选出出现过一次的,出现过两次的,出现过3次以上的

一个种类存储在一个文本文件中
dqlihb 2009-10-24
  • 打赏
  • 举报
回复
先排序吧,简单易行
kaikai_kk 2009-10-24
  • 打赏
  • 举报
回复
出现4次,5,6,7...N次的呢??如何处理

提出来后存在那里?存在文本?

分别存储,是一个IP存一个文本吗?那不是要几万个了?

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧