目录
一、字符串左旋 (两种实现方法)
实现一个函数,可以左旋字符串中的 k个字符
For example
ABCD 左旋一个字符得到 BCDA
ABCD 左旋两个字符得到 CDAB
Solution 1
#include <stdio.h>
#include <string.h>
#define MAX 10
void str_rotate(char* str,int k)
{
int i=0;
int n=strlen(str);
for(i=0;i<k;i++)
{
//每次旋转一个字符
char tmp=*str;
//把后边的n-1个字符往前移
//把tmp放在最后
int j=0;
for(j=0;j<n-1;j++)
{
*(str+j)=*(str+j+1);
}
*(str+n-1)=tmp;
}
}
int main()
{
char arr[MAX]="";
gets(arr);//输入字符
int k=0;//旋转k个字符
scanf("%d",&k);
str_rotate(arr,k);
printf("%s\n",arr);
return 0;
}
Solution 2
例如
ABCDEF
左旋两个,则把前两个当成一体,进行翻转
AB CDEF
BA FEDC ,翻转
再整体翻转
变成CDEFAB
#include <stdio.h>
#include <assert.h>
#include <string.h>
#define MAX 10
void reverse(char* left,char* right)//翻转需要知道前后地址
{
assert(left);
assert(right);
while(left<right)
{
char tmp=*left;
*left=*right;
*right=tmp;
left++;
right--;
}
}
void str_rotate(char* str,int k)
{
assert(str);
int n=strlen(str);
reverse(str,str+k-1);//左边翻转
reverse(str+k,str+n-1);//右边翻转
reverse(str,str+n-1);//整体翻转
}
int main()
{
char arr[MAX]="";
gets(arr);//输入字符
int k=0;//旋转k个字符
scanf("%d",&k);
str_rotate(arr,k);
printf("%s\n",arr);
return 0;
}
二、杨氏矩阵中查找指定数字 (两种方式)
有一个数组矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的
在这样的矩阵中查找每个数字是否存在
such as:
1 2 3
4 5 6
7 8 9
限制条件
要求时间复杂度小于 O(N)
Solution 1
#include <stdio.h>
#define ROW 3
#define LINE 3
int find_num(int arr[ROW][LINE],int r,int c,int k)
{
//先找右上角的数字,然后比较,大的话就往下移,小的话就往左移
int x=0;
int y=c-1;
while(x<r&&y>=0)
{
if(arr[x][y]<k)
{
x++;//往下移
}
else if(arr[x][y]>k)
{
y--;//往左移
}
else
{
printf("%d %d\n",x,y);
return 1;//相等,找到了
}
}
return 0;
}
int main()
{
int arr[ROW][LINE]={0};
printf("请输入杨氏矩阵:\n");
int i=0;
int j=0;
for(i=0;i<ROW;i++)
{
for(j=0;j<LINE;j++)
{
scanf("%d",&arr[i][j]);
}
}
printf("请输入你要查找的数字:\n");
int k=0;//查找的数字k
scanf("%d",&k);
int x=ROW;//行数
int y=LINE;//列数
int ret=find_num(arr,ROW,LINE,k);
if(ret==1)
{
printf("找到了\n");
}
else
{
printf("找不到\n");
}
return 0;
}
Solution 2
#include <stdio.h>
#define ROW 3
#define LINE 3
int find_num(int arr[ROW][LINE],int* px,int* py,int k)
{
int x=0;
int y=*py-1;//*py,列数解引用
while(x<*px&&y>=0)
{
if(arr[x][y]<k)
{
x++;
}
if(arr[x][y]>k)
{
y--;
}
if(arr[x][y]==k)
{
*px=x;
*py=y;
return 1;
}
}
return 0;
}
int main()
{
int arr[ROW][LINE]={0};
printf("请输入杨氏矩阵:\n");
int i=0;
int j=0;
for(i=0;i<ROW;i++)
{
for(j=0;j<LINE;j++)
{
scanf("%d",&arr[i][j]);
}
}
printf("请输入你要查找的数字:\n");
int k=0;//查找的数字k
scanf("%d",&k);
int x=ROW;//行数
int y=LINE;//列数
int ret=find_num(arr,&x,&y,k);
if(ret==1)
{
printf("找到了\n");
printf("下标是%d %d\n",x,y);
}
else if(ret==0)
{
printf("找不到\n");
}
return 0;
}
运行结果
三、判断是否是自幂数
自幂数介绍
类似于水仙花数,只不过位数可以不是3位数
假设位数为n
每位数的n次方之和,等于该数
代码思路
(1)先判断位数n
(2)再计算每一位的n次方之和
(3)判断
Solution
#include <stdio.h>
#include <math.h>
int main()
{
int a=0;
scanf("%d",&a);
int n=1;//最起码是一位数
int tmp=a;//先保存下a的值,方便后续判断
while(a/10)
{
n++;
a=a/10;
}
a=tmp;//让a进行下一步计算
int sum=0;
while(a)
{
sum+=pow(a%10,n);
a=a/10;
}
//判断
if(sum==tmp)
{
printf("%d是自幂数",tmp);
}
else
{
printf("%d不是自幂数",tmp);
}
return 0;
}
四、求最小公倍数 (三种求法)
Solution 1
#include <stdio.h>
int main()
{
int a=0;
int b=0;
scanf("%d %d",&a,&b);
int m=a>b?a:b;//m为最小公倍数,先让m取两者较大的数
while(1)
{
if(m%a==0&&m%b==0)
{
printf("%d\n",m);
break;
}
m++;
}
return 0;
}
Solution 2
#include <stdio.h>
int main()
{
int a=0;
int b=0;
scanf("%d %d",&a,&b);
int i=0;
for(i=0;;i++)
{
if(a*i%b==0)
{
printf("%d\n",a*i);
break;
}
}
return 0;
}
Solution 3
辗转相除法,先算出来最大公约数n,再算最小公倍数(a*b)/n
五、顺序输出每位数 (递归)
#include <stdio.h>
void print(unsigned int n)
{
if (n > 9)
{
print(n / 10);
}
printf("%d\n", n % 10);
}
int main()
{
unsigned int num = 0;
scanf("%u", &num);
//递归
print(num);//自定义print函数,打印数字的每一位
return 0;
}
六、交换两数的值不增设第三变量(两种方法)
Solution 1
设计思路
a=a+b;
b=a-b;//a-b得到的是交换前a的值,将其赋给b
a=a-b;//等式右边的a,值为第一个等式左边的a,即交换前的a与b之和;
//等式右边的b的值为交换前的a,(交换前a+交换前b)-交换前a = 交换前的b
代码内容
#include <stdio.h>
int main()
{
int a,b;
scanf("%d %d",&a,&b);
printf("交换前:a = %d b = %d\n",a,b);
a=a+b;
b=a-b;
a=a-b;
printf("交换后:a = %d b = %d\n",a,b);
return 0;
}
注意事项
如果数字过大,将失效
Solution 2
设计思路
a=a^b;//异或一下
b=a^b;
a=a^b;
代码内容
#include <stdio.h>
int main()
{
int a,b;
scanf("%d %d",&a,&b);
printf("交换前:a = %d b = %d\n",a,b);
a=a^b;
b=a^b;
a=a^b;
printf("交换后:a = %d b = %d\n",a,b);
return 0;
}
数字再大,也可以正确算出结果
七、求第n个斐波那契数(两种方法)
斐波那契数介绍
1 1 2 3 5 8 13 21 34 55
后一项等于前两项之和
Solution 1
递归的方式,简单明了
但递归层数太深,将变得不再适用
#include <stdio.h>
int Fib(int n)
{
if(n<=2)
return 1;
else
return Fib(n-1)+Fib(n-2);
}
int main()
{
int n=0;
scanf("%d",&n);
int ret=Fib(n);
printf("%d\n",ret);
return 0;
}
Solution 2
采用循环的办法,无论多少层都能快速计算出结果
#include <stdio.h>
int Fib(int n)
{
int a=1;
int b=1;
int c=0;
while(n>2)
{
c=a+b;
a=b;
b=c;
n--;
}
}
int main()
{
int n=0;
scanf("%d",&n);
int ret =Fib(n);
printf("%d\n",ret);
return 0;
}
注意事项
本程序适用于计算第47位之前的斐波那契数,第47位之后将计算出负数