2.今日收获(C语言)(高效筛素数)(倒序排数字)

1.用gets读取字符串后,有些时候不一定要用strlen求出字符串长度,用for循环遍历数组时这样写:for(int i=0;a[i]!='\0';i++)   //因为gets会自动在字符串后面加上'\0',遍历的时候只需要让a[i]不等于\0就行了。

2.如果有一个题给你一个字符串,让你把A到Z转换成1到26再相乘,可以先用gets读取,然后遍历的时候:sum*=(a[i]-'A'+1)    //sum类型是int,无需担心前后类型不同char类型是以ASCII码储存的。

3.如何在数组中表示质数(重点) :假如现在输入一个n,我要找2到n之间的质数

代码如下:

#include<stdio.h>
#include<math.h>
int main()
{
	int a[10010] = { 0 };
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	for (i = 2;i <= n;i++)
	{
		a[i] = 1;
	}
	for (i = 2;i <= sqrt(n);i++)
	{
		if (a[i] == 1)
		{
			int j = 0;
			for (j = i * i;j <= n;j+=i)
			{
				a[j] = 0;
			}
		}
	}
	for (i = 2;i <= n;i++)
	{
		if (a[i] == 1)
		{
			printf("%d ", i);
		}
	}
	return 0;
}

思路

对于一个数x,它可以写成x=q*p,其中q<=根号x,p>根号x。

把根号x当成一个分界点,2到x的所有数被分为两部分。

先把下标为2到下标为x(或n)的数组元素都初始化为1,这一步是假定这些元素对应的下标都是素数。

利用根号x,把2到x的所有数分为两部分。只需遍历第一部分,为什么?

因为我们可以用第一部分的素数去筛选第二部分的非素数。举个例子:2是素数吧,那2的倍数,4,6,8....一定不是素数,把下标为这些数的元素变成0,代表它们不是素数。剩下的那些本就是素数的下标就不用管他了。

在遍历第一部分的时候,只要这个 i 下标对应的元素是1,就说明 i 是素数,所以进入内循环,筛选出 i 的倍数的所有下标,把它们对应的元素变成0 。

但是在内循环中 j 是从i的平方开始的,为什么?

举个例子:假如此时i=5,那 i*2=10,但是“10”在之前 i=2 的时候就已经筛过了(2*5=10);i*3=15,但是“15”在之前 i=3 的时候就已经筛过了(3*5=15)....只有从 i*i 开始往后筛选时,才不会出现这种情况。并不是说必须从 i*i 开始往后筛,只是这样效率最高,避免重复无意义的筛选。

以根号x为分界点是非常非常关键的思路!!!

4.一道我思考了很久的题:把输入的数字反着输出,符号位置不变,最高位不能是0。

代码如下:

#include<stdio.h>
#include<string.h>
char a[10010];
int main()
{
    int start=0;
    scanf("%s",a);
    int l=strlen(a);
    if(a[0]=='-')
    {
        printf("-");
        for(int i=l-1;i>0;i--)
        {
            if(a[i]!='0'||start)  //直到找到第一个‘非0’,才能进入if语句,后面的0可以正常输出
            {
                printf("%c",a[i]);start=1;
            }
        }
    }
    else
    {
        for(int i=l-1;i>=0;i--)
        {
            if(a[i]!='0'||start)
            {
                printf("%c",a[i]);start=1;
            }
        }
    }
    if(!start)printf("0");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值