目录
7.输入一个数字,使其从高位到低位依次输出,例如输入2563,输出2 5 6 3
14.求n+nn+nnn+...nn.n(n个n) (不考虑溢出)
17.给一个数组,封装两个函数一个进行初始化全0,一个进行打印
21.给两个int(32位)整数m和n的二进制表达,求其中有多少个位(bit)不同?
25.写一个函数判断一个字符串是否是另一个字符串旋转后的字符串
1.打印100-200之间的素数
试除法
思路:素数的定义是这个数字除了1和本身不能被整除,而且整数都可以写成c=a*b的形式,且有a或者b<=sqrt(c) (sqrt是开平方的意思),那么也就说判断sqrt(c)之前的数字如果能被整除,则说明不是素数,若是不能被整除,那么sqrt(c)后边的数字一定不能被整除,那么这个数字就是素数。
#include<stdio.h>
#include<math.h>//后边用到sqrt库函数
int main ()
{
int i=0;
int count =0;//用做后边用来计数
for (i=100;i<=200;i++) //要找到100到200之间的素数 首先要先生成100到200之间的数字
{
int j=0;
for (j=2;j<=sqrt(i);j++)//产生小于开平方i的数字
{
if (i%j==0)//在这里判断i除以j的余数 如果等于0 这说明整除了 那么不是素数 跳出循环
{
break;
}
}
if (j>sqrt(i))// 如果大于开平方i 则表明开平方i之前都没有数字能被整除 那么之后肯定也不会被整除 那么这个就是素数
{
count++;// 找到一个 计数一次
printf("%d ",i);
}
}
printf("\n");
printf("count=%d\n",count);//最后将计数次数也打印出来
return 0;
}
2.输出9*9乘法口诀表
思路:9*9口诀即
1*1=1
2*1=2 2*2=4
3*1 =3 3*2 =6 3*3 =9
... ...
9*1=9 9*2 =18 ...
可以看出列是从1到9,行也是从1到9,则可以分别用for循环来生成。
#include<stdio.h>
int main ()
{
int i =0;
for (i=1;i<=9;i++)//控制第一个因数 总共9行
{
int j=0;
for (j=1;j<=i;j++)//控制第二个因数
{
printf("%d*%d=%-2d ",i,j,i*j);//%2d是打印两位并且右对齐 位数不够用空格代替 %-2d左对齐
}
printf("\n");
}
return 0;
}
3.判断1000到2000年的闰年
思路:闰年法则为四年一闰,百年不闰,四百年在闰,故可遍历1000到2000的数字,是4的倍数同时不是100的倍数是闰年,或者是400的倍数也是闰年,这两个条件是或的关系。代码如下
#include<stdio.h>
int main ()
{
int year=0;
int count =0;
for (year=1000;year<=2000;year++)
{
if(year%4==0 && year%100!=0) //判断是4的倍数 并且不是100的倍数
{
printf("%d ",year);
count++;
}
else if (year%400==0)// 第二个判断规则 判断400的倍数
{
printf("%d ",year);
count++;
}
}
printf("\ncount=%d ",count);//计数看看共有多少闰年
return 0;
}
4.计算1!+2!+...+10!
思路:首先n!=n*(n-1)*(n-2)*..*2*1,因为每个因子都是连续的,且是1到10的阶乘,故可以用两层循环进行描述,代码如下:
过程为:第一次n=1,进入循环i=1,ret=1,ret=1*1,相当于计算1!;sum=0+1=1;
第二次n=2,进入循环i=1,ret=1,ret=1*1,1<2,再进入小循环i=2,ret=1*2,相当于计算2!;sum=1+2;
第三次n=3,进入循环i=1,ret=1,ret=1*1,1<2,再进入小循环i=2,ret=1*2,2<3继续进入小循环i=3,ret=2*3;sum=3+6;
.........
#include <stdio.h>
int main ()
{
int i=0;
int n=0;
int sum=0;
for (n=1;n<=10;n++)// 首先生成1到10的数字 给求n!传入参数
{
int ret=1;
for (i=1;i<=n;i++)
{
ret =ret*i;//这里可以计算n!但是n不能是太大的数字 否则会溢出 对于此题是可以的
}
sum =sum+ret;
}
printf("sum=%d\n",sum);
return 0;
}
5.二分查找
思路:比如从1 2 3 4 5 6 7 8 9 10中找到7,各个元素下标依次是0-9,能查到的情况在注释中说明的很清楚,主要说下查不到的条件:
如果是从1 2 4 5 6 7 8 9 10 11中查找3 情况如下
查找次数 | 左边元素下标(对应的数字) | 中间元素下标(对应的数字) | 右边元素下标(对应的数字) | 中间元素与3的大小关系 |
第1次 | 0(1) | 4(6) | 9(11) | > 在左边 |
第2次 | 0(1) | 1(2) | mid-1=3(5) | < 在右边 |
第3次 | mid+1=1(2) | 2(4) | 3(5) |
> 在左边 |
第4次 | 1(2) | 1(2) | mid-1=2(4) | < 在右边 |
第5次 | mid+1=2(4) | 1(2) | 2(4) | < 在右边 |
第6次 | mid+1=3(5) | 2(4) | 2(4) | >在左边 |
可以看出 从左边元素下标大于右边元素下标开始 就再也找不到了。
#include<stdio.h>
int main ()
{
int arr[]={1,2,3,4,5,6,7,8,9,10};
int sz =sizeof(arr)/sizeof(arr[0]);//计算元素个数
int left=0;//最左边的元素下标为0
int k=7; //假如是找7
int right =sz-1; //最右边的数下标为sz-1
while (left<=right) //这个等号不能少
{
int mid=(left+right)/2;//中间元素的下标
if(arr[mid]>k) //中间元素下标大于要查找的数字 说明数字在中间的左边 左侧数字下标不动 右侧下标比中间值减1
//这样就去掉右边一半
{
right=mid-1;
}
else if (arr[mid]<k)//中间元素下标小于要查找的数字 说明数字在中间的右边 右侧数字下标不动 左侧下标比中间值加1
//这样就去掉左边一半
{
left=mid +1;
}
else //上边两者都不满足 则说明就是这个中间元素
{
printf("找到了,下标是%d\n",mid);
break;
}
}
if(left>right) //当找到这种情况 则说明不可能找到了
{
printf("找不到\n");
}
return 0;
}
6.猜数字小游戏
思路:
1.猜数字游戏无非就是计算机随机出一个数字,你来猜,但是主要的问题是计算机如何出数字呢?
其实可以运用c语言自带的rand函数,但是这个函数虽然能生成随机数,但是你退出游戏后再次玩的时候其实随机数还是那几个,那样游戏你就只能玩一次,后边在玩就相当于知道答案了,故需要用srand函数来调用rand函数,srand函数主要的参数是一个无符号整形,这里也有个问题就是你把数字定了之后,rand产生的数字也就那一个,故需要你自己给srand函数传入一个随机值,所有我们可以使用时间戳来实现传入随机值来使得srand函数产生随机值,这个时间戳是由time函数实现的。代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<time.h> //下面用到时间函数
#include<stdlib.h>//用到srand库函数
void menu()
{
printf("*********************\n");
printf("******1.进行游戏*****\n");
printf("******0.退出游戏*****\n");
printf("*********************\n");
}
void game()
{
int ret =0;
int guess=0;
ret =rand()%100+1;//由于随机数很大,故为了游戏体验 将其变成100以内的数字 求余数再+1 就可得到0-100的数字
while(1)
{
printf("请猜数字 数字在0到100之间\n");
scanf("%d",&guess); //%d后边不能加换行符和空格
if(ret >guess)
{
printf("猜小了\n");
}
else if (ret <guess)
{
printf("猜大了\n");
}
else
{
printf("恭喜猜对了 真牛逼\n");
break;
}
}
}
int main()
{
int input=0;
//void srand(unsined int seed) 这个seed如果写成一个无符号整形的话srand生成的值
//就一直不会变 故需将seed一直变化 所以可以用时间戳来实现seed一直变化
//用时间戳来设置 时间戳是当前计算机的时间减去计算机起始时间(1970年1月1日0点0分0秒)
srand((unsigned int)time(NULL));//使用rand之前先用srand进行调用
do
{
menu();//菜单函数
printf("请选择输入内容===>\n");
scanf("%d",&input);//%d 后边不能加空格 否则要输入两次才行
switch(input) //分支语句 case 1 玩游戏 case 0 退出游戏
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新在1和0之间选择一个数字");
break;
}
}
while (input);//当输入为假即0时结束游戏
return 0;
}
最后玩游戏的过程如下:
可以看到玩了两把都是不同的数字,按0也可以退出游戏。
7.输入一个数字,使其从高位到低位依次输出,例如输入2563,输出2 5 6 3
思路:假如说要你只输出3的话其实是很简单的,就是拿数字直接模上1000就行了,下一位数字直接模100,依次类推,但是要求从第一个数字是2,所以这种方法显然不行,故可以考虑函数递归的方式,即可以将2563拆分成256 和 3, 再将256分成25 和6,最后将25分成2和5,代码如下:
#include <stdio.h>
void print(int x)
{
if(x>9) //如果输入的数字大于9 则说明这个数字最少有两位数 则进入循环进行函数调用
{
print(x/10);
}
printf ("%d ",x%10);
}
#include <stdio.h>
int main ()
{
int num=0;
scanf("%d",&num);
print(num);
return 0;
}
从图中可以看到,假如传入123这个数字,首先调用print函数,将123送进去,判断条件成立,进入循环再次调用函数,此时进行过了运算传进去的是12,再次进行判断,条件成立再次进去,如图3,这次不满足判断条件,直接进行打印,打印出来的就是1,然后再依次打印2,3,这样就可实现上述效果,其中判断条件的意思是若是小于9则说明就是一位数就直接进行打印即可,满足条件才进行函数递归。
8.不使用中间变量交换两个数字
(1)加减法(缺点:如果两个整形过于大,会溢出)
思路:假设输入为3和4
x=3 | y=4 |
x=x+y=7 | y=4 |
x=7 | y=x-y=3 |
x=x-y=4 | y=3 |
#include <stdio.h>
void swap(int* x,int* y) //形参是实参的一份临时拷贝 不能直接传值 要把地址传进来
{
*x=*x+*y;
*y=*x-*y;
*x=*x-*y;
}
int main ()
{
int a=0;
int b=0;
scanf("%d %d",&a,&b);//输入的按照格式输入 中间有空格
printf("before:%d-----%d\n",a,b);
swap(&a,&b);
printf("after:%d-----%d\n",a,b);
return 0;
}
(2)异或法
思路:假如还是3和4
a=3 101B | b=4 100B |
a=a^b=001B | b=4 100B |
a=001B | b=a^b=101B |
a=a^b=100B | b=101B |
#include <stdio.h>
int main ()
{
int a=0;
int b=0;
scanf("%d %d",&a,&b);//输入的按照格式输入 中间有空格
printf("before:%d-----%d\n",a,b);
a=a^b;
b=a^b;
a=a^b;
printf("after:%d-----%d\n",a,b);
return 0;
}
9.求一个整数存储在内存中的二进制中1的个数
思路:由于&有0出0,全1为1,故可以使得这个二进制数往右边移位依次与1进行按位与,为1则说明有1,结果是0则说明无1,代码如下:
#include <stdio.h>
int main ()
{
int num =0;
int count=0;
int i=0;
scanf("%d",&num);
for (i=0;i<32;i++)
{
if(1==((num>>i)&1)) //使得num右移i位 按位与得1说明有一
{
count++;//有一计数一次
}
}
printf("count=%d ",count);
return 0;
}
10.运算符的运算
首先a先使用后自增,a=0,经过逻辑与运算,最左边为0,整个为0,逻辑与右边不进行运算,a要自增,a=1,bcd不变,结果为a=1,b=2,c=3,d=4.
然后在进行逻辑或运算,此时a=1,逻辑或左边为1整个为1,右边不参加运算,则a自增,a=2,b=2,c=3,d=4.
11.任意输入三个数将其按照从大到小输出
思路:两两相比,将大数和小数进行交换,这里采用简单的方式,创建一个中间变量来实现,代码如下:
#include <stdio.h>
int main ()
{
int a =0;
int b =0;
int c =0;
scanf("%d%d%d",&a,&b,&c);
if (a<b)
{
int tmp=a; //交换ab
a=b;
b=tmp;
}
if (a<c)
{
int tmp =a; //交换ac
a=c;
c=tmp;
}
if (b<c)
{
int tmp =b; //交换bc
b=c;
c=tmp;
}
printf("%d %d %d",a,b,c);
return 0;
}
思路:想实现将welcome to henan 从两边往中间打印在*********上,可以将对应的位置字符直接替换过去就行了,两边打印完了之后,让左边元素往右边移动一下,让右边元素往左边移动一下即可,实现代码如下:
#include <stdio.h>
#include <string.h>
#include<windows.h>
#include<stdlib.h>
int main ()
{
char arr1[]="Welcom to henan";
char arr2[]="****************";
int le