【问题标题】:Pascal/Python Factorization ProgramPascal/Python 因式分解程序
【发布时间】:2018-08-26 15:30:29
【问题描述】:

我已经编写了两个程序来查找数字的质因数,一个在 python 中,一个在 pascal 中。我想分解 600851475143; python程序立即分解它。但是,帕斯卡没有在合理的时间内完成。是否与不同的编程语言或我如何用 Pascal 编码有关?我在 python 中使用了递归,但在 pascal 中没有。为什么 pascal 程序也不能立即完成?

蟒蛇:

def findLowestFactor(num, factors=None):
    if factors:
        start = factors[-1]
    else:
        start = 2
    for i in range(start, int(num)):
        if num%i == 0:
            return i
    else:
        return False


def findPrimeFactors(num, factors=None):
    if factors is None:
        factors = []
    factor = findLowestFactor(num, factors)
    if factor:
        factors.append(factor)
        findPrimeFactors(num/factor, factors)
        return factors
    else: 
        factors.append(int(num))
        return factors


if __name__ == "__main__":
    while True:
        num = int(input("Please enter a number: "))
        factors = findPrimeFactors(num)
        print(*factors)

帕斯卡:

program Primes;

var
  input:string;
  num:integer;
  error:integer;
  factor:integer;
  factors:array of integer;
  found: boolean;
  start:integer;
  x:integer;


begin
  writeln(600851475143);
  (*Repeat untill exit*)
  while true do
  begin
    (*Repeat untill valid input*)
    repeat
    write('Enter a number: ');
    readln(input);
    val(input, num, error);
    if error = 1 then
      writeln('Not an integer');
    until error = 0;

    writeln;

    (*set up list*)
    SetLength(factors, 0);
    factor := 0;
    found := false;
    (*while num is not prime*)
    while found = false do
    begin
      (*start from largest factor found for efficiency*)
      if length(factors) > 0 then
        start := factors[length(factors)-1]
      else
        start := 2;
      (*loop through numbers from number in start var to current num*)
      for factor := start to num do
      begin
        (*if there are no more factors*)
        if num / factor = 1 then
          begin;
            (*add final factor to list*)
            SetLength(factors, length(factors)+1);
            factors[length(factors)-1] := factor;
            (*break out of the loop*)
            found := True;
          end
        (*if factor is found*)
        else if num mod factor = 0 then
          begin
            (*divide num by found factor*)
            num := num div factor;
            (*add the factor*)
            SetLength(factors, length(factors)+1);
            factors[length(factors)-1] := factor;
            (*break for efficiency*)
            Break;
          end;


      end;
    end;

    write('Prime Factors: ');
    for x:= 0 to length(factors)-1 do
      write(factors[x], ' ');
    writeln;
    writeln;

  end;

end. 

【问题讨论】:

  • 很难说。你用的是哪个帕斯卡?此外,Python 代码结构良好,而 Pascal 代码几乎是一个块。该方法似乎也有所不同,因此可以很好地解释这种差异。另请注意,600851475143 大于 32 位,因此如果整数在 Pascal 中为 32 位,它可能无法按预期工作。 Python 可能使用正确的数据类型,具体取决于您给它的数字。所以可能有几个因素。
  • FWIW,而不是 Integer,尝试对 Pascal 中的相关变量使用 Int64。

标签: python pascal factorization


【解决方案1】:

我将您的 Python 代码翻译成 Pascal。我使用了 Delphi,但它也应该在 FreePascal 中编译。它立即返回:

type
  TIntArray = array of Integer; // Delphi: TArray<Integer>;

function findLowestFactor(num: Int64; factors: TIntArray): Integer;
var
  start: Integer;
  i: Int64;
begin
  if Length(factors) > 0 then
    start := factors[High(factors)]  // factors[-1] in Python, i.e. last entry.
  else
    start := 2;
  i := start;
  while i < num do        // Int64 can not be used as index in for-loop... 
  begin                   // ... so I use while loop.
    if num mod i = 0 then // Python: if num % i == 0:
      Exit(i);            // return i
    Inc(i);
  end;
  Exit(0);
end;

procedure findPrimeFactors(num: Int64; var factors: TIntArray);
var
  factor: Integer;
begin
  factor := findLowestFactor(num, factors);
  if factor > 0 then
  begin 
    // Delphi: factors := factors + [factor];
    SetLength(factors, Length(factors) + 1);
    factors[High(factors)] := factor;

    findPrimeFactors(num div factor, factors);
  end
  else
  begin
    // Delphi: factors := factors + [Integer(num)];
    SetLength(factors, Length(factors) + 1);
    factors[High(factors)] := Integer(num);
  end;
end;

const
  testValue: Int64 = 600851475143;

var
  factors: TIntArray;
  i: Integer;
  result: Int64;

begin
  // Instead of user input, I use the testValue above.
  Writeln('test value: ', testValue);
  findPrimeFactors(testValue, factors);
  result := 1;
  for i in factors do
  begin
    Write(i:8);
    result := result * i;
  end;
  Writeln;
  Writeln('multiplied: ', result);
  Readln;
end.

请注意,我必须在某些地方使用 Int64。我假设 Python 会自动执行此操作,但不是 Pascal。也许在某些地方使用整数会使您的代码变得如此缓慢。

我省略了代码的用户输入部分(Readln 等),只使用了您提供的常量值。但是,正如我所说,它会立即返回正确的值(参见变量结果)。

【讨论】:

  • 感谢您的回复。是的,问题是我没有使用 Int64,因为我是 Pascal 的新手。我将通读并尝试使用递归来理解您的 Pascal 版本。我之前尝试过自己翻译,但在 Pascal 方面还不够好。 :)
  • 请注意,我是用 Delphi 编写的。在那里,您可以简单地执行以下操作,而不是 SetLength() 行和之后的行:factors := factors + [factor];。但我认为这在 Pascal 的其他实现中是不可能的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-23
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多