一.埃氏筛法求素数
思想:将2到n范围内的整数写下来,其中2是最小的素数。将表中所有的2的倍数划去,表中剩下的最小的数字就是3,它不能被更小的数整除,所以3是素数。再将表中所有的3的倍数划去……以此类推,如果表中剩余的最小的数是m,那么m就是素数。然后将表中所有m的倍数划去,像这样反复操作,就能依次枚举n以内的素数,这样的时间复杂度是O(nloglogn)。
1.要设置两个数组
int prime[maxn]; //保存素数
int is_prime[maxn]={0}; //is_prime判断是否为素数,元素全部赋值为0为了标志。
1:标志着这个数是i的倍数。
2.Find_prime里的操作:
1)int p=0为prime[]数组的下标
2)for循环从i=2开始,进去时要判断is_prime[i]是素数(即is_prime[i]==0),
是则保存到prime[p]=i;
紧接着for循环(j=2*i;j<maxn;j+=i),标志is_prime中的i的倍数为1(使其不被prime保存)
int Find_prime()
{
int i,j;
int p=0;//p为prime[]数组的下标
for(i=2;i<maxn;i++){
if(is_prime[i]==0){//is_prime[i]对应着数字i
prime[p]=i;//保存的素数从2开始
p++;
}
for(j=2*i;j<maxn;j+=i){
is_prime[j]=1;
}
}
return p;//返回prime数组的下标,main()里好输出
}
3.输入的数不包括0(例:1——100)
代码完全一样!自己取prime[0]={0,......}
#include <iostream>
using namespace std;
#define maxn 101 //包括0
int prime[maxn];//保存素数
int is_prime[maxn]={0};//判断是否为素数
int Find_prime()
{
int i,j;
int p=0;//p为prime[]数组的下标
for(i=2;i<maxn;i++){
if(is_prime[i]==0){//is_prime[i]对应着数字i
prime[p]=i;//保存的素数从2开始
p++;
}
for(j=2*i;j<maxn;j+=i){
is_prime[j]=1;
}
}
return p;//返回prime数组的下标,main()里好输出
}
int main()
{
int p=Find_prime();
for(int i=0;i<p;i++){
cout<<prime[i]<<' ';
}
return 0;
}
二.快速排序
1.思想:每次排序的时候设置一个基准点(选择最左边的第一个数字),将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。
2.注意:
1)必须有递归的边界条件,否则跳不出函数!!
2)当基准数选择最 左 边的数字时,那么就应该先从 右 边开始搜索
【因为最后要停在数值小的i上,然后与基准数交换。如果先从左边搜索,最后i==j时停在比基准数大(因为右边是搜索大于基准数的数)的位置,再基准数交换,这样数值大的i就被放在前面了】
#include <iostream>
using namespace std;
void QuickSort(int left,int right,int *a)
{
if(left>=right) return;//递归边界条件 (因为最后只剩一个元素,left=0,right=-1)
int i,j,base,temp;
i=left,j=right;
base = a[left];
while(i<j){
while(a[j]>=base&&i<j) j--;
while(a[i]<=base&&i<j) i++;
if(i<j){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
a[left] = a[i];//交换a[left]与基准数
a[i]=base;
QuickSort(left,i-1,a);
QuickSort(i+1,right,a);
}
int main()
{
int a[]={34,65,12,43,67,5,78,10,3,70};
QuickSort(0,9,a);
for(int i=0;i<9;i++){
cout<<a[i]<<" ";
}
return 0;
}
3.对比冒泡排序法、选择排序法
1)冒泡排序法:相邻元素两两比较,每次可确定一个最值。
for(i=1;i<n;i++) //外循环控制排序趟数,n个数排n-1趟
{
for(j=0;j<n-i;j++) //内循环每趟比较的次数,第j趟比较n-i次
{
if(a[j]>a[j+1]) //相邻元素比较,逆序则交换
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
2)选择排序法:每趟选出一个最值,确定其在结果序列中的位置
for(i=0;i<n;i++)
{
min=i; //把每次循环的第一个数作为最小值
for(j=i+1;j<n;j++)
{
if(a[min]>a[j]) //若后面的数j更小,则记住此时j的下标
min=j;
}
if(min!=i) //说明第一个数不是最小数,所以将a[i]和a[j]交换位置
{
t=a[min];
a[min]=a[i];
a[i]=t;
}
}
三.将M进制的数X转换为N进制输出(修改!!输入字母的情况)
#include<iostream>
#include<math.h>
using namespace std;
int main(){
int n,i,k,temp;
double oct,m,j;
char x[1111];
cin>>m>>n>>x;
char num[1111];
for(i=0;x[i]!='\0';){//x有多少位
i+=1;
}
for(j=i-1,k=0;j>=0;k++,j--){//转换为十进制
if(x[k]<=90&&x[k]>=65) x[k]-=55;//若输入大写字母
if(x[k]<=122&&x[k]>=97) x[k]-=87;//若输入小写字母
oct+=x[k]*pow(m,j);
}
k=0;
for(i=0;oct>0;i++){
temp=(int)oct%n;//十进制取余结果
if(temp>=10){
num[i]=temp+55;//转为对应大写字母
oct=(oct+55-num[i])/n;
}
else {
num[i]=temp+48;//转为ascii对应数值 0=48
oct=(oct+48-num[i])/n;
}
k++;
}
k=k-1;
for(;k>=0;k--){
cout<<num[k];
}
return 0;
}
四.给出年分m和一年中的第n天,算出第n天是几月几号
1.闰年判定:能被400整除,或者能被4整除但不能被100整除。
if( year%400==0 || (year % 4 == 0 && year % 100 != 0) )
闰年平年区别:闰年2月份有29天,平年2月份28天。
2.c++中不能遍历enum中的所有值。
要遍历所有值,首先想到用数组
#include <iostream>
using namespace std;
int Run(int m)
{
int flag=0;
if(m%400==0||(m%4==0&&m%100!=0)) flag=1;
return flag;
}
void jisuan(int *a,int n)
{
int i,surply=0,sum=0;
for(i=0;i<12;i++){
sum+=a[i];
if(n-sum<0){
surply=n-(sum-a[i]);
i=i-1;
cout<<i+2<<"月"<<surply<<"号";
break;
}
else if(n-sum==0){
surply = a[i];
cout<<i+1<<"月"<<surply<<"号";
break;
}
}
}
int main()
{
int a[]={31,29,31,30,31,30,31,31,30,31,30,31};
int m,n,flag;
cin>>m>>n;
flag=Run(m);
if(flag){
jisuan(a,n);
}
else{
a[1]=28;
jisuan(a,n);
}
return 0;
}
五.输入一个计算值表达式求值
1.注意:1)题目输入要求:整数和运算符之间用一个空格分隔。
2)理解输入的思想
2.c++怎么输入空格?