如何在Delphi中检查素数

如何在Delphi中检查素数,delphi,primes,Delphi,Primes,我想将1到10000之间的所有素数读入一个动态数组,将所有非素数读入另一个动态数组,然后将素数数组读入richedit1到目前为止,我已经: procedure primearrays; var j, k, l, i, m: integer; // k is the number I am testing for prime number // j is used in the for loop to check all numbers smaller than k to see if

我想将1到10000之间的所有素数读入一个动态数组,将所有非素数读入另一个动态数组,然后将素数数组读入
richedit1
到目前为止,我已经:

procedure primearrays;
var
  j, k, l, i, m: integer; // k is the number I am testing for prime number
  // j is used in the for loop to check all numbers smaller than k to see if k is dividable by j
  // l is just a variable set to k mod j to make the if run more smoothly
  // i is the length of the array anotprime
  // m is used to set the length of the array aprime
  bflag: boolean; // bflag is to show if this number is a prime number
  aprime, anotprime: array of integer;
  // aprime is the array of prime and anotprime is the array of nonprime numbers
begin
  j := 0;
  i := 0;
  l := 0;
  richedit1.Lines.Clear;
  bflag := false;
  for k := 2 to 10000 do
  begin
    j := 0;
    while not(j = (k - 1)) do
    begin
      inc(j);
      l := k mod j;
      if (l = 0) then
      begin
        bflag := false;
        inc(i);
        setlength(anotprime, i);
        anotprime[i - 1] := k;
        j := k - 1;
      end
      else
      begin
        bflag := true;
      end;
    end;
    m := -1;
    if (bflag) then
    begin
      inc(m);
      setlength(aprime, m);
      aprime[m - 1] := k;
      richedit1.Lines.Add(inttostr(aprime[l-1]));
    end;
  end;
end;

但这似乎不起作用。它将所有整数放入
anotprime

可能您的主要问题是将所有不同方面(循环候选项、素数检查、显示等)混合到一个函数中

如果你把任务分解成只执行一项任务的小块,生活就会变得容易得多。从测试数字是否为素数的函数开始

function IsPrime(N: Integer): Boolean;
var
  M: Integer;
begin
  Assert(N > 0);
  if N = 1 then // annoying special case
  begin
    Result := False;
    exit;
  end;
  for M := 2 to (N div 2) do
  begin
    if N mod M = 0 then
    begin
      Result := False;
      exit;
    end;
  end;
  Result := True;
end;
现在,您可能希望创建一个包含素数的列表:

var 
  Primes: TList<Integer>;
  N: Integer;
....
// create Primes
for N := 1 to 10000 do
  if IsPrime(N) then
    Primes.Add(N);
var
素数:TList;
N:整数;
....
//创建素数
对于N:=1到10000 do
如果是IsPrime(N),那么
素数。加(N);

这不是枚举素数的最有效方法。但这可能是您应该开始的地方,我写这个答案主要是为了鼓励您将代码划分为一些小的逻辑方法,这些方法可以完成特定的重点任务

可能您遇到的主要问题是,您将所有不同方面(在候选项上循环、素数检查、显示等)混合到一个函数中

procedure TForm1.btnprimeClick(Sender: TObject);
var K, I, iCount : Integer;
begin
  for K := iStart to iEnd do
  begin
    iCount := 0;
    for I := 2 to iEnd do
    begin
      if K mod I = 0 then
      begin
        Inc(iCount);
      end;
    end;
    if iCount = 1 then
    begin
      memData.Lines.Add(IntToStr(K));
    end;
  end;
end;
如果你把任务分解成只执行一项任务的小块,生活就会变得容易得多。从测试数字是否为素数的函数开始

function IsPrime(N: Integer): Boolean;
var
  M: Integer;
begin
  Assert(N > 0);
  if N = 1 then // annoying special case
  begin
    Result := False;
    exit;
  end;
  for M := 2 to (N div 2) do
  begin
    if N mod M = 0 then
    begin
      Result := False;
      exit;
    end;
  end;
  Result := True;
