CodeSky 代码之空

随手记录自己的学习过程

C 关于素数的两道题和相关算法

2014-03-08 20:50分类: C评论: 2

这道题目有点意思。 1.如果一个数是素数,则指出是素数,否则写出因数。 2.输入一个整数,显示所有小于等于该数的素数。

首先明确什么是素数再说,实际上概念我忘得差不多了:

質數,又称素数,指在大於1的自然数中,除了1和此整数自身外,無法被其他自然数整除的数(也可定義為只有1和本身两个因数的数)。

先看看第一题的源码:

1#include <stdio.h>
2#include <stdbool.h>
3
4int main(void)
5{
6    unsigned long num;
7    unsigned long div;
8    bool isPrime;
9
10    printf("Please enter an integer for analysis: ");
11    printf("Enter q to quit.\n");
12    while (scanf("%lu", &num) == 1) {
13        for (div = 2, isPrime = true; (div * div) <= num; div++) {
14            if (num % div == 0) {
15                if ((div * div) != num)
16                    printf("%lu is divisible by %lu and %lu.\n", num, div, num / div);
17                else
18                    printf("%lu is divisible by %lu.\n", num, div);
19                isPrime = false;
20            }
21        }
22        if (isPrime)
23            printf("%lu is prime.\n", num);
24        printf("Please enter another integer for analysis: ");
25        printf("Enter q to quit.\n");
26    }
27    printf("Bye.\n");
28    return 0;
29}
30

这里用到了几个新知识,第一是<stdbool.h>引出bool(否则的话在C99也是能用_Bool的)但是平时没有必要,因为布尔型在日常应用中几乎没有人会特地使用。然后我们就能用truefalse了。

然后再来看一个有意思的:(div * div) <= num 这里这么定义可能会有点不理解,但实际上,可以看作把num开根号了,换句话说就是对半开,因为公约数其实是对称情况,这一点我们可以看看,输入144:

144 is divisible by 2 and 72.
144 is divisible by 3 and 48.
144 is divisible by 4 and 36.
144 is divisible by 6 and 24.
144 is divisible by 8 and 18.
144 is divisible by 9 and 16.
144 is divisible by 12.

所以我们只要运算到一半(开根)就行了,这样执行效率快了一倍(这就是效率问题了)另外if ((div * div) != num)使得相同的公约数不会重复输出。

scanf("%lu", &num) == 1在以前曾经介绍过:C 一个程序说说scanf()判断如果数值类型不对应,它是无法成功读取的,如果是%d 而输入则是123A那么在A处会停止。

那么第二道题其实类似,只是加了一层嵌套而已。

1/* Programmming Exercise 7-9 */
2#include <stdio.h>
3#define NO 0
4#define YES 1
5int main(void)
6{
7   long num;                      /* value to be checked */
8   long div;                      /* potential divisors  */
9   long lim;                      /* limit to values     */
10   int prime;
11
12   printf("Please enter limit to values to be checked; ");
13   printf("Enter q to quit.\n");
14   while (scanf("%ld", &lim) == 1 && lim > 0)
15   {
16         for (num = 2; num <= lim; num++)
17         {
18          for (div = 2, prime = YES; (div * div) <= num; div++)
19             if (num % div == 0)
20                prime = NO;           /* number is not prime  */
21          if (prime == YES)
22             printf("%ld is prime.\n", num);
23      }
24      printf("Please enter another limit; ");
25      printf("Enter q to quit.\n");
26   }
27   return 0;
28}
29

评论 (1)

lujjjh2014年3月12日 14:55

一个数是没有公约数的啊喂,是想说列出所有的因数么?

敖天羽2014年3月12日 16:01

咦好像是这个意思吧