求最佳效率算法(100分)

  • 主题发起人 主题发起人 jingtao
  • 开始时间 开始时间
J

jingtao

Unregistered / Unconfirmed
GUEST, unregistred user!
有一个文本文件.里面包含了很多个IP地址.求一最高效率算法.能取出第一个IP地址.
 
当流来找;
找第一个小数点,其后 8个字符内必须有两个小数点,再判断数字
 
这是硬编码.我要高效率的.
 
什么格式的文本文件?能放一个上来看看吗?
 
sefs92345kmzxcasdfl;;asdasfbgtrthrthrth202.103.628.76oplasasdhjghsdAm,SDSFGNNZASDFB111.345.sxdsdsddf202.103.224.68zsdffghntghtrtrt102.103.23.88sasSDG90234
 
先确认一下,是不是会有这样的数据???还是你写错了
202.103.628.76
 
我现在是硬编码.但循环太多了..
procedure TForm1.Button2Click(Sender: TObject);
var
Result: Boolean;
strText, s1, s2, s3, s4,s: string;
iStart, iEnd, i, j, k, l, m, n, iPos: integer;
bFound: Boolean;
begin
Result := False;

strText:='sefs92345kmzxcasdfl;;asdasfbgtrthrthrth202.103.628.76oplasasdhjghsdAm,SDSFGNNZASDFB111.345.sxdsdsddf202.103.224.68zsdffghntghtrtrt102.103.23.88sasSDG90234';
for i := 1 to length(strText) do if strText in ['1'..'9'] then
begin
iStart := i;
for j := i to i + 3 do if strText[j] = '.' then
begin

bFound := True;
for n := i to j - 1 do if not (strText[n] in ['0'..'9']) then
begin
bFound := False;
break;
end;
if not bFound then Continue;

s1 := Copy(strText, i, j - i);


if strText[j + 1] in ['1'..'9'] then
begin
for k := j + 1 to j + 4 do if strText[k] = '.' then
begin

bFound := True;
for n := j + 1 to k - 1 do if not (strText[n] in ['0'..'9']) then
begin
bFound := False;
break;
end;
if not bFound then Continue;
s2 := Copy(strText, j + 1, k - 1 - j);

if strText[k + 1] in ['1'..'9'] then
begin
for l := k + 1 to k + 4 do if strText[l] = '.' then
begin

bFound := True;
for n := k + 1 to l - 1 do if not (strText[n] in ['0'..'9']) then
begin
bFound := False;
break;
end;
if not bFound then Continue;
s3 := Copy(strText, k + 1, l - 1 - k);

if strText[l + 1] in ['1'..'9'] then
begin
for m := l + 1 to l + 4 do
if not (strText[m] in ['0'..'9']) then break;

bFound := True;
for n := l + 1 to m - 1 do if not (strText[n] in ['0'..'9']) then
begin
bFound := False;
break;
end;
if not bFound then Continue;
s4 := Copy(strText, l + 1, m - 1 - l);

if (StrToIntDef(s1,256)>255) or
(StrToIntDef(s2,256)>255) or
(StrToIntDef(s3,256)>255) or
(StrToIntDef(s4,256)>255) then
Continue else
begin
s:=copy(strText, iStart, m - iStart);
ShowMessage('Found:'+s);
exit;
end;
end;
end;
end;
end;
end;
end;
end;
ShowMessage('finish');
end;
 
没写错.202.103.628.76 说明格式不对.继续找下一个.
 
不过上面的算法仍然有一个BUG.如果把202.103.224.68改成602.103.224.68.那么,会找到2.103.224.68
 
我帮你想算法
但不写
可以吗
 
还是写.....来的直接些....
 
TEXT:文本文件,I:位置,开始位置是1
一、写一个自定义函数AAA
接收I
自位置I开始,读出TEXT中第一个1-9的字符
返回位置J
二、自定义函数BBB:获取第一IP段(返回:逻辑型L,位置M:)
1、接收AAA函数返回的位置J,读取第一个数字
2、第二个字符:‘。’,返回L=True,位置J+2
0-9,继续,否则,返回J+2,L=False
3、第三个字符:‘。’,返回L=True,位置J+3
0-9,继续,否则,返回J+3,L=False
判断J到J+2三个字符联合<=255,继续;否则,返回False,J+1
4、第四个字符:‘。’,返回True,J+4
三、程序主体
先调用AAA,得到第一个数字,然后调用BBB,返回为True,则获取了第一个IP段,和下一个IP段的开始位置
再次调用BBB,成功,则获取了第二段,否则,返回相应位置,调用AAA,查找第一个1-9的字符