end;
现在,您可能希望创建一个包含素数的列表:

var 
  Primes: TList<Integer>;
  N: Integer;
....
// create Primes
for N := 1 to 10000 do
  if IsPrime(N) then
    Primes.Add(N);
var
素数:TList;
N:整数;
....
//创建素数
对于N:=1到10000 do
如果是IsPrime(N),那么
素数。加(N);


这不是枚举素数的最有效方法。但这可能是您应该开始的地方,我写这个答案主要是为了鼓励您将代码划分为一些小的逻辑方法,这些方法可以完成特定的重点任务

这不是您尝试的实际代码。至少,这里有输入错误(变量
aprime
不能通过键入
apriem
来引用),但事实上,您并不是简单地复制和粘贴代码,这使得其中也有可能存在其他错误,而这些错误在您的原始版本中并不错误。除此之外,“这似乎不起作用”是什么意思?它不编译吗?它会给出错误的结果吗?它是否引发了一个例外?你知道它在哪一点出错了吗?如果代码有一些注释就好了。至少记录方法(筛子等)检查除数从2到n的第2部分。如果你找不到它,它就是素数。使用n mod m=0测试除数。请将您的代码格式化为可读。调试应包括等待,直到您有一个已知的素数,并查看是什么除数导致您的代码将其检测为非素数。(由于
j
在最初的内部循环迭代中被增加到
1
,我认为它看到所有的数字都可以被1整除。)如果您感兴趣,我最后一次尝试素数(它的功能与您的代码类似)是:这不是您尝试的实际代码。至少,这里有输入错误(变量
aprime
不能通过键入
apriem
来引用),但事实上,您并不是简单地复制和粘贴代码,这使得其中也有可能存在其他错误,而这些错误在您的原始版本中并不错误。除此之外,“这似乎不起作用”是什么意思?它不编译吗?它会给出错误的结果吗?它是否引发了一个例外?你知道它在哪一点出错了吗?如果代码有一些注释就好了。至少记录方法(筛子等)检查除数从2到n的第2部分。如果你找不到它,它就是素数。使用n mod m=0测试除数。请将您的代码格式化为可读。调试应包括等待,直到您有一个已知的素数,并查看是什么除数导致您的代码将其检测为非素数。(由于在最初的内部循环迭代中,
j
被增加到
1
,我认为它看到所有的数字都可以被1整除。)如果你感兴趣,我最后一次尝试素数(与你的代码类似)是这样的:你的答案真的帮助了我,谢谢你,我很抱歉,我一直忘了我可以写自己的程序,函数等等。我很高兴它有帮助。将代码分解为可重用的小片段是非常重要和强大的。“for m:=2 to(n div 2)do”循环应该是“for m:=2 to sqrt(n)do”。@不,这样就可以了。我宁愿避免浮点运算。整数sqrt将是一个很好的转折点。浮点不能很好地处理for循环。不如
Floor(Sqrt(N))
好吗?你的回答真的帮了我的忙,谢谢你,我很抱歉,我一直忘了我可以自己写程序、函数等等。我很高兴这对我有帮助。将代码分解为可重用的小片段是非常重要和强大的。“for m:=2 to(n div 2)do”循环应该是“for m:=2 to sqrt(n)do”。@不,这样就可以了。我宁愿避免浮点运算。整数sqrt将是一个很好的转折点。浮点不能很好地处理for循环。不如改为
地板(Sqrt(N))
procedure TForm1.btnprimeClick(Sender: TObject);
var K, I, iCount : Integer;
begin
  for K := iStart to iEnd do
  begin
    iCount := 0;
    for I := 2 to iEnd do
    begin
      if K mod I = 0 then
      begin
        Inc(iCount);
      end;
    end;
    if iCount = 1 then
    begin
      memData.Lines.Add(IntToStr(K));
    end;
  end;
end;