列出多个其他数字的数字总和

时间:2014-05-21 10:27:07

标签: delphi delphi-7

我有以下问题:

  

如果我们列出10以下的所有自然数,它们是3或3的倍数   5,我们得到3,5,6和9.这些倍数的总和是23。

     

查找低于1000的3或5的所有倍数的总和。

这是我用来尝试解决问题的代码(Edit1是输出,Edit2是问题引发的数字):

procedure TForm1.Button1Click(Sender: TObject);
  var i, answer : longint;
begin
  answer := 0;
  for i := 0 to strtoint(Edit2.text) - 1 do begin
    if i mod 3 = 0 then answer := answer + i;
    if i mod 5 = 0 then answer := answer + i;
  end;

  Edit1.Text := inttostr(answer);
end;

输入数字10到Edit2(编辑框)将输出:23,如问题所示。在Edit2中输入数字13将输出35,这也是正确的

由于某种原因,当将输入提高到1000时,输出为:266333;当作为答案输入时,被认为是不正确的。

编辑:我已将代码更改为重复计算,这是更新版本:

procedure TForm1.Button1Click(Sender: TObject);
  var i, answer : longint;
begin
  answer := 0;
  for i := 0 to strtoint(Edit2.text) - 1 do begin
    if i mod 3 = 0 then answer := answer + i;
    if i mod 5 = 0 then begin
      if not i mod 3 = 0 then begin
        answer := answer + i;
      end;
    end;
  end;

  Edit1.Text := inttostr(answer);
end;

这仍未给出正确答案。

1 个答案:

答案 0 :(得分:3)

你重复计算。任何数字都是3和5的倍数将被计算两次。还有什么可以从1开始循环而不是零。您可以像这样修复代码:

answer := 0;
for i := 1 to strtoint(Edit2.text) - 1 do begin
  if (i mod 3 = 0) or (i mod 5 = 0) then
    answer := answer + i;
end;

但是,如果将代码与用户界面分开,则代码更容易理解。你也可以把它变得更加通用。所以,你的代码可能如下所示:

function SumOfMultiples(const N: Integer; 
  const Candidates: array of Integer): Integer;
var
  i, j: Integer;
begin
  Result := 0;
  for i := 1 to N-1 do
    for j := 0 to high(Candidates) do
      if i mod Candidates[j] = 0 then
      begin
        inc(Result, i);
        break;
      end;
end;

这里的关键是使用break。一旦我们发现一个数字是一个数字,我们增加运行总数,并打破内部循环。这避免了重复计算。

要找到3和5的倍数之和,小于10,你会写:

SumOfMultiples(10, [3, 5])

我确信可以优化代码以避免任何循环。您需要执行以下操作:

  1. 求和每个候选人的倍数。这可以通过一些除法和乘法直接完成,但没有任何循环。
  2. 考虑重复计算。这可以通过查看候选产品的倍数来完成。
  3. 实施很简单,至少对候选人而言:

    function SumOfMultiples(const N, k: Integer): Integer; overload;
    var
      Count: Integer;
    begin
      Assert(N>0);
      Assert(k>0);
      Count := (N-1) div k;
      Result := k*Count*(Count+1) div 2;
    end;
    
    function SumOfMultiples(const N, k1, k2: Integer): Integer; overload;
    begin
      Assert(k1<>k2);
      Result := SumOfMultiples(N, k1) + SumOfMultiples(N, k2)
        - SumOfMultiples(N, k1*k2);
    end;
    

    我想对两个以上的候选人来说会有点棘手。无论如何,这不是问题,但它可能会成为一个非常有趣的项目,以备不时之需!