c语言常见小算法的解题思路
判定某一年是否是闰年
闰年时间:四年一闰,百年不闰,四百年再闰。,其中
大写字母转小写字母
大写字母+32 = 小写字母
A = 65
a = 97
输入一个华氏温度,要求输出摄氏温度。
计算公式为:
求方程的根。a,b,c由键盘输入,设。
一元二次方程的根为
求一天内表的指针的重合次数
可以只考虑12小时的情况,时针和分针重合时满足一下两条:
每分钟的度数×分钟数=每小时的读书×小时数(因为两针重合,故其度数一定相等)
小时-分钟数÷60=n (n为0到12的整数)
故有
12小时内重和11次(在12点重合两次只算一次)
故一天24小时内重合23次
判断m是否是素数。
让m被2到k=除,如果m能被2~k之中任何一个整数整除,则提前结束循环,此时i必然小于或等于k;如果m不能被2~k之间的任意整数整除,则在完成最后一次循环猴,i还要加1,因此i=k+1,然后猜种植循环。在循环之后判别i的值是否大于或等于k+1,若是,则表明未曾被2~k之间任意整数整除过,因此是素数。
约瑟夫问题
设有n个人围坐一圈,现从指定的第1个人开始报数,数到第m个人出列,然后从下一个人重新开始报数,数到第m个人又出列,。。。。如此重复,知道所有的人全部出列为止。
选用单循环链表做为存储结构,输入出列人的标号,
建立具有几个节点的单循环链表,其数据域值为生成结点时的顺序号。
用j计数扫描过的结点,当j = m-1 时,说明其直接后继结点就是出列结点,先输出其数据域值,再删除该结点,再从被删结点的下一个结点重新开始计数。如此重复上述步骤,知道仅剩最后一个结点,再将该结点出列。
设有n个元素进栈,请给出全部可能的出栈序列个数和不可能的出栈序列个数。
设全部可能的出栈序列个数为,则
对n个元素组成的序列,全部可能的排列数,所以不可能出栈序列的个数为
11.字符串的模式匹配:子串的定位运算。
一般将主串称为目标串s,子串称为模式串t,如果目标串s中能够找到模式串t,则模式匹配成功,否则不成功。
简单模式匹配算法:Brute-Force算法
从目标串s=”s0s1s2…sn-1”的第一个字符开始和模式串”t=t0t1…tm-1”中第一个字符比较,若相等,则继续逐个比较后续字符,否则从目标串s的第二个字符开始重新与模式串t的第一个字符进行比较(相当与模式串t整体向后移动一位字符)。
int index(Sstring s,Sstring t)
{
int i,j,m,n;
i = j = 0;
n = s.len; m = t.len;
if(n
while(( i < n )&& ( j < m))
{
if(s.data[i] == t.data[j]) {i++; j++}
else {i = i – j +1; j = 0;}
}
if(j>= m)return i-m+1;
else return o;
}
算法最多比较n-m+1 趟,总比较次数为 m*(n-m+1),最坏情况下时间复杂度为O(m*n)。由于目标串的指针要回溯,所以比较次数较大。
KMP算法
改进的模式匹配算法可使目标串的检测指针不必回溯。
模式串的回溯位置与s无关,由t自身就可以推出。
算法:
void Next(Sstring t, int next[])
{
int m = t.len;
int j = 0, k = -1;
next[0] = -1;
while( j < n )
{
if( k == -1 || t.data[j] == t.data[k] )
{ k++;
j++;
next[j] = k;
}
else k = next[k];
}
}
KMP算法的思想是:设设i和j分别指向目标串和模式串中正待比较的字符,i和
j的初值均为0。若有,则i和j分别增1再继续比较;否则,i不变,j改变为next[j](模式串右滑),再比较和。依次类推,直到出现以下两种情况:一种是j回退到 j = next[j] 的位置时有,则i和j分别增1再继续比较;另一种是j回退到j = -1 时,此时令目标串和模式串的下标各增1,即用和比较。
int KMPIndex ( Sstring s, Sstring t, int next[])
{
int i = 0, j = 0, n = s.len, m = t.len;
if (n < m ) return 0;
while ( i < n && j
{
if ( j == -1 || s.data[i] == t.data[j] ) { i++; j++; }
else j