网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
将一个十进制数转换成二进制并打印二进制序列的每一位。
答案
void Bin(n)
{
if (n / 2 != 0)
{
Bin(n / 2);
}
printf("%d", n % 2);
}
解析
10进制数转换成二进制数,这是一个连续除2的过程:
- 把要转换的数,除以2,得到商和余数,
- 将商继续除以2,直到商为0。
最后将所有余数倒序排列,得到数就是转换结果。
7冒泡排序
题目
有一个无序的整型数组,使用冒泡排序的方法使其按升序或降序的方式排序。
答案
int BubbleSort() {
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz - 1; i--) {
for (int j = 0; j < sz - 1 - i; j++) {
if (arr[j] < arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
解析
冒泡排序的核心思想是相邻两数相比,可以抽象为一个比较函数。
基本思路是比较
n
−
1
n-1
n−1 趟,每趟比较
n
−
1
−
i
n-1-i
n−1−i 次。
因为外循环结束一次排序完一个数,使其来到其最终位置上,内循环一次使其与未经和其比较的数进行比较,并在满足条件的情况下进行交换,所以每次减
i
。
8数组操作
题目
实现reverse()
函数完成数组元素的逆置。
答案
void reverse(int arr[], int sz)
{
int left = 0;
int right = sz - 1;
while (left < right)
{
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
解析
通过下标访问数组元素从左向右依次进行交换。这种逆序整型数组也可以逆序字符串。都是一样的字符串也可以通过下标访问。
9打印二进制奇数偶数位
题目
输入一个整数,分别打印其二进制序列的奇数位和偶数位。
答案
int main() {
int n = 0;
int i = 0;
scanf("%d", &n);
printf("奇数位:");
for (i = 30; i >= 0; i -= 2) {
printf("%d ", (n >> i) & 1);
}
printf("\n偶数位:");
for (i = 31; i >= 1; i -= 2) {
printf("%d ", (n >> i) & 1);
}
return 0;
}
解析
循环遍历二进制序列中的每一位,让每一位右移上i
位都有机会来到最后一位和整数1
按位与,这样得到的数也只能1
或0
,这样就相当于变相得到二进制序列的每一位。由于要区分奇数位和偶数位且按照顺序打印,故要从后往前遍历。
10交换两个变量
题目
不创建临时变量的条件下,交换两个整型变量。
答案
int main()
{
int a = 10;
int b = 20;
printf("a=%d,b=%d\n", a, b);
//1.
a = a + b;
b = a - b;
a = a - b;
//2.
//(a^b)^a=b (a^b)^b=a
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a=%d,b=%d\n", a, b);
return 0;
}
解析
不创建临时变量来交换两个整数数据。
- 通过赋值的方法,把
a+b
赋值给a
,此时a
已经等于a+b
,再将a-b
赋值给b
,这样b
就等于原来的a
,再用a-b
,这样就得到了b
再赋值给a
。这样a,b就完成了交换。 - 通过按位异或的方法,按位异或的特点是,相同为0,相异为1。这样就会导致一个结果
(a^b)^a=b
,(a^b)^b=a
。这样的话把a^b
的结果再与b
异或然后赋值给b
,再将a^b
,也就是(a^b)^a=b
赋值给a
。
但二者都有局限,前者的大小受限,a+b加起来不可以大于一个整型不然就会溢出。后者因按位操作符仅是由于整型,故后者也受限于变量类型为整型。
11统计二进制中1的个数
题目
输入一个整数,统计其二进制序列中1的个数。
答案
- 方法1
int Return\_Number\_1(int n)
{
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)
{
if (((n >> i) & 1) == 1)
{
count++;
}
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
printf("%d\n", Return\_Number\_1(n));
return 0;
}
- 方法2
int main()
{
int n = 0;
int count = 0;
scanf("%d", &n);
while (n) {
n = n & (n - 1);
count++;
}
printf("%d\n", count);
return 0;
}
解析
如图所示我们用n&(n-1)
作为计数器的条件,可以发现n&(n-1)
的结果比n的二进制序列少一个1,再将结果赋值给n,就可以依靠循环来实现计数器。
12计算求和
题目
求
S
n
=
a
a
a
a
a
a
a
a
a
a
a
a
a
a
a
Sn = a + aa + aaa + aaaa + aaaaa
Sn=a+aa+aaa+aaaa+aaaaa 的前5项之和,其中
a
a
a 是一个数字,例如:
2
22
222
2222
22222
2 + 22 + 222 + 2222 + 22222
2+22+222+2222+22222。
答案
第一种思路:
2 = 2\*10^0
22 = 2\*10^1 + 2
222 = 2\*10^2 + 22
2222 = 2\*10^3 + 222
22222 = 2\*10^4 + 2222
22222 = 2\*10^4 + 2222
第二种思路:
2 = 2 + 0
22 = 2 \* 10 + 2
222 = 22 \* 10 + 2
2222 = 222 \* 10 + 2
22222 = 2222 \* 10 + 2
#include <math.h>
int main()
{
int a = 0;
scanf("%d", &a);
int sum = 0;
int ret = 0;
for (int i = 0; i < 5; i++) {
//1.
ret += a \* (int)pow(10, i);
//2.
ret = ret \* 10 + a;
sum += ret;
}
printf("%d\n", sum);
return 0;
}
第三种方法:
#include <math.h>
int main()
{
int a = 0;
int n = 0;
int sum = 0;
scanf("%d %d", &a, &n);
while (n) {
int i = n;
int ite = 0;
while (i) {
ite += a \* pow(10, i - 1);
i--;
}
sum += ite;
n--;
}
printf("%d\n", sum);
return 0;
}
解析
- 第一种是把
a
a
a 看作
a
×
1
0
0
a×10^0
a×100,
a
a
aa
aa 看成
a
×
1
0
1
a
×
1
0
0
a×101+a×100
a×101+a×100 ……
- 第二种每次在前一次运算的结果上乘10并加上2。
- 第三种是可以规定位数。
13自幂数
题目
求出0~100000之间的所有“水仙花数”并输出。
“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:
153
=
1
3
5
3
3
3
153=13+53+3^3
153=13+53+33 。
则153是一个“水仙花数”。
答案
#include<math.h>
int main() {
for (int i = 0; i < 10000; i++) {
//1. 求位数
int n = 1;
int num = i;
while (num /= 10) {
n++;
}
//2. 求每项和
int sum = 0;
num = i;
while (num) {
sum += (int)pow((num % 10), n);
num /= 10;
}
//3. 判断
if (sum == i) {
printf("%d\n", i);
}
}
return 0;
}
解析
求自幂数需要三步,1求出该数的位数2求每项和3.判断是否相等。每次做出改变i
动作时,要把i
赋值给临时变量以免在循环内改变临时变量。
14字符串逆序
题目
现有一字符串i am a student
,将其全部逆序得tneduts a ma i
。
进阶版:将其单词外逆序,单词内顺序不变,得:student a am i
。
答案
#include <string.h>
char\* reverse(char\* arr) {
int len = strlen(arr);
char\* left = arr;
char\* right = arr + len - 1;
while (left < right) {
char tmp = \*left;
\*left = \*right;
\*right = tmp;
left++;
right--;
}
return arr;
}
int main()
{
char arr[] = "i am a student";
reverse(arr);
printf("%s\n", arr);
return 0;
}
进阶版:
char\* reverse(char\* left, char\* right) {
while (left < right) {
char tmp = \*left;
\*left = \*right;
\*right = tmp;
left++;
right--;
}
return left;
}
char\* move(char\* arr) {
int len = strlen(arr);
reverse(arr, arr + len - 1);
reverse(arr, arr + 6);
reverse(arr + 8, arr + 8);
reverse(arr + 10, arr + 11);
reverse(arr + 13, arr + 13);
return arr;
}
//tneduts a ma i
//01234567890123
int main()
{
char arr[] = "i am a student";
move(arr);
printf("%s\n", arr);
return 0;
}
解析
把所有单词都可视为字符,故逆序字符串即可。进阶版只需要将全部逆序后的结果数清每个字符的下标位置,并单独在逆序就可以了。
15喝汽水问题
题目
喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水。
答案
//喝汽水
int main()
{
int money = 20;
//买的
int total = money;
int empty = money;
//换的
while (empty > 1) {
total += empty / 2;
empty = empty / 2 + empty % 2;
}
printf("%d\n", total);
return 0;
}
解析
喝到的汽水可以分为两种,一种是买来的一种是换来的。首先花已有的钱买来的一元一瓶故先total等于money。
然后计算换来的,定义空瓶数,两个空瓶换一瓶,故total等于empty/2,empty执行整数除法,故empty等于不仅要/2还要%2,奇数瓶还会剩下奇数瓶。
16程序解释
题目
请解释下列代码的运行结果和问题原因。
#include <stdio.h>
int main()
{
int i = 0;
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("hello bit\n");
}
return 0;
}
答案
解析
数组其后第三块空间正好被编译器用来放置存储下标的变量,故每次到这里都会清零,就重新开始了。每个编译器的位置不一样,这个属于编译器的自我优化,不是我们可以改变的。且在release版本会优化掉这个问题。
17调整奇偶顺序
题目
调整数组使奇数全部都位于偶数前面。
输入一个整数数组,调整该数组中数字的顺序,使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。
答案
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int\* pl = arr;
int\* pr = &arr[sz - 1];
while (pl < pr) {
while (\*pl % 2 == 1) {
pl++;
}
while (\*pr % 2 == 0) {
pr--;
}
if (pl < pr) {
int tmp = \*pl;
\*pl = \*pr;
\*pr = tmp;
}
}
for (int i = 0; i < sz; i++) {
printf("%d ", arr[i]);
}
return 0;
}
解析
pl
和pr
不可以同时加减。在前面用pl
寻找奇数,后面用pr
寻找偶数。找到之后再两者交换。
18杨辉三角
题目
打印如图所示的数据三角形。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
打印杨辉三角菱形形式。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
答案
int main()
{
int n = 0;
scanf("%d", &n);
int arr[20][20] = { 0 };
arr[1][1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];//规律
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
进阶版:
int main()
{
int arr[10][10] = { 0 };
for (int i = 0; i < 10; i++) {
for (int j = 0; j <= i; j++) {
//初始化
arr[i][0] = arr[i][i] = 1;
//计算
if (i >= 2 && j >= 1) {
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
}
//打印
printf("%d ", arr[i][j]);
}
printf("\n");
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (j < 9 - i) {
printf(" ");
}
else {
printf("%d ", arr[i][j - 9 + i]);
}
}
printf("\n");
}
return 0;
}
解析
首先杨辉三角的规律为
a
r
r
[
i
]
[
j
]
=
a
r
r
[
i
−
1
]
[
j
−
1
]
a
r
r
[
i
−
1
]
[
j
]
arr[i][j] = arr[i-1][j-1]+arr[i-1][j]
arr[i][j]=arr[i−1][j−1]+arr[i−1][j] 。
- 第一种初始化时是从第2行第2列初始化,将arr[1][1]置为1。
- 第二种是将第1列和对角线初始化为1,然后从第3行第2列开始初始化。
19猜凶手
题目
日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。以下为4个嫌疑犯的供词:
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。
答案
int main()
{
int kill = 0;
//枚举法,一一列举
for (kill = 'A'; kill <= 'D'; kill++) {
//利用表达式返回值特点,直观
if ((kill != 'A') +
(kill == 'C') +
(kill == 'D') +
(kill != 'D') == 3) {
printf("%c\n", kill);
break;
}
}
return 0;
}
解析
定义killer变量,将是与不是转化为关于killer变量的关系运算。因为只有ABCD每人一个条件故只要一个循环即可。三人真话,一人假话,故所有条件表达式相加的结果应为3,在killer假设条件正确时。
20程序解释
题目
求代码中strlen(a)
的结果,并解释清楚原因。
int main()
{
char a[1000] = { 0 };
int i = 0;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d", strlen(a));
return 0;
}
答案
255
解析
求strlen(a)
的值,也就是求a[i]=0
的时候,i
为多少,准确的来说应该是-1-i
等于多少。因为数组a
为字符元素数组,故当-1-i
的尾七位二进制补码为全1
的时候,由于存入数组时发生截断故存入的是0。
21猜名次
题目
5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。
答案
int main()
{
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int e = 0;
for (a = 1; a <= 5; a++) {
for (b = 1; b <= 5; b++) {
for (c = 1; c <= 5; c++) {
for (d = 1; d <= 5; d++) {
for (e = 1; e <= 5; e++) {
//循环5^5次
//判断条件1.
//if ((b == 2) + (a == 3) +
// (b == 2) + (e == 4) +
// (c == 1) + (d == 2) +
// (c == 5) + (d == 3) +
// (e == 4) + (a == 1) == 5) {
//判断条件2.
if (((b == 2) + (a == 3) == 1) &&
((b == 2) + (e == 4) == 1) &&
((c == 1) + (d == 2) == 1) &&
((c == 5) + (d == 3) == 1) &&
((e == 4) + (a == 1) == 1)) {
if (a \* b \* c \* d \* e == 120) {//1\*2\*3\*4\*5=120
printf("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e);
goto again;
return 0;
}
}
}
}
}
}
}
again:
}
解析
找凶手的题目凶手只有一个,猜名次必须要排序,所以要有5个循环,每个循环判断一个选手的名次。同样是把所有人的话作为一个条件,限制条件是每个人只有半句是对的,所以是两个条件加起来是1。最后要取出排名重复的情况。
22杨氏矩阵
题目
有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,
请编写程序在这样的矩阵中查找某个数字是否存在。
要求:时间复杂度小于O(N);
答案
void find\_key(int(\*pa)[3], int\* px, int\* py, int k) {
int x = \*px;
int y = \*py;
while (x < 3 && y >= 0) {
if (pa[x][y] > k) {
y--;
}
else if (pa[x][y] < k) {
x++;
}
else {
printf("(%d,%d)\n", x, y);
return;
}
}
printf("NO\n");
}
int main() {
int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
int key = 7;
int x = 0;
int y = 2;
find\_key(arr, &x, &y, key);
![img](https://img-blog.csdnimg.cn/img_convert/585467ce564c71177d7a763d07f7dd79.png)
![img](https://img-blog.csdnimg.cn/img_convert/364a26d8d2aaf07bede1cd013dabdc16.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**
//判断条件2.
if (((b == 2) + (a == 3) == 1) &&
((b == 2) + (e == 4) == 1) &&
((c == 1) + (d == 2) == 1) &&
((c == 5) + (d == 3) == 1) &&
((e == 4) + (a == 1) == 1)) {
if (a \* b \* c \* d \* e == 120) {//1\*2\*3\*4\*5=120
printf("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e);
goto again;
return 0;
}
}
}
}
}
}
}
again:
}
解析
找凶手的题目凶手只有一个,猜名次必须要排序,所以要有5个循环,每个循环判断一个选手的名次。同样是把所有人的话作为一个条件,限制条件是每个人只有半句是对的,所以是两个条件加起来是1。最后要取出排名重复的情况。
22杨氏矩阵
题目
有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,
请编写程序在这样的矩阵中查找某个数字是否存在。
要求:时间复杂度小于O(N);
答案
void find\_key(int(\*pa)[3], int\* px, int\* py, int k) {
int x = \*px;
int y = \*py;
while (x < 3 && y >= 0) {
if (pa[x][y] > k) {
y--;
}
else if (pa[x][y] < k) {
x++;
}
else {
printf("(%d,%d)\n", x, y);
return;
}
}
printf("NO\n");
}
int main() {
int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
int key = 7;
int x = 0;
int y = 2;
find\_key(arr, &x, &y, key);
[外链图片转存中...(img-LMvvqUkI-1715570664024)]
[外链图片转存中...(img-qanY7xcT-1715570664026)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**