作为函数/过程的pascal中的主分解

时间:2016-10-25 17:45:58

标签: arrays pascal dynamic-arrays freepascal prime-factoring

我必须使用函数或过程使用pascal构建一个素数分解程序。 我认为我的路径非常好,但我现在的问题是,似乎无法将动态中继分配为函数/过程的输出。我并不知道我可以使用或做什么(除了一个字符串,但感觉根本就不对)。

PROCEDURE PrimFac(n: INTEGER; VAR res: array of INTEGER);

VAR
    divisor, a, counter: INTEGER;
    b: array of INTEGER;

BEGIN
    divisor := 2;
    a := n;
    counter := 0;
    WHILE divisor <= n DIV 2 DO BEGIN
        IF a MOD divisor = 0 THEN BEGIN
            a := a DIV divisor;
            counter := counter + 1;
            SetLength(b, counter);
            b[counter] := divisor;
        END
        ELSE
            divisor := divisor + 1;
    END;
    res := b
END;

BEGIN
WriteLn(PrimFac(210));
END.

任何帮助或暗示都将受到高度赞赏。 (: 非常感谢你提前 -Florian

1 个答案:

答案 0 :(得分:2)

我看到这是FreePascal,它与Delphi非常相似。

您应该预先定义要返回的类型,而不是使用open array parameter(不应该与动态数组混淆),您应该预先定义要返回的类型:

type
  TIntegerDynArray = array of Integer;

function PrimFac(n: Integer): TIntegerDynArray;
...
  SetLength(Result, counter);
  Result[counter - 1] := divisor;
...

FWIW,每次要添加元素时重新分配动态数组通常不是一个好主意。最好将结果保存在临时TList(如果可能的话,通用TList)中,然后在最后将其转换为所需长度的数组,然后摆脱临时列表,IOW类似(未经测试):

uses
  fgl;

type
  TIntegerDynArray = array of Integer;
  TIntegerList = specialize TFPGList<Integer>;

function PrimFac(N: Integer): TIntegerDynArray;
var
  Divisor, A, I: Integer;
  L: TIntegerList; 
begin
  A := N;
  L := TIntegerList.Create;
  try
    { Find divisors and add each to list. }
    for Divisor := 2 to N div 2 do
    begin
      { Use "while" so a divisor can be found multiple times, e.g. }
      { using "if": 1000 --> 2 4 5 25 (but 4 = 2*2, and 25 = 5*5)  }
      { using "while": 1000 --> 2 2 2 5 5 5                        }
      while A mod Divisor = 0 do
      begin
        A := A div Divisor;
        L.Add(Divisor);
      end;
    end;

    { Copy list to result array. }
    SetLength(Result, L.Count);
    for I := 0 to L.Count - 1 do
    begin
      Result[I] := L[I];
    end;
  finally
    L.Free;
  end;
end;

请注意,您的算法可以使用一些额外的检查(0,1等),但这取决于您。我只回答了如何返回值。

更新

如果要打印列表,请执行以下操作:

    { Find divisors and print each one. }
    for Divisor := 2 to N div 2 do
    begin
      while A mod Divisor = 0 do
      begin
        A := A div Divisor;
        L.Add(Divisor);
        Write(Divisor, ' ');
      end;
    end;
    Writeln;

列出所有以空格分隔的数字,并在完成后执行最终换行。如果你想要更复杂的输出,请运用你的想象力。