C语言刷题:整数加逗号、删除公共字符、求最小公倍数和将字符串倒置

简介: C语言刷题:整数加逗号、删除公共字符、求最小公倍数和将字符串倒置



一、整数加逗号

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;
}
相关文章
|
2天前
|
C语言
【C语言】字符分类函数与字符转换函数
【C语言】字符分类函数与字符转换函数
7 1
|
3天前
|
C语言 C++
C语言利用ASCII码表统计字符串每个字符出现的次数
C语言利用ASCII码表统计字符串每个字符出现的次数
7 0
|
3天前
|
C语言
C语言刷题1
C语言刷题1
|
3天前
|
C语言
C语言:字符函数和字符串函数(strlen strcat strcmp strncmp等函数和模拟实现)
C语言:字符函数和字符串函数(strlen strcat strcmp strncmp等函数和模拟实现)
|
24天前
|
存储 C语言
【我爱C语言】详解字符函数isdigit和字符串转换函数(atoi和snprintf实现互相转换字符串)&&三种strlen模拟实现1
【我爱C语言】详解字符函数isdigit和字符串转换函数(atoi和snprintf实现互相转换字符串)&&三种strlen模拟实现
|
1月前
|
C语言
C语言第二十五弹---字符函数和字符串函数(上)
C语言第二十五弹---字符函数和字符串函数(上)
|
18天前
|
程序员 C语言
C语言库函数 — 内存函数(含模拟实现内存函数)
C语言库函数 — 内存函数(含模拟实现内存函数)
29 0
|
29天前
|
编译器 C语言 C++
【C语言】memset()函数(内存块初始化函数)
【C语言】memset()函数(内存块初始化函数)
27 0
|
3天前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
2天前
|
程序员 编译器 C语言
C语言之函数与参数
C语言之函数与参数
5 0