目录
一、整数加逗号
1.原题
对于一个较大的整数 N(1<=N<=2,000,000,000)
比如 980364535,我们常常需要一位一位数这个数字是几位数,但是如果在这 个数字每三位加一个逗号,它会变得更加易于朗读。因此,这个数字加上逗号成如下的模样:980,364,535请写一个程序帮她完成这件事情
样貌:题目意思就是每三位数就加一个逗号
2.思路
- 利用数组存放加了逗号之后的数字
- 一位位存入数组中,每存放三位,就往数组中存放一个逗号
- 利用%10得到最低位数字,/10去掉最低位的数字,从后往前存入数字
- 再将数组逆序打印就可以得到目标
将每一位数字放入字符数组中,利用%10得到最后一位,/10去掉最后一位。最后再逆序打印数组即可。
3.完整代码
cpp
#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)思路
- 定义三个数组,第一个是被查重的数组,第二个是存放标记的数组,第三个是存放删除公共字符串后的数组
cpp
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)完整代码
cpp
#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读取字符串,定义两个数组即可
cpp
char arr1[101] = { 0 };
char arr2[101] = { 0 };
gets(arr1);
gets(arr2);
- 遍历第一个数组,用函数判断字符是否相等,相等则返回某个值,再打印出来
cpp
int i = 0;
while (arr1[i])
{
if (my_str(arr1[i], arr2) == 0)
{
printf("%c",arr1[i]);
}
i++;
}
- 字符比较函数:同样需要一个个遍历
cpp
int my_str(char arr1,char arr2[])
{
int i = 0;
while (arr2[i++])
{
if (arr1 == arr2[i])
return 1;
}
return 0;
}
(2)完整代码
cpp
#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)完整代码
cpp
#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)完整代码
cpp
#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函数
如:
cpp
char arr[101] = { 0 };
gets(arr);
【传参】
在写函数前,我们需要传参,也就是需要知道字符串的头跟尾,于是:
cpp
int len =strlen(arr);
reverse(arr,arr+len-1);
【完成逆置字符串函数】
有了首位指针,我们就可以逐个交换,直到达到某个条件。下面的代码就是类型两个变量的交换,借助第三方,不断循环交换的过程:
cpp
void reverse(char* left,char* right)//逆置整个字符串
{
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
条件的注意点:当只剩下一个字符没有被交换的时候,也就是left==right的时候,他们是不需要交换的。
(2)逆置每个单词
【传参】这次的传参就只需要传字符串的首地址即可
cpp
recerse(arr);
void recerse(char* ptr1)
【定位每个单词】
- 现在我们需要逆置每个单词,把这个单词看成一个字符串(空格不需要逆置),所以需要找到这个单词的首跟尾
- 因为每个单词后面不是空格就是\0,所以根据这两个条件找尾
- 找到尾之后,需要记录尾后面的位置,方便下次找到下个单词
找尾:
cpp
char* left=ptr1;//头
char* right = ptr1;//尾
char* p = NULL;//记录空格或\0位置
while (*right != ' '&&*right!='\0')//找空格
{
right++;
}
p = right--;//找到了尾并记录空格位置
逆置该单词:直接调用刚才所撰写的逆置字符串函数即可,这就完成了一个单词的逆置
cpp
reverse(left, right);
逆置所有单词:这就需要用到循环
cpp
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.完整代码
cpp
#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;
}