C语言每日一练
2021年11月15日
题目描述
现在有一串字符需要输入,规定输入的字符串中只包含字母和*号。请编写程序,实现以下功能:除了字符串前后的*号之外,将串中其他的*号全部删除。
例如,假设输入的字符串为****A*BC*DEF*G********,删除串中的*号后,字符串变为****ABDEFG********
分析
我的思路:
一个简单直观的方法:新建一个用来输出的字符数组,将符合条件
的字符存入数组再输出即可。
字符串开头的*
号,我们可以通过一个指针来遍历
,如果指针指向的字符是*
号,则将其存入输出数组中,直到检测到非*
号的字符,但这种单向遍历的方法不好判断字符串尾部的*
号,比如***aaa***bb***
,字符串中间是连续的*
,和尾部的*
号没有很明显的差别,这时单个字符的检测就不方便了。
但是,我们可以在定义一个右指针
,从字符串最后的字符向前遍历
,直到检测到非*
的字符,这时它就指向尾部*
号起点的前面,这时左指针和右指针之间的字符即为中间区域
。
【右指针向前移动要考虑是否会出界,可以和原字符串或左指针进行地址比较,避免出现越界问题】
最后,将字符串中间区域
的非*
字符和以右指针开头的字符串存入输出字符数组即可。
代码实现
代码的核心步骤
- 右指针向左移动,直到非
*
位置或字符串开头,如果到了字符串开头,直接输出原字符串。- 左指针向右移动,将
*
存入输出字符数组,直到非*
的位置。- 将中间区域的非
*
字符存入输出字符数组。- 将右指针指向的字符串存入输出字符数组。
#include <stdio.h>
#include <string.h>
#define MAX_LANGTH 50 //字符数组最大长度
int main()
{
char str[MAX_LANGTH] = {0}; //目标字符串
char *str_left = str; //从左向右判断*号
char *str_right = NULL; //指向尾部*的起点
char str_tmp[MAX_LANGTH] = {0}; //结果字符数组
int i = 0;
printf("请输入一个字符串,必须带*号\n");
gets(str);
str_right = &str[strlen(str) - 1]; //指向字符串末尾
/* 尾部指针向左移动,直到没有检测到*号或到达字符串开头 */
while(*str_right == '*' && str_right != str_left)
str_right--; //移到到尾部*的起点之前
if(str_right == str_left) //如果字符串只有*号
{
printf("删除中间的*号后:%s\n", str);
return 0;
}
/* 头部指针向右移动,直到检测到非*的其他符号 */
while(*str_left == '*')
str_tmp[i++] = *str_left++; //将头部的*存入输出字符数组中
/* 开始删除字符串中间的*号 */
while(str_left != str_right) //判断范围为字符串中间区域
{
if(*str_left != '*')
str_tmp[i++] = *str_left; //将除*号以外的字符存入输出字符数组中
str_left++;
}
/* 将后面的所有字符都追加到输出字符串中 */
while(*str_right != '\0')
str_tmp[i++] = *str_right++;
str_tmp[i] = '\0'; //不要忘了'\0'
printf("删除中间的*号后:%s\n", str_tmp);
return 0;
}
运行结果
网上参考
这份代码没有新建字符数组,而是在原字符串上进行移位删除,具体实现思路见原文,链接如下:
原文链接:http://c.biancheng.net/cpp/html/3374.html
但是,这份代码有一个不足之处:没有考虑全是*
号的情况(见文末)。
#include <stdio.h>
int fun(char *a, char *h, char *p)
{
int i, j;
/*删除指针h与p之间的所有“*”*/
for(i=0,j=0; &h[i]<p; i++)
if(h[i]!='*')
h[j++]=h[i];
/*将指针p至字符串尾部的所有字符前移*/
for(i=0; p[i]; i++,j++)
h[j]=p[i];
h[j]='\0'; /*在字符串尾部添加结束标志*/
return 0;
}
int main( )
{
char s[81], *t, *f;
printf("Enter a string :\n");
gets(s); /*输入字符串*/
t=f=s; /*用字符指针t、f指向串s*/
while(*t)
t++;
t--; /*将指针t定位到字符串中最后一个字符*/
while(*t == '*') /*指针t指向字符串中最后一个字符*/
t--;
while (*f == '*') /*指针f指向字符串中第一个字符*/
f++;
fun(s, f, t);
printf("The string after deleted:\n"); /*输出结果*/
puts(s);
return 0;
}
如果输入一个只包含
*
号的字符串,程序将会进入死循环