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;
}