马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
目次
C语言习题2.0
删除数组中的指定元素
1)运用双指针
2)创建新数组
在数组中找只出现过一次的数字
1)有一个数字成单,其他成对
2)有两个数字成单,其他成对
递归打印
字符串左旋和右旋
1)运用字符串函数
2)将字符串前移,第一个字符调到末了
互换整形变量
1)通过创建第三变量来实现
2)不创建第三方变量,利用两数作差的方法实现
1>.利用a=a-b;
2>.利用a=a+b;
3)运用位异或
4)利用指针变量
求一个数二进制中1的个数的方法
1)利用%和/来盘算
2)对第一种方法举行改进
3)利用位移操纵符举行盘算
4)利用n&(n-1)的性子盘算
将数组中全部的奇数放在前面,偶数放在反面
1)运用指针
2)将奇偶放在两个数组中
strlen的实现
在矩阵中找数字
找凶手
杨辉三角
模仿实现atoi
offsetof的模仿实现
将一个数二进制的奇数位和偶数位举行互换
C语言习题2.0
C语言习题2.0-CSDN博客
删除数组中的指定元素
1)运用双指针
运用双指针,一个在前面走,另一个来更换;
- //方法一:采用双指针
- int main()
- {
- int arr1[] = { 1,8,6,5,4,8,9,8,5,9,6,8,5,8,5,2,8 };
- int c = 8;
-
- int j = 0, k = 0;
- int num = sizeof(arr1) / sizeof(arr1[0]);
- for(int i=0;i<num;i++)
- {
- if (arr1[k] != c)
- {
- arr1[j] = arr1[k];
- j++;
- }
- k++;
- }
- for (int i = 0; i < j; i++)
- printf("%d ", arr1[i]);
- return 0;
- }
复制代码 2)创建新数组
- //方法二:创建新数组,遍历原数组
- int main()
- {
- int arr[] = { 1,8,6,5,4,8,9,8,5,9,6,8,5,8,5,2,8 };
- int t = 8;//删除数组中的元素8
- int sz = sizeof(arr) / sizeof(arr[0]);
- int new[20] = { 0 };
- int a = 0;
- int* p = arr;
- for (int i = 0; i < sz; i++)
- {
- if (arr[i] != t)
- {
- new[a] = arr[i];
- a++;
- }
- }
-
- for (int i = 0; i < a; i++)
- {
- printf("%d ", new[i]);
- }
- return 0;
- }
复制代码 在数组中找只出现过一次的数字
1)有一个数字成单,其他成对
运用按位或操纵符^,a^a=0;0^a=a;根据这个特性,将数组中全部的数字都举行按位与,得到的效果就是成单的数字;
- //找到数组中只出现过一次的数字
- int main()
- {
- int arr[] = { 1,2,6,5,4,5,6,2,1 };
- int sz = sizeof(arr) / sizeof(arr[0]);
- int differ = 0;
- for (int i = 0; i < sz; i++)
- {
- differ ^= arr[i];
- }
- printf("%d", differ);
- return 0;
- }
复制代码 2)有两个数字成单,其他成对
将全部数字按位或,得到a^b即两个成单数字按位或的效果。找到其二进制中第一个1的位置,该位置a,b中肯定有一个是1,另一个是0;此时利用该二进制位就可以将他们分开。
- //有两个成单的元素
- int main()
- {
- int arr[] = { 1,5,6,9,8,6,5,1,3,3 };
- int sz = sizeof(arr) / sizeof(arr[0]);
- int differ = 0;
- for (int i = 0; i < sz; i++)
- {
- differ ^= arr[i];
- }
- //此时differ就是两个成单数字按位或的结果
- //找二进制中第一个1的位置
- int num = 0;
- for (int i = 1; i < 31; i++)
- {
- if (((differ >> i) & 1) == 1)
- {
- num = i;
- break;
- }
- }
- //此时将数组中的元素分开,依据二进制的num位是否为1
- int diff_1 = 0;
- int diff_2 = 0;
- for (int i = 0; i < sz; i++)
- {
- if (((arr[i] << num)&1) == 1)
- diff_1 ^= arr[i];
- else
- diff_2 ^= arr[i];
- }
- printf("%d %d", diff_1, diff_2);
- return 0;
- }
复制代码 递归打印
运用递归打印一个数中最高位到最低为全部的数;
- void Print(int x)
- {
- if (x > 9)
- {
- Print(x / 10);
- printf("%d ", x % 10);
- }
- else
- printf("%d ", x % 10);
- }
- int main()
- {
- int a = 15615646;
- Print(a);
- return 0;
- }
复制代码 字符串左旋和右旋
将字符串中的字符向左(向右)移动指定的位数,移动到最左边(右边)的字符会从右边补上。
原字符串:"abcde" ,左旋 2 位:"cdeab";原字符串:"abcde" 右旋 2 位:"deabc"。
1)运用字符串函数
运用字符串函数。strcpy和strncat函数实现,先将旋转反面的字符串复制到前面,再将前面的字符串追加到反面。
- //左旋,右旋
- //将"ABCDE"左旋2个单位为"CDEAB"
- int main()
- {
- char arr[6] = "ABCDE";
- char arr2[6];
- //先将后面的字符串复制到前面
- strcpy(arr2, arr + 2);
- //将前面的追加到后面
- strncat(arr2, arr, 2);
- //将目标字符串复制回来
- strcpy(arr, arr2);
- printf("%s", arr);
- return 0;
- }
复制代码 2)将字符串前移,第一个字符调到末了
- //方法二:将后面的字符串向前移动,前面的字符调转到后面
- //将"ABCDE"左旋2个单位为"CDEAB"
- int main()
- {
- char arr[6] = "ABCDE";
- int sz = strlen(arr);
- //向前调转2次
- for (int i = 0; i < 2; i++)
- {
- char a = arr[0];
- //将字符串向前移动
- for (int i = 0; i < sz-1; i++)
- arr[i] = arr[i + 1]; //arr[3]=arr[4]
- //将第一个字符调转到最后一个字符
- arr[sz - 1] = a;
- }
- printf("%s", arr);
- return 0;
- }
复制代码 互换整形变量
1)通过创建第三变量来实现
假设互换a和b,重新界说一个c,利用变量赋值是从左向右的,先将a赋值给c(c=a),再将b赋值给a(a=b),末了再将c赋值给b(b=c);此处可以类比为两个杯子的水互换,假设a是雪碧,b是可乐,c是空瓶,先将a倒入到c中,再将b倒入到a中,末了将c倒入到b中完成互换;此方法可读性较高。
- //1)运用第三个变量来交换
- int main()
- {
- int a = 10;
- int b = 20;
- int c;
- printf("交换前a=%d,b=%d\n", a, b);
- c = a;
- a = b;
- b = c;
- printf("交换之后a=%d,b=%d", a, b);
- return 0;
- }
复制代码 2)不创建第三方变量,利用两数作差的方法实现
1>.利用a=a-b;
此方法与第一种方法雷同,也是运用赋值是从左向右,从上向下,此处不外多赘述
- //不创建第三方变量,利用两数作差的方法实现
- //利用a=a-b;
- int main()
- {
- int a = 10;
- int b = 20;
- printf("交换前a=%d,b=%d\n", a, b);
- a = a - b;
- b = a + b;
- a = b - a;
- printf("交换之后a=%d,b=%d", a, b);
- return 0;
- }
复制代码 2>.利用a=a+b;
- //利用a=a+b;
- //#include <limits.h> //调用INT_MAX所需要的头文件
- int main()
- {
- printf("%d\n", INT_MAX);
- int a = 10;
- int b = 20;
- printf("交换前a=%d,b=%d\n", a, b);
- a = a + b; //注意此处于上一个代码的不同,此处的a=a+b的a可能超出INT_MAX即int类型的最大值
- b = a - b;
- a = a - b;
- printf("交换之后a=%d,b=%d", a, b);
- return 0;
- }
复制代码 留意这两种方法的差异,第一种a=a-b大概会导致,a小于INT_MIN,而第二种大概会导致a大于INT_MAX,两种方法都大概导致整数溢出,以是不发起.
3)运用位异或
两个雷同的操纵数位异或的效果为0,即a^a=0;任何数与0位异或还是其自己,即a^0=a;
- //运用位异或
- int main()
- {
- int a = 10;
- int b = 20;
- printf("交换前a=%d,b=%d\n", a, b);
- a = a ^ b;
- b = a ^ b;
- a = a ^ b;
- printf("交换之后a=%d,b=%d", a, b);
- return 0;
- }
复制代码 此处形象化明白,a=a^b(此时的a已经不是20了)的a可以当作是一把钥匙,碰到b位异或为a,碰到a位异或为b;此方法不太发起,可读性较低
4)利用指针变量
与创建第三变量雷同,只是通过所在及解引用来互换,此处不再过多赘述
- //利用指针即解引用来交换
- int main()
- {
- int a = 10;
- int b = 20;
- int c = 0;
- printf("交换之前a=%d,b=%d\n", a, b);
- int* p1 = &a;
- int* p2 = &b;
- int* p3 = &c;
- *p3 = *p1;
- *p1 = *p2;
- *p2 = *p3;
- printf("交换之后a=%d,b=%d\n", a, b);
- return 0;
- }
复制代码 求一个数二进制中1的个数的方法
1)利用%和/来盘算
(方法类于盘算11111十进制中1的个数);分别利用%2来确定末了一位是否为1,在利用/2往复掉当前的二进制最右侧一位,方法较为质朴,可读性也高,不再过多赘述。但是这个方法不能用来盘算负数。
- //利用/和%来计算
- int main()
- {
- int n = 15;
- //15: 00000......00001111
- int count = 0;
- while (n) //此方法不能用来计算负数
- {
- if (n % 2 == 1) //此处的%2是为了确定是否为1
- count++;
- n /= 2; //利用/2来去掉二进制的最右侧一位
- }
- printf("%d", count);
- return 0;
- }
复制代码 2)对第一种方法举行改进
第一种方法在于n=-1是默认有符号的,n%或/的效果均为负数,且相处后效果为0,无法盘算,我们知道-1的二进制是11111111.....11111111,而输出的效果是0。以是我们只必要将其有符号位的1酿成数字位的1即可,就是将其酿成无符号整形,即m=(unsigned int)n此时的m表现一个很大的整数,而不是-1。
- int main()
- {
- int n = -1;
-
- int count = 0;
- unsigned int m = (unsigned int)n; //此处将n改成无符号就可以进行计算了
- while (m)
- {
- if (m % 2 == 1) //此处的%2是为了确定是否为1
- count++;
- m /= 2; //利用/2来去掉二进制的最右侧一位
- }
- printf("二进制中1的个数为%d", count);
- return 0;
- }
复制代码 3)利用位移操纵符举行盘算
利用>>依次向右移动来逐个查抄,此方法简朴,但是其必要循环32次才气竣事,以是其举行了多次无用循环,浪费时间,不发起利用。
- //利用移位操作符来计算
- int main()
- {
- int a = 15;
- int count = 0;
- for (int i = 0; i < 32; i++)
- {
- if (a & 1 == 1) //利用a&1来的出二进制的最右侧移位是0还是1
- count++;
- a >>= 1; //将二进制向右移动,逐个检查
- }
- printf("二进制数字中1的个数为%d", count);
- return 0;
- }
复制代码 4)利用n&(n-1)的性子盘算
- //利用n&(n-1)的性质计算
- int main()
- {
- int n = 15;
- int count = 0;
- while (n)
- {
- count++;
- n = n & (n - 1);
- }
- printf("二进制数中的1一共有%d个", count);
- return 0;
- }
复制代码 将数组中全部的奇数放在前面,偶数放在反面
1)运用指针
运用两个指针left,right,分别在两边找到偶数和奇数,再将left和right举行互换。
- //将一个数组的所有奇数放在前面,偶数放在后面。
- int main()
- {
- int arr[] = { 1,6,9,6,2,7,8,6,3,1,4,5,6 };
- int sz = sizeof(arr) / sizeof(arr[0]);
- int left = 0, right = sz - 1;
- while (left < right)
- {
- //在左半边找到偶数
- while (arr[left] % 2 == 0)
- left++;
- //在右半边找到奇数
- while (arr[right] % 2 != 0)
- right--;
- //交换
- int tmp = arr[left];
- arr[left] = arr[right];
- arr[right] = tmp;
- }
- for (int i = 0; i < sz; i++)
- printf("%d ", arr[i]);
- return 0;
- }
复制代码 2)将奇偶放在两个数组中
- //创建两个数组,专门用来存放奇数,偶数
- int main()
- {
- int arr[] = { 1,6,9,6,2,7,8,6,3,1,4,5,6 };
- int jji[10] = { 0 };
- int ji = 0;
- int oou[10] = { 0 };
- int ou = 0;
- int sz = sizeof(arr) / sizeof(arr[0]);
- for (int i = 0; i < sz; i++)
- {
- if (arr[i] % 2 == 0)
- {
- oou[ou] = arr[i];
- ou++;
- }
- else
- {
- jji[ji] = arr[i];
- ji++;
- }
- }
- for (int i = 0; i < ji; i++)
- printf("%d ", jji[i]);
- for (int i = 0; i < ou; i++)
- printf("%d ", oou[i]);
- return 0;
- }
复制代码 判定一个数是否是2的次方数
1)/2看是否没有余数
将该数字不绝除以2,取模2。
- //判断一个数是否是2的次方数
- bool IsTow(int a)
- {
- while (a!=1)
- {
- if (a % 2 == 0)
- ;
- if (a % 2 == 1)
- return false;
- a /= 2;
- }
- return true;
- }
复制代码 2)二进制中只有1个是1
- //判断一个数是否是2的次方数
- //如果其二进制中只有一个1就是2的次方数
- bool IsTow(int a)
- {
- int count=0;
- while (a)
- {
- a = a & (a - 1);
- count++;
- }
- if (count == 1)
- return true;
- return false;
- }
复制代码 strlen的实现
运用指针找到字符串的末端,在减去起始所在即可。
- //strlen的是实现
- int main()
- {
- char arr[] = "asfnkdsbnvfkua";
- char* p = arr;
- while (*(p++))
- ;
- //地址减去地址表示两个地址中间的元素个数
- int sz = p - arr;
- printf("%d", sz);
- return 0;
- }
复制代码 在矩阵中找数字
找一个矩阵中找到要求的数字,并返回它的坐标;要求时间复杂度小于O(x),即不能一个一个查找;要求:从左到右数字增大,从上到下数字增大,下面是一个4*4的矩阵
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
找数字:arr[ i ][ j ]初始时 i=0,j=4数字比找的数字大j--,比找的数字小了i++;
- int main()
- {
- //生成一个矩阵
- int arr[4][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16} };
- int p;
- scanf("%d", &p);
- int i = 0, j = 4;
- int flag = 0;
- while (i < 4 && j>0)
- {
- if (arr[i][j] > p)
- j--;
- else if (arr[i][j] < p)
- i++;
- else
- {
- flag = 1;
- break;
- }
- }
- if (flag)
- printf("%d %d\n", i, j);
- else
- printf("没找到\n");
- return 0;
- }
复制代码 找凶手
A:不是我;
B:是C;
C:是D;
D:C说谎;
四个人中有一个人说谎,以一个凶手
运用酿成找到凶手;
- //找凶手
- int main()
- {
- char killer;
- for (char i = 'A'; i <= 'D'; i++)
- {
- killer = i;
- // A B C D
- if ((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D') == 3)
- break;
- }
- printf("%c", killer);
- return 0;
- }
复制代码 杨辉三角
1
1 1
1 2 1
1 3 3 1
通过观察可以看到:二维数组当i=j及i=0的时间是1;其他时间arr[ i ][ j ]=arr[ i-1 ][ j ]+arr[ i ][ j+1 ]
下面来打印8行杨辉三角。
- //打印杨辉三角
- int main()
- {
- int arr[8][8] = {0};
- for (int m = 0; m < 8; m++)
- {
- for (int n = 0; n < m + 1; n++)
- {
- if (m == n || n == 0)
- {
- arr[m][n] = 1;
- printf("%d ", arr[m][n]);
- }
- else
- {
- arr[m][n] = arr[m - 1][n-1] + arr[m-1][n];
- printf("%d ",arr[m][n]);
- }
- }
- printf("\n");
- }
- return 0;
- }
复制代码 模仿实现atoi
atoi函数是用来舍去字符串前面的空格,找到第一个数字。
eg: -651safdafa这个字符串的返回值就是-651。
写一个自界说函数来实现atoi功能
此处利用isspace函数查抄空格,isdigit函数查抄数字。
- //实现atoi函数
- int my_atoi(char* p)
- {
- //先将空格跳过
- while (isspace(*p))
- p++;
- int flag = 1;
- //看有没有'+'或‘-’
- if (*p == '-')
- {
- flag = -1;
- p++;
- }
- if (*p == '+')
- p++;
- //返回数字
- int sum = 0;
- while (isdigit(*p))
- {
- sum = sum * 10 + flag*(*p - '0');
- p++;
- }
- return sum;
- }
- int main()
- {
- char arr[100];
- scanf("%s", arr);
-
- int c = my_atoi(arr);
- printf("%d", c);
- return 0;
- }
复制代码 offsetof的模仿实现
offserof是用来检察一个布局体成员的偏移量的;
实现原理:offserof(s,m) s是布局体,m是布局体成员。
(size_t)&(((s*)0)->m)这就是offsetof的底层逻辑
1)先将0的所在转换为布局体范例的,再在布局体中找到成员m,对成员m举行取所在,此时成员m的所在就是其相对于0的所在,0所在就是0,以是m的所在转换成size_t范例就是它的偏移量
将一个数二进制的奇数位和偶数位举行互换
先得到奇数和偶数位,再将奇数位<<1,偶数为>>1,再将奇偶归并
- //将一个数二进制的奇偶交换
- int main()
- {
- int a = 616;
- //先得到奇数位,用&
- //01010101 01010101 01010101 01010101
- // 55 55 55 55
- int c = a & (0x55555555);
- //得到偶数位
- //10101010 10101010 10101010 10101010
- // AA AA AA AA
- int d = a & (0xAAAAAAAA);
- //将奇数>>1,偶数<<1
- c <<= 1, d >>= 1;
- //将两者^
- a = c ^ d;
- return 0;
- }
复制代码 |