一、整数加逗号
1.原题
对于一个较大的整数 N(1<=N<=2,000,000,000)
比如 980364535,我们常常需要一位一位数这个数字是几位数,但是如果在这 个数字每三位加一个逗号,它会变得更加易于朗读。因此,这个数字加上逗号成如下的模样:980,364,535请写一个程序帮她完成这件事情
样貌:题目意思就是每三位数就加一个逗号
2.思路
- 利用数组存放加了逗号之后的数字
- 一位位存入数组中,每存放三位,就往数组中存放一个逗号
- 利用%10得到最低位数字,/10去掉最低位的数字,从后往前存入数字
- 再将数组逆序打印就可以得到目标
将每一位数字放入字符数组中,利用%10得到最后一位,/10去掉最后一位。最后再逆序打印数组即可。
3.完整代码
#include<stdio.h> int main() { int N = 0;//需要加逗号的数字 scanf("%d",&N); char arr[15] = { 0 }; int i = 0; int k = 0;//记录三位数 while (N) { if (k != 0 && k % 3 == 0) { arr[i++] = ','; } arr[i++] = N % 10+'0'; N = N / 10;//去掉最后一位 k++; } //此时的i为指向数组的后一个位置,i==数组元素 for (--i;i>=0;--i) { printf("%c",arr[i]); } return 0; }
二、删除公共字符
1.题目
输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”
样貌:
原题链接:删除公共字符_牛客题霸_牛客网
2.第一种解法
(1)思路
- 定义三个数组,第一个是被查重的数组,第二个是存放标记的数组,第三个是存放删除公共字符串后的数组
char arr1[101] = { 0 }; char arr2[101] = { 0 }; char arr3[101] = { 0 };//存放重组后的字符 scanf("%[^\n]s",arr1);//删除arr1中的字符 getchar();//吸收回车字符 scanf("%[^\n]s",arr2);//标记 my_str(arr1,arr2,arr3);
- 每遍历第一个数组中的一个字符,就需要遍历整个第二个数组,与第一个数组中的一个字符一一对照,若都不相等,则存放到第三个数组中
- 每次对照结束,第二个数组的指针需要回到起始位置
(2)完整代码
#include<stdio.h> void my_str(char* arr1,char* arr2,char* arr3) { char* p1 = arr1; int i = 0; while (*p1 != '\0')//遍历第一个数组 { int tmp = 1; char* p2 = arr2;//保证数组2每次回到起始位置 while (*p2 != '\0')//遍历第二个数组 { if (*p1 != *p2) { p2++; } else { tmp = 0; break; } } if (tmp)//不相等就存入第三个数组 { arr3[i++] = *p1; } p1++; } printf("%s\n", arr3); } int main() { char arr1[101] = { 0 }; char arr2[101] = { 0 }; char arr3[101] = { 0 };//存放重组后的字符 scanf("%[^\n]s",arr1);//删除arr1中的字符 getchar();//吸收回车字符 scanf("%[^\n]s",arr2);//标记 my_str(arr1,arr2,arr3); return 0; }
3.第二种解法
(1)思路
- 用gets读取字符串,定义两个数组即可
char arr1[101] = { 0 }; char arr2[101] = { 0 }; gets(arr1); gets(arr2);
- 遍历第一个数组,用函数判断字符是否相等,相等则返回某个值,再打印出来
int i = 0; while (arr1[i]) { if (my_str(arr1[i], arr2) == 0) { printf("%c",arr1[i]); } i++; }
- 字符比较函数:同样需要一个个遍历
int my_str(char arr1,char arr2[]) { int i = 0; while (arr2[i++]) { if (arr1 == arr2[i]) return 1; } return 0; }
(2)完整代码
#include<stdio.h> int my_str(char arr1,char arr2[]) { int i = 0; while (arr2[i++]) { if (arr1 == arr2[i]) return 1; } return 0; } int main() { char arr1[101] = { 0 }; char arr2[101] = { 0 }; gets(arr1); gets(arr2); int i = 0; while (arr1[i]) { if (my_str(arr1[i], arr2) == 0) { printf("%c",arr1[i]); } i++; } return 0; }
三、求最小公倍数
1.题目
正整数 a 和正整数 b 的最小公倍数,是指能被 a 和 b 整除的最小的正整数。请你求 a 和 b 的最小公倍数。
比如输入5和7,5和7的最小公倍数是35,则需要返回35。
全貌:
原题链接:求最小公倍数_牛客题霸_牛客网
2.第一种解法
(1)思路
- 直接利用最小公倍数的性质:用来除那两个数都可以整除。
- 其中最小的公倍数一定是他们其中最大的那个数;最大的最小公倍数一定是他们的乘积
- 利用以上性质,不断循环和试除
(2)完整代码
#include<stdio.h> int main() { int a = 0, b = 0; scanf("%d%d",&a,&b); int max = a > b ? a : b;//找出大的数 while (1) { if (max % a == 0 && max % b == 0)//从他们之间大的数开始 break;//直到找到,退出循环 max++; } printf("%d\n",max); return 0; }
3.第二种解法
(1)思路
利用下面图片的原理
(2)完整代码
#include<stdio.h> int main() { int a = 0, b = 0; scanf("%d%d",&a,&b); int ret = 1; while (ret) { if (ret * a % b == 0) break; ret++; } printf("%d\n",ret*a); return 0; }
四、倒置字符串
1.题目
将一句话的单词进行倒置,标点不倒置。比如 "I like beijing.",经过处理后变为:"beijing. like I"。字符串长度不超过100。
全貌:
2.思路
我们有两种思路,第一种是先将整个字符串逆置,再将每个单词逆置;第二种就是先将每个单词逆置,最后再整体逆置。我们下面采用第一种。
(1)先逆置整个字符串
【输入字符串】
我们观察题目,发现字符串有多个空格,而我们的sacnf函数是不方便输入空格的,所以我们使用gets函数
如:
char arr[101] = { 0 }; gets(arr);
【传参】
在写函数前,我们需要传参,也就是需要知道字符串的头跟尾,于是:
int len =strlen(arr); reverse(arr,arr+len-1);
【完成逆置字符串函数】
有了首位指针,我们就可以逐个交换,直到达到某个条件。下面的代码就是类型两个变量的交换,借助第三方,不断循环交换的过程:
void reverse(char* left,char* right)//逆置整个字符串 { while (left < right) { char tmp = *left; *left = *right; *right = tmp; left++; right--; } }
条件的注意点:当只剩下一个字符没有被交换的时候,也就是left==right的时候,他们是不需要交换的。
(2)逆置每个单词
【传参】这次的传参就只需要传字符串的首地址即可
recerse(arr); void recerse(char* ptr1)
【定位每个单词】
- 现在我们需要逆置每个单词,把这个单词看成一个字符串(空格不需要逆置),所以需要找到这个单词的首跟尾
- 因为每个单词后面不是空格就是\0,所以根据这两个条件找尾
- 找到尾之后,需要记录尾后面的位置,方便下次找到下个单词
找尾:
char* left=ptr1;//头 char* right = ptr1;//尾 char* p = NULL;//记录空格或\0位置 while (*right != ' '&&*right!='\0')//找空格 { right++; } p = right--;//找到了尾并记录空格位置
逆置该单词:直接调用刚才所撰写的逆置字符串函数即可,这就完成了一个单词的逆置
reverse(left, right);
逆置所有单词:这就需要用到循环
void recerse(char* ptr1) { char* left=ptr1;//头 char* right = ptr1;//尾 char* p = NULL;//记录空格位置 while (*left!='\0') { while (*right != ' '&&*right!='\0')//找空格 { right++; } p = right--;//记录尾 reverse(left, right); left = right = ++p;//重新找下个单词的首部 } }
直到首部找到\0,程序结束
3.完整代码
#include<stdio.h> #include<string.h> void reverse(char* left,char* right)//逆置整个字符串 { while (left < right) { char tmp = *left; *left = *right; *right = tmp; left++; right--; } } //逆置每个单词 void recerse(char* ptr1) { char* left=ptr1;//头 char* right = ptr1; char* p = NULL;//记录空格位置 while (*left!='\0') { while (*right != ' '&&*right!='\0')//找空格 { right++; } p = right--; reverse(left, right); left = right = ++p; } } int main() { char arr[22] = { 0 }; gets(arr); int len =strlen(arr); reverse(arr,arr+len-1); recerse(arr); printf("%s\n",arr); return 0; }