【问题标题】:Program to find prime numbers in MATLAB在 MATLAB 中查找素数的程序
【发布时间】:2019-07-24 14:42:01
【问题描述】:

按照维基百科上的伪代码,我编写了一些代码来显示 2 和用户选择的数字之间的质数。我不确定为什么这不起作用,因为我在 Erastothenes 的筛子之后的增量是正确的。请帮帮我。

我尝试过更改边界,但这不起作用。

没有错误,但它返回错误的输出。如果我输入 10,它会返回 2、3、4、5、6、7、8、9、10。

n=input("Enter an upper limit: ");
nums= 2:n;
p=2;
for i = p:sqrt(n)
    for j = (i^2):i:sqrt(n)
        nums(j) = 0;
    end
end
for k = 1:n-1
    if nums(k) ~= 0
        disp(nums(k))
    end
end

【问题讨论】:

  • edit把“不工作”的问题说清楚,结果是不是错了,会不会导致错误,会不会让你的电脑爆炸……?
  • j 循环需要一直到 n 而不是 sqrt(n) 否则此代码如何检查数字 > sqrt(n) 是否可以除以已经找到的素数? nums 也是从 2 而不是 1 开始的,所以你应该写 nums(j-1) = 0;

标签: matlab for-loop primes


【解决方案1】:

您可以为此使用 MATLAB 中的 primes 函数

N = 10;        % upper limit
p = primes(N); % List of all primes up to (and including) N

少一步自动化,您可以使用另一个内置的isprime

p = 1:N;                  % List of all numbers up to N
p( ~isprime( p ) ) = [];  % Remove non-primes

最后,我们可以在不使用内置函数的情况下处理您的代码! 我假设您指的是this pseudocode 维基百科上的埃拉托色尼筛。

 Input: an integer n > 1.

 Let A be an array of Boolean values, indexed by integers 2 to n,
 initially all set to true.

 for i = 2, 3, 4, ..., not exceeding √n:
   if A[i] is true:
     for j = i2, i2+i, i2+2i, i2+3i, ..., not exceeding n:
       A[j] := false.

 Output: all i such that A[i] is true.

我会一步一步来,指出你的代码的不同之处:

n = 10;
A = [false; true(n-1,1)];   % array of true Booleans, first element (1) is not prime
% But I've included a first element to make indexing easier.
% In your code, you were using index 'i' which was incorrect, as your array started at 2.
% Two options: (1) take my approach and pad the array
%              (2) take your approach and using indices i-1 and j-1
for ii = 2:sqrt(n)
    if A(ii) == true        % YOU WERE MISSING THIS STEP!
        for jj = ii^2:ii:n   % YOU ONLY LOOPED UNTIL SQRT(n)!
            A(jj) = false;
        end
    end
end

p = find(A);
disp(p)

这会输出预期值。

请注意,在手动循环方法的末尾,A 等同于 isprime(1:n),反映了我之前的建议。

【讨论】:

    【解决方案2】:

    你的代码有两个错误:

    1. 应检查倍数直到n 而不是sqrt(n)

    2. 由于您的 nums 向量以 2 而不是 1 开头,如果您想 访问您需要使用的正确值nums(j-1) = 0

    所以:

    n=100
    nums= 2:n;
    p=2;
    for i = p:sqrt(n)
        for j = (i^2):i:n
            nums(j-1) = 0;
        end
    end
    for k = 1:n-1
        if nums(k) ~= 0
            disp(nums(k))
        end
    end
    

    注意到您可以使用模数跳过一个 for 循环,它可能不会比以前的解决方案快,因为此代码创建了一个包含已找到的每个素数的逻辑索引。

    n   = 100
    nums= 2:n;
    
    for i = 2:sqrt(n) 
        nums(mod(nums,i)==0 & nums != i) = [];
    end
    
    nums.'
    

    我只是删除了nums中可以除以x但不能除以x的值。

    【讨论】:

    • "Optimise" 在这里被自信地使用,我不确定调用 mod 实际上会比直接索引数组元素更快...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 2022-10-14
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多