你是真的“C”——经典问题解答技巧
创始人
2025-05-30 06:25:19
0

你是真的“C”——经典问题解答技巧😎

  • 前言🙌
    • 喝汽水问题🙌
    • 写一个函数,可以逆序一个字符串的内容。
    • 调整数组使奇数全部都位于偶数前面。
    • 实现一个函数,可以左旋字符串中的k个字符。
    • 写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
    • 求出 5位数中的所有 Lily Number。
    • 求出0~100000之间的所有“水仙花数”并输出。
    • 不允许创建临时变量,交换两个整数的内容
    • 写一个函数返回参数二进制中 1 的个数。
    • 获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
    • 两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
    • 如何判断一个数是不是 2 的幂次方?
  • 总结撒花💞

追梦之旅,你我同行

   
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!

😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
在这里插入图片描述

前言🙌

    哈喽各位友友们😊,我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下!😘我仅已此文,和大家分享你是真的“C”——经典问题解答技巧。都是精华内容,可不要错过哟!!!😍😍😍

喝汽水问题🙌

喝汽水问题
题目内容
喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)

在这里插入图片描述
解题方法一源码分享:

int main()
{int money = 0;scanf("%d", &money);//20int empty = money;int total = money;while (empty >= 2){total += empty / 2;empty = empty / 2 + empty%2;}printf("%d\n", total);return 0;
}

解题方法二源码分享:

int main()
{int money = 0;scanf("%d", &money);//20int total = 0;if(money>0)total = 2 * money - 1;printf("%d\n", total);return 0;
}

写一个函数,可以逆序一个字符串的内容。

做题链接: 逆序一个字符串

void Reverse(char* str)
{char* left = str;char* right = str + strlen(str)-1;while(left < right){char temp = *left;*left = *right;*right = temp;++left;--right;}
}int main()
{char str[] = "hello bit";//在这里完成下面函数,参数自己设计,要求:使用指针Reverse(str);return 0;
}// 注意:如果是在线OJ时,必须要考虑循环输入,因为每个算法可能有多组测试用例进行验证,参考以下main函数写法,
int main()
{char str[101] = {0};while(gets(str)){Reverse(str);printf("%s\n", str);memset(str, 0, sizeof(str)/sizeof(str[0]));}return 0;
}

调整数组使奇数全部都位于偶数前面。

题目:
输入一个整数数组,实现一个函数,
来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,
所有偶数位于数组的后半部分。

思路:

  1. 给定两个下标left和right,left放在数组的起始位置,right放在数组中最后一个元素的位置
  2. 循环进行一下操作
    a. 如果left和right表示的区间[left, right]有效,进行b,否则结束循环
    b. left从前往后找,找到一个偶数后停止
    c. right从后往前找,找到一个奇数后停止
    d. 如果left和right都找到了对应的数据,则交换,继续a,

