素数:一个数,如果只有1和它本身两个因数,那么这样的数叫做素数
合数:一个数,如果除了1和它本身还有别的因数,那么这样的数叫做合数
输入
20
输出
4
程序要实现的功能:输出不超过20的相邻且差为2的素数对的个数
大体分析:
(1)找到不超过20的素数
(2)找出相邻且差值为2的素数对
具体步骤
(1)找到不超过20的素数
对于素数的存储,选择用链表结构,在不知道存储数组大小的情况下,使用链表结构能节省存储空间。
struct node{
int data;
node* next;
};
①生成初始链表
我们知道,2是最小的素数,那么2的倍数就是合数,即不是素数,利用这一点,生成初始链表
void passEven(node *p,int n){
int i = 2,j;
node *p1;
for(j = i + 1;j <= n;j++){
if(j % i != 0){
p1 = new node;
p1->data = j;
p1->next = NULL;
p->next = p1;
p = p1;
}
}
}
此时链表中的结点如下所示
②遍历初始链表
我们先看一组初始链表
发现了没,我们只要循环√n次,就可以剔除其他的合数,形成一个只有素数的链表。
遍历初始链表需要借助3个指针,p,p1,p2,比如,当p指向3的时候,p1去遍历3后面的结点,当p1指向9时
此时p1->data % p->data == 0
,所以我们要释放指针p1指向的结点,如下图所示
释放完结点后,p1=NULL
,我们要让p1 = p2->next
,然后继续遍历
遍历初始链表的函数为
void traverse(node *p,int n){
node *p2,*p1;
while(p->data < sqrt(n)){
p2 = p->next;
p1 = p2->next;
p = p2;
while(p1){
if(p1->data % p->data != 0){
p2 = p1;
p1 = p2->next;
}
else{
p2->next = p1->next;
p1->next = NULL;
delete p1;
p1 = p2->next;
}
}
}
}
③删除结点
执行完程序后,我们需要用delete运算符删除结点,防止结点占用自己的存储空间。
void delNode(node *p){
node *p1;
while(p->next != NULL){
p1 = p->next;
p->next = p1->next;
p1->next = NULL;
delete p1;
}
delete p;
}
(2) 找出相邻且差值为2的素数对
这一步,我们直接遍历链表找差值即可
void PrimeArray(node *p){
int k= 0;
node *p1;
p1 = p->next;
while(p1){
if(p1->data - p->data == 2)
k++;
p = p1;
p1 = p->next;
}
cout<<k<<endl;
}
在主函数的中的调用过程如下
int main(){
int n;
node *head;
cin>>n;
head = new node;head->data=2;head->next=NULL;
passEven(head,n);//生成初始链表
traverse(head,n);//遍历链表
PrimeArray(head);//素数对猜想
delNode(head);//释放结点
}
完整的代码如下
#include<iostream>
#include<cmath>
using namespace std;
struct node{
int data;
node* next;
};
//过滤掉2的倍数,生成链表
void passEven(node *p,int n){
int i = 2,j;
node *p1;
for(j = i + 1;j <= n;j++){
if(j % i != 0){
p1 = new node;
p1->data = j;
p1->next = NULL;
p->next = p1;
p = p1;
}
}
}
//遍历结点
void traverse(node *p,int n){
node *p2,*p1;
while(p->data < sqrt(n)){
p2 = p->next;
p1 = p2->next;
p = p2;
while(p1){
if(p1->data % p->data != 0){
p2 = p1;
p1 = p2->next;
}
else{
p2->next = p1->next;
p1->next = NULL;
delete p1;
p1 = p2->next;
}
}
}
}
//素数对猜想
void PrimeArray(node *p){
int k= 0;
node *p1;
p1 = p->next;
while(p1){
if(p1->data - p->data == 2)
k++;
p = p1;
p1 = p->next;
}
cout<<k<<endl;
}
//删除结点
void delNode(node *p){
node *p1;
while(p->next != NULL){
p1 = p->next;
p->next = p1->next;
p1->next = NULL;
delete p1;
}
delete p;
}
//创建一个结点
int main(){
int n;
node *head;
cin>>n;
head = new node;head->data=2;head->next=NULL;
passEven(head,n);//生成链表
traverse(head,n);//遍历链表
PrimeArray(head);//素数对猜想
delNode(head);//释放结点
}