四段连续IP找到的时候,返回’我成功了,IP地址找到了,哈哈‘
文件结束,没有找到,则返回’程序错了,还是真的没有?IP呢???‘

不小心死循环了呢,就好好研究一下算法
 
好像我上面的硬编码就是这么干的吧....
 
是吗?
没注意看,太乱,嵌套太多
做个自定义函数吧
 
循环太多,效率太低啊
 
一、找出第一个点的位置。
二、找到第二个点的位置。
三、找到第三个点的位置。
四、看他们之间有几个字符,均小于三,进一步判断是否是数字,是则,看其第一点和第三点前是否为数字,否则继续找,是则取ip。
五、找到退出,找不到,继续
注:没试验不知道效率如何,中间可能会用到较多的pos。但省去一个一个查找。
 
楼上兄弟
情况复杂,我觉得还是一个字符一个字符来找的准确
比如,688.12.25.31
这个你说它是不是
说是也不是,说不是也是
或者也可以在你方法的基础上,多加些判断,也许可行,但两个方法就差不多了
///////////////////
楼主是说我的方法循环多呢?还说自己的??
 
算法的出发点不对,应该先找到点,然后截取字符串处理。你对每一个字符进行
strText in ['1'..'9']需要判断9次,如果找点只是需要判断1次,看如下算法


function FindIp(vStr: String): String; //从字符串中取ip 不成功则返回空
var
SeekPos, i,StrStat, StrEnd: Integer;
tmpStr: String;//保存需要测试的字符串

//从短字符串中取ip 不成功则返回空
function FindIpInShortString(vShortStr: String): String;
var
i,dotCount: Integer;
DotArray: Array[1..15] of Integer; //保存ip中点的位置
begin
Result := '';
if Length(vShortStr)=0 then exit;
//删除头字符
for i:=1 to length(vShortStr) do
begin

if vShortStr in ['0'..'9'] then
begin
if i>1 then
Delete(vShortStr, 1,i-1);
break;
end;
end;

//删除尾字符
for i:= length(vShortStr) downto 1 do
begin
if vShortStr in ['0'..'9'] then
begin
if i<Length(vShortStr) then
Delete(vShortStr, i+1, length(vShortStr)-i);
break;
end;
end;

//排除非字符,并计算点的位置
dotCount := 0;
for i:=1 to Length(vShortStr) do
begin
if vShortStr='.' then
begin
DotArray[dotCount] := i;//点的位置
Inc(dotCount);
Continue;
end;

if not (vShortStr in ['0'..'9']) then
Exit;
end;
if dotCount<3 then exit;

//进行ip合法性判断,自己完善吧
//...
Result := vShortStr;
end;
begin

Result := '';
for SeekPos := 1 to Length(vStr) do
begin
if vStr[SeekPos]='.' then
begin
tmpStr := copy(vStr, SeekPos-3, 15); //ip长度最长15
Result := FindIpInShortString(tmpStr);
if Result<>'' then
exit;
end;
end;
end;
 
忘记说明了,将主要函数中不需要的变量删掉
 
var
myString: string;
i,j,k : integer;
num :array[1..4] of integer;
begin
memo7.Clear;
myString :='sefs92345kmzxcasdfl;;asdasfbgtrthrthrth202.103.628.76oplasasdhjghsdAm,SDSFGNNZASDFB111.345.sxdsdsddf202.103.224.68zsdffghntghtrtrt102.103.23.88sasSDG90234';
//init num array
for k :=1 to 4 do
begin
num[k] :=0;
end;
k:=0;
for i:=1 to length(mystring) do
begin
if ( mystring in ['0'..'9']) then
begin
if k=0 then
k:=1;
num[k] :=num[k]*10+ord(mystring)-ord('0');
if num[k]>255 then
begin
for j :=1 to k do
begin
num[j] :=0;
end;
k:=0;
end;
end
else if mystring ='.' then
begin
if ( mystring[i+1] in ['0'..'9']) then
k :=k+1;
end
else
begin
if k=4 then //»ñÈ¡ÁË¿ÉÄܵÄip ´¦Àí
begin
memo7.Lines.Add(IntTostr(num[1])+'.'+IntTostr(num[2])+'.'+IntTostr(num[3])+'.'+IntTostr(num[4]));
//Çå¿Õ
for j :=1 to k do
begin
num[j] :=0;
end;
k:=0;
end;
end;
end;
 
后退
顶部