你是真的“C”——经典问题解答技巧
创始人
2025-05-30 07:38:56

你是真的“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的幂次方数。

总结撒花💞

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

相关内容

热门资讯

长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
cad打印线条粗细设置 cad... 004-线型(下)打印样式设置和线型文件使用一、线宽设置方法制图规范里边的线宽要求,我们已经定义好,...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...