我想打印子序列不是素数的所有素数。例如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;
}
答案 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_mask
或end_of_masks
,并设置该变量以便循环
运行次数恰到好处。