您当前的位置: 首页 >  蓝桥杯

[蓝桥杯][算法提高VIP]去注释

发布时间:2021-07-28 15:45:03 ,浏览量:9

题目

题目链接

题解

模拟?

先说明一下不考虑printf中输出的/等情况,不要将输入理解为代码,而是理解为若干行字符串,去掉/**/内部的内容和去掉//所在行之后的内容。

我们分为三部分实现(我将按我的思考过程讲述):

一、我们最先能想到的就是判断注释部分是否开始。

注释分两种,一种是/**/,另一种是//。开始条件很明显,第一种遇到/*开始,第二种遇到//开始。当然这俩字符也不能输出。

若当前获取到的字符c为/,那么我们立即再获取下一个字符cc,

  • 若cc是/说明//开始了,用标记two = 1表示//开始,continue掉即可;
  • 若cc是*说明/*开始了,用标记one = 1表示/*开始,continue掉即可;
  • 若 不满足上面两种情况,即else,那么输出一下c和cc。

否则(当前获取到的字符c不是/),那么正常输出c即可。

PS: 可能有人会有疑惑,一次获取两个,万一c和cc无法配成/*或//,但是cc和下一个字符说不定就配成了,那你现在把cc提前取出来并输出了,不会出错吗

答案是不会的,反证一下:因为如果要上述的错误,即c和cc无法匹配,而cc和下一个字符匹配成功。因为cc和下一个字符匹配成功,那么就要保证cc是/才行。进入获取cc语句的前提是c为/,如果cc是/,那么c和cc必然匹配成功啊,这不与c和cc无法匹配的条件相违背嘛。因此不用存在这方面的疑虑。

二、 注释部分

这部分比较好考虑,根据标记我们可以轻松判断出是否处于注释部分,处于注释部分什么也不用输出直接continue就行。

三、 判断注释是否结束

两种注释对应的结束条件分别是*/和'\n'。

  • */的判断:先保证one == 1说明处于第一种注释状态,再判断当前字符c的前一个字符是否为星号(这时候我们就不能取c的后一个字符判断是否匹配了,因为这时候多取一个字符是不满足上述PS部分证明的)。如果前一个字符为星号且c为/则结束注释,重置标记,continue。
  • '\n'的判断:先保证two == 1说明处于第二种注释状态,若当前字符c是回车符,则输出回车符,重置标记,continue即可。

三部分的思路都明白了,但实际上三段代码顺序应该为“三”、“二”、“一”。 判断结束在前,其次是注释部分continue,最后才是判断开始。 这个你应该可以自己理解。

最后给个样例,这个对了应该就AC了(我觉得)

abscasc//daw/*dawdaw*/ /dawda*/ /*/abdwh
dawda
*/dawdaw
daw/*//a/b/c//*/dawd /*//dawda 

看高亮就知道哪些该输出哪些不该输出了。 在这里插入图片描述

在这里插入图片描述

代码
#include using namespace std; char c; int xing, two, one; // xing代表获取的当前字符c的前一个字符是否为星号    one代表 /**/ 注释    two代表 // 注释  int main() { while((c=getchar()) != EOF) { // 判断注释结束  if(two && c=='\n') { two = 0; putchar(c); continue;} // 把回车输出一下  else if(one) { if(xing && c=='/') { one = 0; xing = 0; continue;} if(c=='*') xing = 1; else xing = 0; // 每次获取的不是星号后都要修改  } // 注释部分 continue  if(one || two) continue; // 判断注释开始:若符合开始条件则进行标记,不符合就正常输出字符  if(c=='/') { char cc = getchar(); if(cc == '/') { two = 1; continue; } else if(cc == '*') { one = 1; continue; } else { putchar(c); putchar(cc); continue; } } else putchar(c); } return 0; } 
关注
打赏
1688896170
查看更多评论

暂无认证

  • 9浏览

    0关注

    115984博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0830s