关于自定义函数的问题(90分)

  • 主题发起人 主题发起人 chenfsb
  • 开始时间 开始时间
C

chenfsb

Unregistered / Unconfirmed
GUEST, unregistred user!
函数存在问题请帮忙改一改。thanks:)
想实现一个自定义函数,流程:
1.把valuelist中的值求出平均数
2.valuelist-平均数
3.再量化valuelist中的每一值,取出正数中的最大值,让每一个正数除以最大值
4.取出最小值,让负数除以最小值的绝对值
这个函数写得很憋脚,若有优化代码的建议也给分。

function ConvertValues(valuelists:TStringlist;I:Integer;average,minv,maxv:Double;):TStringList;
begin
average:=0;
minv:=0;
maxv:=0;
for I:=0 to valuelists.Count-1 do
begin
average:=average+StrToFloat(valuelists);
end;
average:=average/valuelists.Count;
minv:=Min(StrToFloat(valuelists[0]),StrToFloat(1));
maxv:=Max(StrToFloat(valuelists[0]),StrToFloat(valuelists[1]));
for I:=2 to valuelists.Count-1 do
begin
if StrToFloat(valuelists)<0 then
valuelists:=Format('%10.6f',[StrToFloat(valuelists)/Abs(minv)])
else
valuelists:=Format('%10.6f',[StrToFloat(valuelists/maxv)]);
end;
end;
 
好象你的代码实现的不是你说的要求哦。
你的代码实现的是:
1、求平均数。(求完就不用了)
2、从第3行开始所有负数除以第一与第二行中小的那个数的绝对值, 所有0或正数除以第一与第二行中大的那个数。
这里除数可能是0(!!)或负数。 比如象下面这种数据函数就无法处理:
2
0
3
8
....

帮你重写了一个(按你提的1、2、3、4)。

procedure ConvertValues(valuelists:TStringlist);
var
i: Integer;
arr: array of Double;
avg, minv, maxv: Double;
begin
SetLength(arr, valuelists.Count);
avg := 0;
minv := 1.7E308;
maxv := -1.7E308

for i := 0 to valuelists.Count-1 do
begin
arr := StrToFloat(valuelists.strings);
avg := avg+arr;
minv := min(arr, minv);
maxv := max(arr, maxv);
end;
avg := avg / valuelists.count;
minv := minv-avg;
maxv := maxv-avg;
if minv=0 then minv := 1;
if maxv=0 then maxv := 1;
for i := 0 to valuelists.count-1 do
begin
arr := arr-avg;
if arr<0 then
arr := arr / abs(minv)
else if arr>0 then
arr := arr / maxv;
valuelists.strings := format('%10.6f', [arr]);
end;
setlength(arr, 0);
end;
 
function ConvertValues(var valuelists:TStringlist;var average,minv,maxv:Double):Boolean;
var
x:double;
I:Integer;
begin
Result:=false;
if valuelists.Count<1 then exit;
try
x:=StrToFloat(trim(valuelists[0])+'0');
except
exit;
end;
average:=x;
minv:=x;
maxv:=x;
try
for I:=1 to valuelists.Count-1 do
begin
x:=StrToFloat(trim(valuelists)+'0');
average:=average+x;
if x>maxv then maxv:=x;
if x<minv then minv:=x;
end;
except
exit;
end;

average:=average/valuelists.Count;
minv:=abs(minv);
maxv:=abs(maxv);//最大值也有可能为负。
try
for I:=0 to valuelists.Count-1 do
begin
x:=StrToFloat(trim(valuelists)+'0');
if x=0.0 then continue;
if x<0 then
x:=x/minv
else
x:=x/maxv;
valuelists:=trim(Format('%10.6f',[x]));
end;
except
exit;
end;
Result:=true;
end;
 
thanks you all
to Another_eYes
你的方法有点问题的是:
minv := 1.7E308;
maxv := -1.7E308

可能arr中最大和最小值都超不过这两个最大和最小值,那么这个函数就失去了意义

to jsxjd
"maxv:=abs(maxv);//最大值也有可能为负"
这个提示很重要。:)
 
>>可能arr中最大和最小值都超不过这两个最大和最小值,那么这个函数就失去了意义
怎么可能呢。
最大值的初始化值我设为-1.7E308即-1.7*10^308 你的数组中所有值都小于这个数的话那么它们当然也小于1.7E308即1.7*10^308(也就是我设置的最小值的初始化值), 所以可以取到正确的最小值。同理也能取到最大值。
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
911
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部