当前位置:   article > 正文

一维数组——找素数_3、统计数组中素数的个数

3、统计数组中素数的个数

【问题描述】

编写程序,从任意n个数中找出素数,计算素数之和,并按从大到小顺序排序。

【输入形式】

输入分2行:第一行为n的值,第二行为n个整数;

【输出形式】

输出分2行:第一行为素数之和,第二行为素数排序结果。

【样例输入】

5

1 3 5 2 0

【样例输出】

10

5 3 2

【样例说明】

数列1、3、5、2、0中的素数是3、5、2,它们的和是10,对它们从大到小排序,结果是5 3 2

解析

这道题目思路非常清晰,就是先找到所有的素数,然后再进行排序。找素数,很简单,这里不再赘述。
接下来粗略地讲一讲一些常见的两种排序:冒泡排序、选择排序。由于还不太会做动画,我只能简单讲一讲他们的优劣。

1. 冒泡排序
冒泡排序可以说是每个初学者都要学的排序,其原理很简单:就是每一个元素都跟他它相邻的元素进行比较,如果不符合要求就交换位置。
其核心代码为:

for(int i=1;i<=num-1;i++)//num是数组f中元素的个数
		for(int j=1;j<=num-i;j++)
			if(f[j]<f[j+1])
				swap(f[j],f[j+1]);
  • 1
  • 2
  • 3
  • 4

当然,if语句中是大于号还是小于号,根据题目情况而定。

也许有人会问,为什么j循环的右边界是(num-i)?
其实很简单。就一次一次循环来进行分析。
以num=7为例:

初始5264137
第一次循环i=15642371
第二次循环i=26543721
第三次循环i=36547321
第四次循环i=46574321
第五次循环i=56754321
第六次循环i=67654371

可以观察出两个规律:
1)在第六次的时候,排序已经结束了;
2)对于任意次循环i=C(C是常数),数组里最后C个元素的排序都是对的。换句话说,当在任意次循环i=C时,只需要对前面(num-C)个数进行冒泡排序即可。而又判断条件是f[j]<f[j+1],故j循环只需要到(num-i);

那么,对于本题而言,冒泡排序的代码如下:

#include<iostream>
using namespace std;
const int N=10002;
int n,a[N],num,f[N],sum;
bool b;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		b=1;
		for(int j=2;j<=a[i]/j;j++)
			if(a[i]%j==0)
			{
				b=0;
				break;
			}
		if(b&&a[i]>1)
		{
			sum+=a[i];
			f[++num]=a[i];
		}
	}
	cout<<sum<<endl;
	for(int i=1;i<=num-1;i++)
		for(int j=1;j<=num-i;j++)
			if(f[j]<f[j+1])
				swap(f[j],f[j+1]);
	for(int i=1;i<=num;i++) cout<<f[i]<<" ";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

也可以这么写:(同样属于冒泡排序,只不过是先排好前面的数)

#include<iostream>
using namespace std;
const int N=10002;
int n,a[N],num,f[N],sum;
bool b;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		b=1;
		for(int j=2;j<=a[i]/j;j++)
			if(a[i]%j==0)
			{
				b=0;
				break;
			}
		if(b&&a[i]>1)
		{
			sum+=a[i];
			f[++num]=a[i];
		}
	}
	cout<<sum<<endl;
	for(int i=1;i<=num-1;i++)
		for(int j=i+1;j<=num;j++)
			if(f[i]<f[j])
				swap(f[i],f[j]);
	for(int i=1;i<=num;i++) cout<<f[i]<<" ";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

2. 选择排序
选择排序应该是继冒泡排序之后,初学者学习的第二种排序方法。其原理是依次找到最大的,然后放在相应的位置上。
核心代码如下:

for(int i=1;i<=num-1;i++)
	{
		maxx=i;
		for(int j=i+1;j<=num;j++)
		 if(f[j]>f[maxx])
		  maxx=j;
		swap(f[i],f[maxx]);
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这道题用选择排序做的全部代码是:

#include<iostream>
using namespace std;
const int N=10002;
int n,a[N],num,f[N],sum,maxx;
bool b;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		b=1;
		for(int j=2;j<=a[i]/j;j++)
			if(a[i]%j==0)
			{
				b=0;
				break;
			}
		if(b&&a[i]>1)
		{
			sum+=a[i];
			f[++num]=a[i];
		}
	}
	cout<<sum<<endl;
	for(int i=1;i<=num-1;i++)
	{
		maxx=i;
		for(int j=i+1;j<=num;j++)
		 if(f[j]>f[maxx])
		  maxx=j;
		swap(f[i],f[maxx]);
	}
	for(int i=1;i<=num;i++) cout<<f[i]<<" ";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

两种排序方法的时间复杂度均为O(n2)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/328757
推荐阅读
相关标签
  

闽ICP备14008679号