请教:如何实现一组数据自动修约?(100分)

  • 主题发起人 主题发起人 godfa
  • 开始时间 开始时间
G

godfa

Unregistered / Unconfirmed
GUEST, unregistred user!
[h4][:(][:(]有A、B、C、D、E这样一组数据,都有1位小数,要求按下列规则修约成整数并使其总和为100:
(1)检查A,如果其小数部分大于或等于0.5,则进位,如93.5修约为94;
(2)取B、C、D、E的整数部分,与修约后的A相加得到总和,如果总和为100,则此结果为最终结果;如总和不是100,则进入下列程序:
(3)查找B、C、D、E中的小数部分最大的进位,然后取另外三个数的整数部分,与刚进位的整数以及修约后的A相加得到总和,如果总和为100,则为最终结果;
如总和不是100,则重复这一步;如果小数部分相同,则进位的优先顺序为B、C、D、E。[/h4]
 
这个 算法 你自己 已经 说的 很明白了啊...
剩下的 就是 写程序了,这没什么 难的吧..自己 多试试..
提 个思路, round 四舍五余 函数
Trunc 取整数 ..

小数 A_real := A- trunc(A);
 
先谢谢小侠,第(3)步及以后不知如何实现
 
最后一步 写个 递归 函数 就 行了啊...至于怎么写 就看 你自己的了
 
拿分来,我给你写
 
unit ut_EdocuAt163com;

{
分析设计:
求和时总是以修约后的整数部分为准
整数部分,小数部分设计缓存,原值在程序中并不是最根本的,但仍要设计缓存区
和值溢出验证
当A的小数部分小于0.5时,与谁相加呢,这是需求描述的不完整(猜一下,A的整部)
godfa同学虽然还不擅长写代码,其需求工作十分到位准确
}

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Math;

type
TNumRec = record
SrcValue: Double; {原值}
NewValue: Double; {新值}
Int: Integer; {整部}
Frac: Double; {小数部}
end;

procedure FixStartUp(A, B, C, D, E: Double); //入口
procedure XInit;
procedure Eval;
procedure Print;

implementation

var
X: array[0..4] of TNumRec;
i: Integer;
Sum: Double;
Index: Integer; {BCDE谁进位}
Msg: string;

{入口}
procedure FixStartUp(A, B, C, D, E: Double);
begin
X[0].SrcValue := A;
X[1].SrcValue := B;
X[2].SrcValue := C;
X[3].SrcValue := D;
X[4].SrcValue := E;

Xinit;

repeat
Eval;
until (Sum = 100);

{打印}
Print;
end;

{初始化}
procedure Xinit;
begin
for i := 0 to 4 do
begin
X.Int := Trunc(X.SrcValue);
X.Frac := X.SrcValue - X.Int;
X.NewValue := X.SrcValue;
end;

{修理A,进位后重设整数部分,小数部分}
if (0.5 <= X[0].Frac) then
begin
X[0].NewValue := Ceil(X[0].NewValue);
X[0].Int := X[0].Int + 1;
X[0].Frac := 0.0;
end;
end;


{评估,修正}
procedure Eval;
begin
{求和}
Sum := 0;
for i := 0 to 4 do
begin
Sum := Sum + X.Int;
end;

if (100 < Sum) then
begin
Application.MessageBox('输入可能有错误,和值溢出100', '', MB_ICONERROR);
Abort;
end;

{若和值不足,选定一个数进位,进位后重设整数部分,小数部分}
if (Sum <> 100) then
begin
Index := 1;
for i := 2 to 4 do
begin
if (X[Index].Frac < X.Frac) then
begin
Index := i;
end;
end;
X[Index].Int := X[Index].Int + 1;
X[Index].Frac := 0.0;
X[Index].NewValue := X[Index].Int;
end;
end;

procedure Print;
begin
Msg := '';
for i := 0 to 4 do
begin
Msg := Msg + Format('%0:s> %1:.1f ==> %2:.1f'#13#10, [Char(65+i), X.SrcValue, X.NewValue]);
end;
ShowMessage(Msg);
end;

end.
 
to icc:

麻烦问个愚蠢问题,比如我在一个窗体上设置了输入ABCD的文本框,再加上一个修约命令,如何调用这个单元啊?因为您提供的只是单元,没有窗体啊。见笑了!
非常感谢!解决问题随后给分!
 
to Mr/Ms icc:

您好,我在命令中调用ut_EdocuAt163com.FixStartUp(A,B,C,D,E)实现了!修约结果正确。但是,结果显示格式与期望有点差异,比如,
输入数据:92.5,3.4,1.6,1.6,1.6
修约结果显示:93.0,3.4,2.0,1.6,1.6
能否将未进位的数值的小数舍去,如显示为:93.0,3.0,2.0,1.0,1.0?
最后一个问题,能否将最终结果写入文本框中?
致以诚挚的感谢!

godfa
 
那位 icc 朋友也许会帮你帮到底的。
这真是你的福气。

像我们这种水平不够不能帮你写程序的,只能在旁边喊喊加油了。
 
已基本解决。谢谢!
 
后退
顶部