😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!
😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
前言🙌
哈喽各位友友们😊,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分享一下!😘我仅已此文,和大家分享你是真的“C”——经典问题解答技巧。都是精华内容,可不要错过哟!!!😍😍😍
喝汽水问题🙌
喝汽水问题
题目内容
喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)
解题方法一源码分享:
int main() { int money = 0; scanf("%d", &money);//20 int 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);//20 int 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<right) { // 从前往后,找到一个偶数,找到后停止 while((left<right)&&(arr[left]%2==1)) { left++; } // 从后往前找,找一个奇数,找到后停止 while((left<right)&& (arr[right]%2==0)) { right--; } // 如果偶数和奇数都找到,交换这两个数据的位置 // 然后继续找,直到两个指针相遇 if(left<right) { tmp = 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个字节的空间来做这个tmp strcpy(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); //整体逆序 }
这样就舒服多了。