C语言经典编程题
一、递归求一个数的阶乘:
int factorial(int n)
{
while (n > 1)
{
return n*func(n-1);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
当然也可以不用while循环,因为都是n级运算,算法复杂度都为O(n),所以影响不大。
int factorial(int n)
{
if(n == 0)
{
return 1;
}
else
{
return n*func(n-1);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
二、输入一个整数(任意位数),倒叙输出:
因为要把一个整数颠倒过来。所以得把从低位到高位的顺序分别打印出来,然后乘以相应的倍数,最后相加即可。
#include <stdio.h>
int getLen(int num) //计算该数一共有多少位(长度)
{
int flags = 0;
for (num; num >0 ; num/=10)
{
flags++;
}
return flags; //返回位数(长度)
}
int getIndex(int len) //len是数的位数
{
int i=0;
int res = 1;
for (i = 0; i < len ; i++)
{
res=res*10;
}
return res; //返回10^i
}
int main()
{
int num,temp,LastNum;
printf("please input a num:\n");
scanf("%d",&num);
int len = getLen(num);
int i=0;
for(i = 0; i<len ; i++)
{
temp=num%10; //提取每个位的数
num=num/10;
LastNum+=temp*getIndex(len-i-1); //这里是个累加过程
}
printf("the resault=%d\n",LastNum);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
三、将一个数组逆序放到原来数组中。(考虑复杂度)
算法一:相当于把数组对应位置前后调换,只需要n/2次。
for (i = 0;i < n/2;i++)
{
t = arr[i];
arr[i] = arr[n-1-i];
arr[n-1-i] = t;
}
- 1
- 2
- 3
- 4
- 5
- 6
算法二:
for (i = 0;i < n;i++)
b[i] = a[n-i-1];
for (i = 0;i < n;i++)
a[i]=b[i];
- 1
- 2
- 3
- 4
算法一借助辅助空间t ,而算法二借助辅助空间为 b[n]。所以空间复杂度来说,算法一空间复杂度为O(1),算法二空间复杂度为O(n)。
四、斐波那契数列:
Fib(0) = 0
Fib(1) = 1
Fib(n) = Fib(n-1) + Fib(n-2)
F() = 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 …
int Fibonacci(int n)
{
if (n <= 1)
return n;
else
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
这里,给定规模 n,计算 Fib(n) 所需的时间为计算 Fib(n-1) 的时间和计算 Fib(n-2) 的时间的和。
T(n<=1) = O(1)
T(n) = T(n-1) + T(n-2) + O(1)
fib(5)
/ \
fib(4) fib(3)
/ \ / \
fib(3) fib(2) fib(2) fib(1)
/ \ / \ / \
- 1
- 2
- 3
- 4
- 5
- 6
通过使用递归树的结构描述可知算法复杂度为 O(2n)。
int Fibonacci(int n)
{
if (n <= 1)
return n;
else
{
int[] f = new int[n + 1];
f[0] = 0;
f[1] = 1;
for (int i = 2; i <= n; i++)
{
f[i] = f[i - 1] + f[i - 2];
}
return f[n];
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
不使用递归:(复杂度降为O(n))
int Fibonacci(int n)
{
if (n <= 1)
return n;
else
{
int iter1 = 0;
int iter2 = 1;
int f = 0;
for (int i = 2; i <= n; i++)
{
f = iter1 + iter2;
iter1 = iter2;
iter2 = f;
}
return f;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
五、判断是大端还是小端字节序:
方法一(使用联合体):
这里用到了联合体:联合体内成员共享内存,所以所有成员首地址相同。
所以可以通过对较长的成员赋值,通过判断另个一个成员变量的值来判断存放的是高位字节还是低位。
union
{
char c;
unsigned short s;
}A;
A.s = 0x1234;
if(A.c == 0x12) //0x12是高位字节
{
printf("It's MSB"); // 1 0x34
// 0 0x12
}
else
{
printf("It's LSB"); // 1 0x12
// 0 0x34
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
方法二:(不使用联合)
unsigned int a = 0x12345678;
unsigned char i = (unsigned char)a; //截断a
if (i == 0x12)
{
printf("MSB");
}
else
{
printf("LSB");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
六、桶排序:对公司员工年龄进行排序(存在年龄相同情况)
这里用的是桶排序的思想。桶排序虽然速度快,算法简单,但是因为要借助辅助空间,浪费空间,只适合对较少的数据排序。
#include <stdio.h>
void sortage(int arr[],int len)
{
int i=0;
if (arr == NULL || len <= 0)
{
return;
}
const int oldestAge = 99; //最大年龄
int timeofAge[oldestAge+1]; //每个年龄次数(辅助内存)
//初始化数组
for(i = 0;i <= oldestAge;i++)
{
timeofAge[i] = 0;
}
for (i = 0;i < len;i++) //循环读入年龄
{
int age = arr[i];
if(age < 0 || age > oldestAge )
{
printf("age is not in the range");
}
timeofAge[age]++; //每个年龄作为数组的下标,就代表这个年龄的员工有几人
}
int index=0;
int j=0;
//双层循环,外层遍历所有年龄
for (i = 0;i <= oldestAge;i++)
{
for (j = 0;j < timeofAge[i];j++) //内层循环:出现几次就打印几次
{
arr[index] = i;
++index;
}
}
}
void main()
{
int i=0;
int arr[7]={22,18,23,22,50,34,19};
sortage(arr,7);
for(i = 0;i < 7;i++)
{
printf("%d ",arr[i]);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
七、字符串移动:
编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh” 函数头是这样的:
//pStr是指向以’\0’结尾的字符串的指针
//steps是要求移动的n
void LoopMove ( char * pStr, int steps )
{
//请填充…
}
正确答案:
解析:都是用临时变量来存储,然后通过指针指向来实现改变。解答2更直观。
正确解答1:
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) - steps;
char tmp[MAX_LEN];
strcpy ( tmp, pStr + n );
strcpy ( tmp + steps, pStr);
*( tmp + strlen ( pStr ) ) = '\0';
strcpy( pStr, tmp );
}
正确解答2:
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) - steps;
char tmp[MAX_LEN];
memcpy( tmp, pStr + n, steps );
memcpy(pStr + steps, pStr, n );
memcpy(pStr, tmp, steps );
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
八 、计算最后一个单词的长度
思想:这里采用逆向思维,把字符串从后往前数,依次对每个字符判断是否为空,定义一个变量计数。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
while(getline(cin,s)) //c++键盘输入的一种表达
{
int n=0,flag=1;
for(int i = s.length()-1; i >= 0;--i)
{//倒着计算
if(flag && s[i]==' ')
{
//如果末尾有空格,先清除末尾空格
continue;
}
else if(s[i]!=' ')
{
flag = 0;
++n;
}
else
{
break;
}
}
cout << n << endl;
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
九、联发科2017笔试题:
删除一个字符串中指定的所有某个字符。
解法一:
思想:找到某字符后把后面的字符串依次往前移动。算法复杂度为O(n^2)。
void dele_char(char *str,char s)
{
char *p = str;
char *temp=NULL;
while ( *p != '\0' )
{
if (*p == s)
{
temp = p; //找到字符后保存该地址,方便返回继续遍历
while (*p != '\0' )
{
*p = *(p+1);
p++;
}
p = temp-1; //返回前一个位置,为了防止该字符连续出现
}
p++;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
方法二
思想:上面方法复杂度是O(n^2),下面用更简单的算法复杂度来实现。这里思想是直接对该字符不予理踩,对不相等的部分重新赋值。
void dele_char(char *str,char s)
{
int i = 0;
int j = 0;
for (i = 0; i < strlen(a); i++)
{
if (a[i] != 'f')
{
a[j] = a[i]; //把不相等的部分进行赋值
j++;
}
}
a[j] = '\0'; //最后一位设置为'\0'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
十、用一个表达式判断一个整数是否在某两个整数之间
a < b < c : 判断b在a~c之间
static inline int between(__u32 a, __u32 b, __u32 c)
{
return c - a >= b - a;
}
- 1
- 2
- 3
- 4
杰发科技2015改错题:
把一个字符串s拷贝到t中,并且把倒叙的字符串s接到t后面。
如:
输入:abc.
打印:abccba
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void inv_cat(char *s,char *t)
{
int i,len;
len = strlen(s);
for (i=0; i<len; i++)
{
t[i] = s[i];
}
for (i=0; i<len; i++)
{
t[len+i] = s[len-1-i]; //原题这里少了-1
}
t[2*len] = '\0'; //原题为2*len-1
}
int main()
{
char s[100];
//原题t没有分分配内存,直接段错误
char *t =(char *)malloc(sizeof(char));
printf("\nPlease enter string s:\n");
scanf("%s",&s);
inv_cat(s,t);
printf("The result is : %s",t);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
--------------------- 本文来自 qicheng777 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qicheng777/article/details/77073976?utm_source=copy