帕斯卡中的质因数分解为 function/procedure
Prime factorization in pascal as a function/procedure
我必须使用函数或过程用 Pascal 构建素数分解程序。
我认为我走在一条很好的道路上,但我现在的问题是,似乎不可能将动态继电器分配为 function/procedure 的输出。而且我不知道我可以使用什么或做什么(字符串除外,但感觉根本不对)。
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.
如有任何帮助或提示,我们将不胜感激。 (:
非常感谢你提前
-弗洛里安
我看到这是FreePascal,和Delphi很像。
而不是使用 open array parameter(尽管语法相似,但不应与 动态数组 混淆),您应该预定义一个类型 return:
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 等),但这取决于您。我只是回答了如何 return 值。
更新
如果要打印列表,请执行以下操作:
{ 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;
这会列出所有由空格分隔的数字,并在完成时执行最后的换行。如果你想要更复杂的输出,请发挥你的想象力。
我必须使用函数或过程用 Pascal 构建素数分解程序。 我认为我走在一条很好的道路上,但我现在的问题是,似乎不可能将动态继电器分配为 function/procedure 的输出。而且我不知道我可以使用什么或做什么(字符串除外,但感觉根本不对)。
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.
如有任何帮助或提示,我们将不胜感激。 (: 非常感谢你提前 -弗洛里安
我看到这是FreePascal,和Delphi很像。
而不是使用 open array parameter(尽管语法相似,但不应与 动态数组 混淆),您应该预定义一个类型 return:
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 等),但这取决于您。我只是回答了如何 return 值。
更新
如果要打印列表,请执行以下操作:
{ 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;
这会列出所有由空格分隔的数字,并在完成时执行最后的换行。如果你想要更复杂的输出,请发挥你的想象力。