回文数的判断

首先第一个,回文数
定义:正着念倒着念都一样的数。比如121。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
main()
{
int num,copy,target=0;
scanf("%d",&num);
copy = num;
while(num != 0)
{
int digit= num % 10;
target = target*10+digit;
num /= 10;
}

if(target == copy) printf("is huiwen");
}

核心思路是把输入数值颠倒过来,然后比较原来的和颠倒后的值是否相等。如果相等,那就是回文数。
其中关键的是如何把数字倒过来:
比如给到数据是123
首先取个位num % 10的余数是3(注意要新建一个变量存,千万别放原始数变量num里)。
然后把它当作目标,乘10变成30,把3推到首位,留出后续数字的空间(30里的那个0,代表下一个数目前还是0)
最后除以10,把原来的数个位消掉。这样回到开始取到的下一个个位就是2了。
循环往复,直到原始数被“耗光”(变成0)这样target里面装的就是我们颠倒后的数了。

因为我们需要和原来的数进行比较,所以在开始前我们需要先备份原数(copy = num)。

水仙花数的判断

水仙花数其实就是给定一个数,每一位的位数次方的和为给定的数本身。
编程实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <math.h>
main()
{
int num,copy,copy2,target=0,n=0;
scanf("%d", &num);
copy = num;
copy2 = num;
while(copy != 0)
{
copy /= 10;
n++;
}
while(num != 0)
{
int digit = num % 10;
target = target + pow(digit, n);
num /= 10;
}

if(copy2 == target) printf("is shuixianhuashu");
}

这个比回文数那个要难上一点。核心思路是先算输入的数一共有多少位,再把每一位指数运算并相加,最后判断原数是不是等于操作完成的数。
计算位数其实就是删个位,然后计数器n累加,直到删光。这时候计数器n里的值就是输入数的位数了。
下面,还是之前的取个位算法,然后就是求方计算和。最后也是通过删个位来移动所操作的数的。

可以看到我们复制了两次输入的数值,是因为其中一份被拿来计算位数,另一份拿来比对了。

素数判断

素数是一个大于1的数,除了它本身和1之外 不能再被任何其他数整除 的数。1不是素数
编程实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
main()
{
int num,i;
scanf("%d", &num);
if(!(num <= 1))
{
for(i=2;i<num;i++)
{
if(num % i == 0)
{
printf("not sushu");
return;
}
}
printf("is sushu");
} else {
printf("not sushu");
}
}

这里输入一个数,然后判断它如果不是1或者负的再进行判定,如果是1或者比1小那就不是素数,立刻结束;
判定过程是对比输入数小,比1大的数能不能和输入数整除(从2开始,2是最小的素数)。如果可以,那么不是素数;如果跑完了都没有能整除的那就是素数,否则就不是。

这里其实还有一个可以优化的点。如果输入的数足够大的话挨个遍历会慢,于是我们可以用sqrt(num)来求它的算术平方根。假如输入25,那五五二十五,跑到5就能知道它不是素数了,后面的就都无意义了,极大地减少了比对次数,节省蒜粒(算力)。

单行文本输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
main()
{
char c,n=0;
int flag=0,start=1;
while((c = getchar()) != '\n')
{
if(c == ' '){
if(flag && !start) {
n++;
flag=0;
}
} else {
flag=1;
if(start)
{
start=0;
n++;
}
}
}
if(flag==0 && n!=0) n--;
printf("%d",n);
}

这个程序的功能是输入一行文本,输出被空格隔开的“单词”数。
我用了两个标识位(flag和start)来进行状态判定实现的。
首先通过while获得一串字符,回车作为结束符。起始start变量为1表示刚开始键入文本。
循环内:
开头判断是空格,如果前面键入的是其他字符(flag==1)并且不在起始状态(防止开头敲一堆空格)就给计数器加一。
判断不是空格,是其他字符,设置标识位flag为1,判断如果是起始状态就把起始状态取消并给计数器加一(这里刚开始输入的是字符而不是空格,不做这一步会少统计一个)
直到输入换行,结束获取字符的循环。
在循环外,有一个边界判断。如果输入完字符后在末尾敲一个空格(flag=0)并 不再输入其他字符 再回车(退出循环)的话就会多统计一个(因为单词计数器增加是在敲空格的时候触发的,最后没有任何字符存在)。
于是在这里判断一个flag==0的时候把多的减回去就对了(前提是n不能为0,也就避开了开头连续空格导致减成负数的问题)。
应该会有更好的写法,这里只是我的想法。