void swap_arr(int arr[], int sz)
{int left = 0;int right = sz-1;int tmp = 0;while(left// 从前往后,找到一个偶数,找到后停止while((leftleft++;}// 从后往前找,找一个奇数,找到后停止while((leftright--;}// 如果偶数和奇数都找到,交换这两个数据的位置// 然后继续找,直到两个指针相遇if(lefttmp = arr[left];arr[left] = arr[right];arr[right] = tmp;}}
}

实现一个函数,可以左旋字符串中的k个字符。

例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB

方法一:设计循环使其可以旋1次,然后让他执行n次是一个最简单的思路:

void leftRound(char * src, int time)
{int i, j, tmp;int len = strlen(src);time %= len; //长度为5的情况下,旋转6、11、16...次相当于1次,7、12、17...次相当于2次,以此类推。for (i = 0; i < time; i++) //执行k次的单次平移{tmp = src[0];for(j = 0; j < len - 1; j++) //单次平移{src[j] = src[j + 1];}src[j] = tmp;}
}

这个思路当然可以,但是一次一次转毕竟太麻烦,就不能一次到位么?

方法二:
当然可以,我们可以选择拼接法,一次到位:

void leftRound(char * src, int time)
{int len = strlen(src);int pos = time % len; //断开位置的下标char tmp[256] = { 0 }; //更准确的话可以选择malloc len + 1个字节的空间来做这个tmpstrcpy(tmp, src + pos); //先将后面的全部拷过来strncat(tmp, src, pos); //然后将前面几个接上strcpy(src, tmp); //最后拷回去
}

这个方法要用到一个数组形成的辅助空间,让人觉得有点不爽。

方法三:

还可以有更好的选择,例如ABCDEFG,左旋3次后变成DEFGABC,有一个特殊的操作
先将要左旋的前三个家伙逆序(CBADEFG),然后将后半段也逆序(CBAGFED),最后整体逆序(DEFGABC)即可。这样只需要做数值交换即可,可以写一个函数帮我们完成局部逆序,代码如下:

void reverse_part(char *str, int start, int end) //将字符串从start到end这一段逆序
{int i, j;char tmp;for (i = start, j = end; i < j; i++, j--){tmp = str[i];str[i] = str[j];str[j] = tmp;}
}void leftRound(char * src, int time)
{int len = strlen(src);int pos = time % len;reverse_part(src, 0, pos - 1); //逆序前段reverse_part(src, pos, len - 1); //逆序后段reverse_part(src, 0, len - 1); //整体逆序
}

这样就舒服多了。

写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC

本题当然可以将所有旋转后的结果放到一个数组里,然后进行查找,但是这种做法既不好操作,也太费事,但是这题有一个很简单的做法:
其实ABCDE无论怎么旋,旋转后的所有结果,都包含在了ABCDEABCD这个字符串里了。所以做法很简单,只需要将原字符串再来一遍接在后面,然后找一找待查找的字符串是不是两倍原字符串的子集即可。

int findRound(const char * src, char * find)
{char tmp[256] = { 0 }; //用一个辅助空间将原字符串做成两倍原字符串strcpy(tmp, src); //先拷贝一遍strcat(tmp, src); //再连接一遍return strstr(tmp, find) != NULL; //看看找不找得到
}

求出 5位数中的所有 Lily Number。

//12345
12345/10    12345%10
12345/100   12345%100=45
12345/1000  12345%1000=345
12345/10000 12345%10000=2345int main()
{int i = 0;for (i = 10000; i <= 99999; i++){//判断i是否是lily numberint j = 0;int sum = 0;for (j = 1; j <= 4; j++){int n = (int)pow(10, j);sum += (i / n) * (i % n);}if (sum == i){printf("%d ", i);}}return 0;
}

求出0~100000之间的所有“水仙花数”并输出。

//“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1 ^ 3+5 ^ 3+3 ^ 3,则153是一个“水仙花数”
//自幂数


#include int main()
{int i = 0;//ifor (i = 0; i <= 100000; i++){//判断i是否是自幂数//1. 计算i的位数 - nint n = 1;int tmp = i;while (tmp /= 10){n++;}//2. 计算i的每一位的n次方和tmp = i;int sum = 0;while (tmp){sum += pow(tmp % 10, n);tmp /= 10;}//3. 判断if (sum == i){printf("%d ", i);}}return 0;
}

不允许创建临时变量,交换两个整数的内容

a^0 = a
a^a = 0int main()
{int a = 3;int b = 5;//int tmp = a;//a = b;//b = tmp;//a = a ^ b;//b = a ^ b;//a = a ^ b;printf("a=%d b=%d", a, b);return 0;
}

写一个函数返回参数二进制中 1 的个数。

在这里插入图片描述

比如: 15 0000 1111 4 个 1
-1
10000000000000000000000000000001
11111111111111111111111111111110
11111111111111111111111111111111


这个算法对负数有点问题
int count_one_bit(int num)
{int count = 0;while (num){if (num % 2 == 1){count++;}num /= 2;}return count;
}
-1int count_one_bit(unsigned int num)
{int count = 0;while (num){if (num % 2 == 1){count++;}num /= 2;}return count;
}int count_one_bit(int num)
{int count = 0;int i = 0;for (i = 0; i < 32; i++){if (((num >> i) & 1) == 1){count++;}}return count;
}int count_one_bit(int num)
{int count = 0;while (num){num = num & (num - 1);count++;}return count;
}int main()
{int num = 0;scanf("%d", &num);//10 20 15 -1int ret = count_one_bit(num);printf("%d\n", ret);return 0;
}

获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 0 1

int main()
{int num = 0;scanf("%d", &num);int i = 0;//偶数位for (i = 31; i >= 1; i -= 2){printf("%d ", (num >> i) & 1);}printf("\n");//奇数位for (i = 30; i >= 0; i -= 2){printf("%d ", (num >> i) & 1);}printf("\n");return 0;
}

两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?

/ 01
10


int main()
{int m = 0;int n = 0;int i = 0;scanf("%d %d", &m, &n);int count = 0;for (i = 0; i < 32; i++){if (((m >> i) & 1) != ((n >> i) & 1)){count++;}}printf("%d\n", count);return 0;
}int main()
{int m = 0;int n = 0;int i = 0;scanf("%d %d", &m, &n);int count = 0;//异或 - 相同为0,相异为1//010//001//011int ret = m ^ n;while (ret){ret = ret & (ret - 1);count++;}printf("%d\n", count);return 0;
}

如何判断一个数是不是 2 的幂次方?

//2 的幂次方 的数:二进制中只有1个1
//2 - 10
//4 - 100
//8 - 1000
// …
当 n&(n-1) == 0
时,该数就是2的幂次方数。

总结撒花💞

   本篇文章旨在分享几道曾今自己感到疑惑的经典题目。希望大家通过阅读此文有所收获!😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘

相关内容

热门资讯

最新或2023(历届)北京市所... 最新或2023(历届)北京市所有的中学高中排名,北京市最好的中学高中排行榜一、北京一流高中名单1.1...
最新或2023(历届)上海市小...     徐汇  第一梯队:世界外国语小学、爱菊小学、逸夫小学、盛大花园小学、高安路一小、向阳小学、汇...
SC8P1762E指令一览表 控制类 NOP, 空操作 STOP, 进入休眠模式 CLR...
最新或2023(历届)杭州民办... 自从上周钱报教育微信升学宝开通“我问鹿姐”栏目后,问题汹涌得快把鹿姐姐给淹没了,本周提问时间进入“小...
最新或2023(历届)北京小升...  最新或2023(历届)北京小升初政策春节前已经公布,关于最近很受关注的小升初特长生招生情况,最新或...
3.docker入门到精通—常... docker私服仓库启动docker run -d -p 5000:5000 -v /zzyyuse...
最新或2023(历届)杭州民办... 杭城民办初中虽说要4月底网上招生报名,但眼下老师们收简历收得手软。孩子面临小升初的家长,带着孩子的简...
最新或2023(历届)北京小升...  北京市市教委公布最新或2023(历届)义务教育阶段入学政策,比往年公布时间提前了两个月。政策规定今...
最新或2023(历届)重庆小升...   近日,重庆部分民办初中开始小升初招生网上报名登记工作。  洋洋今年读6年级。前几天,洋洋爸爸与两...
技术布道 | 推动XR技术在产... 近年来,越来越多的企业正在利用扩展现实(XR)为用户提供沉...
最新或2023(历届)北京小升...  最新或2023(历届)北京小升初政策已经公布,今年各区将制定非京籍“五证”审核细则,进一步规范化非...
模糊的图片能恢复成高清图吗? 之前照了一组照片,当时忘了保存原图,现在翻出来看好模糊,还...
最新或2023(历届)北京小升...  最新或2023(历届)北京小升初政策春节前已经公布,关于最近很受关注的非京籍小升初,最新或2023...
最新或2023(历届)北京小升... 最新或2023(历届)北京小升初政策已经公布,政策中规定今年北京各区县都将对非京籍“五证”的审核制定...
最新或2023(历届)北京小升...  最新或2023(历届)北京小升初政策已经公布,今年各区将会出台非京籍“五证”细则,以保证非京籍学生...
最新或2023(历届)北京小升... 最新或2023(历届)北京小升初入学信息采集将于5月1日开始,这是是小升初进程中相当重要的一步。由于...
Golang在ACM模式下的刷... 受之前用C和C++刷题的影响,所有输入我都喜欢用scanf处理,恰恰golang也有scanf函数,...
天津和平教育局长谈最新或202...   近年来,和平区在区内各校全面推广义务教育现代化达标建设以及优秀教师交流、校长轮岗等制度,使义务教...
最新或2023(历届)北京小升...  随着最新或2023(历届)北京小升初进程的加快,最近名校游活动不管是线上答疑还是线下的沙龙以及走进...
最新或2023(历届)天津小升... 最新或2023(历届)天津小升初政策已经公布,各种考试几乎全部取消的消息使得很多天津小升初家长一瞬间...