procedure TForm1.Button1Click(Sender: TObject); var S, T: String; Odd, Even: Integer; List: TStringList; begin List := TStringList.Create; S := '21,33,03,45,31,04,56,66,86,55'; List.DelimitedText := S; Odd := 0; Even := 0; for T in List do begin if (StrToInt(T) mod 2) = 1 then Inc(Odd) else Inc(Even); end; List.Free; ShowMessage(Format('奇数个数: %d, 偶数个数:%d', [Odd, Even])); end;
以前我竟然不会使用for T in List do,哈哈哈
//也可以不使用TStringList,下面的写法运行效率更高一点: procedure TForm1.Button1Click(Sender: TObject); var C: AnsiChar; S: AnsiString; Found: Boolean; I, Len, Odd, Even: Integer; begin S := '21,33,03,45,31,04,56,66,86,55'; Found := False; Odd := 0; Even := 0; len := Length(S); for I := 1 to Len do begin if S[I] in ['0'..'9'] then begin C := S[I]; Found := True; end; if Found and ((I = Len) or (not (S[I] in ['0'..'9']))) then begin if (C in ['1', '3', '5', '7', '9']) then Inc(Odd) else Inc(Even); Found := False; end; end; ShowMessage(Format('奇数个数: %d, 偶数个数:%d', [Odd, Even])); end;
我刚仿着把我的控件遍历修改完,你又说这个效率高,哈哈 那么问题来了:for T in List do 和 for I := 1 to Len do 到底哪一个效率更高呢?
for T in List do 和 for I := 1 to Len do的效率基本是一样的, 有没有使用到TStringList才是关键。 只在有海量的数据需要判断奇偶数个数的情况下,这两个程序的才会有区别。如果只是判断'21,33,03,45,31,04,56,66,86,55', 假定一个用了1毫秒,另一个用了0.1毫秒,对你有区别吗
严格上讲,for I := 1 to Len do的效率会高点,但一般差别很少
可以:uses System.SysUtils, System.StrUtils;procedure StatNumbers(const S: string; var Odds, Evens: integer); var p1, p2, n, c: integer; begin Odds := 0; Evens := 0; p1 := 1; p2 := 1; repeat if p1 > Length(S) then break; p2 := PosEx(',', S, p2); if p2 = 0 then p2 := Length(S) + 1; Val(Copy(S, p1, p2 - p1).Trim, n, c); if c = 0 then if n and 1 <> 0 then Inc(Odds) else Inc(Evens); p1 := p2 + 1; p2 := p1; until false; end;
procedure TForm1.Button1Click(Sender: TObject); var S: AnsiString; i,Len, Odd, Even: Integer; begin S := '21,33,03,45,31,04,56,66,86,55'; Odd := 0; Even := 0; len := Length(S); for I := 1 to Len do begin if i<Len then begin if S[I+1]=',' then begin if S[I] in ['1', '3', '5', '7', '9'] then Inc(Odd) else Inc(Even); end end else begin if S[I] in ['1', '3', '5', '7', '9'] then Inc(Odd) else Inc(Even); end; end; ShowMessage(Format('奇数个数: %d, 偶数个数:%d', [Odd, Even])); end;也可这样。方式多种。
只是算法不同,当然,使用Stringlist,比较好。当出现分隔符多样时: 这种算法比较实用了。 仅修改一句 if (S[I+1]=',') or (S[I+1]=';') or (S[I+1]=' ') then 即可。 同时,比较规范的操作,应事前对String进行格式化处理。
只是算法不同,当然,使用Stringlist,比较好。当出现分隔符多样时: 这种算法比较实用了。 仅修改一句 if (S[I+1]=',') or (S[I+1]=';') or (S[I+1]=' ') then 即可。 同时,比较规范的操作,应事前对String进行格式化处理。
procedure OddEvenNumCounter(S:String;var OddNumCount:Integer;var EvenNumCount:Integer;var ZeroNumCount:Integer); var List: TStringList; i:Integer; begin //0不为奇偶数,在过程外设置初始值,有利于批处理 List := TStringList.Create; List.DelimitedText := S; for i:=0 to List.Count-1 do begin if StrToInt(List[i])=0 then INC(ZeroNumCount) else if StrToInt(List[i]) then INC(OddNumCount); end; EvenNumCount := EvenNumCount + List.Count - OddNumCount - ZeroNumCount; List.Free; end;
if xx and 1 = 1 then {奇数} else {偶数}
const S: string = '21,33,03,45,31,04,56,66,86,55'; var nStr: string; begin for nStr in S.Split([',']) do try if nStr.ToInteger and 1 = 1 then ShowMessage('奇数') else ShowMessage('偶数'); except ShowMessage('不是有效数字'); end; end;
procedure TForm1.Button1Click(Sender: TObject);
var
S, T: String;
Odd, Even: Integer;
List: TStringList;
begin
List := TStringList.Create;
S := '21,33,03,45,31,04,56,66,86,55';
List.DelimitedText := S;
Odd := 0; Even := 0;
for T in List do
begin
if (StrToInt(T) mod 2) = 1 then
Inc(Odd)
else
Inc(Even);
end;
List.Free;
ShowMessage(Format('奇数个数: %d, 偶数个数:%d', [Odd, Even]));
end;
//也可以不使用TStringList,下面的写法运行效率更高一点:
procedure TForm1.Button1Click(Sender: TObject);
var
C: AnsiChar;
S: AnsiString;
Found: Boolean;
I, Len, Odd, Even: Integer;
begin
S := '21,33,03,45,31,04,56,66,86,55';
Found := False; Odd := 0; Even := 0; len := Length(S);
for I := 1 to Len do
begin
if S[I] in ['0'..'9'] then
begin
C := S[I];
Found := True;
end;
if Found and ((I = Len) or (not (S[I] in ['0'..'9']))) then
begin
if (C in ['1', '3', '5', '7', '9']) then
Inc(Odd)
else
Inc(Even);
Found := False;
end;
end;
ShowMessage(Format('奇数个数: %d, 偶数个数:%d', [Odd, Even]));
end;
那么问题来了:for T in List do 和 for I := 1 to Len do 到底哪一个效率更高呢?
只在有海量的数据需要判断奇偶数个数的情况下,这两个程序的才会有区别。如果只是判断'21,33,03,45,31,04,56,66,86,55', 假定一个用了1毫秒,另一个用了0.1毫秒,对你有区别吗
var
p1, p2, n, c: integer;
begin
Odds := 0;
Evens := 0;
p1 := 1;
p2 := 1;
repeat
if p1 > Length(S) then break;
p2 := PosEx(',', S, p2);
if p2 = 0 then p2 := Length(S) + 1;
Val(Copy(S, p1, p2 - p1).Trim, n, c);
if c = 0 then
if n and 1 <> 0 then Inc(Odds) else Inc(Evens);
p1 := p2 + 1;
p2 := p1;
until false;
end;
var
S: AnsiString;
i,Len, Odd, Even: Integer;
begin
S := '21,33,03,45,31,04,56,66,86,55';
Odd := 0; Even := 0; len := Length(S);
for I := 1 to Len do
begin
if i<Len then
begin
if S[I+1]=',' then
begin
if S[I] in ['1', '3', '5', '7', '9']
then Inc(Odd)
else Inc(Even);
end
end
else begin
if S[I] in ['1', '3', '5', '7', '9']
then Inc(Odd)
else Inc(Even);
end;
end;
ShowMessage(Format('奇数个数: %d, 偶数个数:%d', [Odd, Even]));
end;也可这样。方式多种。
仅修改一句 if (S[I+1]=',') or (S[I+1]=';') or (S[I+1]=' ') then 即可。
同时,比较规范的操作,应事前对String进行格式化处理。
仅修改一句 if (S[I+1]=',') or (S[I+1]=';') or (S[I+1]=' ') then 即可。
同时,比较规范的操作,应事前对String进行格式化处理。
var
List: TStringList;
i:Integer;
begin
//0不为奇偶数,在过程外设置初始值,有利于批处理
List := TStringList.Create;
List.DelimitedText := S;
for i:=0 to List.Count-1 do
begin
if StrToInt(List[i])=0 then
INC(ZeroNumCount)
else if StrToInt(List[i]) then
INC(OddNumCount);
end;
EvenNumCount := EvenNumCount + List.Count - OddNumCount - ZeroNumCount;
List.Free;
end;
{奇数}
else
{偶数}
const
S: string = '21,33,03,45,31,04,56,66,86,55';
var
nStr: string;
begin
for nStr in S.Split([',']) do
try
if nStr.ToInteger and 1 = 1 then
ShowMessage('奇数')
else
ShowMessage('偶数');
except
ShowMessage('不是有效数字');
end;
end;