C中子序列的原始性测试

时间:2015-11-24 18:50:51

标签: c

我想打印子序列不是素数的所有素数。例如881是可接受的数字(8,8,81,81,88,1不是素数)但109是不可接受的(1,0, 9,10,19..19是素数)。我通过使用掩码找到每个数字的子序列。所以这里的问题是我找不到分别检查每个数字的子序列的方法。我无法存储我的子序列,因为我不应该使用数组或函数。你可以给我一个建议吗?我是一个C begginer.Thanks提前!

#include <stdio.h>

#define MAXNUMB 100

int main (void) 
{
    int i,j,x,l,mask,max=1,mult,sub,c;
    for (i = 11 ; i < MAXNUMB; i += 2 ) {
       //
        for (j = 3; j * j <= i; j += 2) {  
           if (i % j == 0) { 
               break; 
           }           
        }
        if (j * j > i) {

            int length = 0;
            int tmp=i;
            while (tmp != 0) {
                tmp /= 10;
                length++;
            }


           for (x=1;x<length*2;x++) {
              mask=x;
              mult=1;
              sub=0;
              int num=i;
              while ( num != 0 ) {
                  if ( mask % 2 == 1 ) {
                      sub += num % 10 * mult;
                      mult *= 10; 
                   }
                   num /= 10;
                   mask /= 2;

                }
           //the problem is here.If we use a printf command for the subsequences printf("%d \n,sub); it runs perfectly


                int k=sub;

                for (l = 2; l * l <= k; l ++) {  
                    if (k % l == 0) { 
                    printf("%d \n",i);
                    break; 
                   }           
                }   


            }


        }


    }
    return 0;
}

1 个答案:

答案 0 :(得分:2)

当他们使用子程序时,我发现这样的事情更容易理解。 例如,对于从11到MAXNUMB的每个整数,您必须确定整数是否具有任何素数子序列。所以写一个函数int hasPrimeSubsequence(int value)。在此函数中,您需要查看每个子序列并确定它是否为素数。所以写一个函数int isPrime(int value)

因为计算数字的子序列是非常重要的, 我甚至会写一个函数 int getSubsequenceOfNumberUsingMask(int value, int mask)。 函数int getMaximumMask(int value)也很方便。

hasPrimeSubsequence的实现如下:

/* Returns 1 if the value has a prime subsequence, 0 if it does not. */
int hasPrimeSubsequence(int value)
{
  int has_found_prime = 0;
  int maximum_mask    = getMaximumMask(value);
  for (mask = 1; mask <= maximum_mask; ++mask )
  {
    int subsequence = getSubsequenceOfNumberUsingMask(value, mask);
    if (isPrime(subsequence))
    {
      /* We found a prime subsequence, so the answer is "yes". */
      has_found_prime = 1;
      break;
    }
  }

  return has_found_prime;
}

请注意,当我们按值将数字传递给子程序时, 子程序可以随心所欲地处理这些值 (如mask /= 2之类的东西)而不会影响调用者的值, 所以我们不必制作这么多不同名称的数字副本。

变量has_found_prime是您如何跟踪变量的 子序列是素数。它从0(假)开始,因为我们没有 发现了任何主要的后续序列(我们甚至还没找过一个)。 但如果子序列的任何是素数,我们设置has_found_prime = 1 (true)我们从未将其设置回0

另一种实现方式甚至不打扰 变量has_found_prime;如果你找到一个素数,只需立即返回1, 如果你在没有返回1的情况下到达函数的末尾,那么就没有素数子序列,你返回0。 但是有些人不喜欢那种风格。

你可能会注意到hasPrimeSubsequence的这种实现 在开始之前不测试输入值是否为素数 尝试面具。那是因为我假设最后一个面具会选择全部 原始数字的数字,即数字本身 其中一个子序列。如果你发现这不起作用,那么你 要做的是在for循环之前插入这样的东西 (甚至更好,在你实际呼叫getMaximumMask之前):

  if (isPrime(value))
  {
    has_found_prime = 1;
  }

添加了备注:您显然应该在此处使用的“掩码” 被视为二进制数,其二进制位数与您想要的数字中的小数位数相同 提取子序列(我将其称为“输入值”)。

每个掩码从输入值中选择一个子序列; 掩码的每个位确定是否对应 输入值的十进制数字包含在该子序列中。 例如,如果输入值是1237,那么只有最不重要 使用掩码的四位,

掩码0001(二进制)选择子序列7,

掩码0010(二进制)选择子序列3,

mask 1000(binary)选择子序列1,

掩码1011(二进制)选择子序列137,依此类推。

使用四位的最高值掩码是二进制1111, 这是1小于2到4的幂。 该掩码选择 all 四位输入值的数字。

通常,如果输入值的长度为N个十进制数字,则最大可能的掩码为2,增加到N次幂,减去1。 这也是可能的子序列的数量 (不包括空子序列,根本不包含任何数字)。

如果你不尝试从1到2的每个掩码(2到N次幂,减1), 包括的, 然后你没有尝试所有的后续序列,你可能得到一个错误的答案 (猜测这个数字实际上没有素数子序列)。

只需尝试从1到length(位数)的掩码值, 甚至高达2*length,几乎总是错误的。

评论提示类似

  for (mask = 1; mask < (1 << length); ++mask)

这样可行,因为(1 << length)是2 length幂, 并且使用<实际尝试的最后一个掩码比这少1。 我仍然发现,如果你创建一个变量,它会使代码更易读 有一个合理的不言自明的名称,如 maximum_maskend_of_masks,并设置该变量以便循环 运行次数恰到好处。