【力扣每日一题】2023.8.3 删除注释

目录

题目:

示例:

分析:

代码:


题目:

示例:

分析:

这道题属于模拟题,我们实际运用场景是使用正则表达式,并且我看评论区也有不少大佬也是用的正则,而我就是用最土的办法直接模拟了,然后写出了五十多行的屎山代码,我这办法一定不是最好的办法,在这边分享出来也算是给大家提供一种思路,在碰到这类题想不到其他更妙的办法也可以用咱这土办法来做出来。

这道题让我们把代码里的注释删掉,并且不用考虑无效的情况,也不用考虑注释在双引号里的情况,那难度其实不大,就是很磨人,要注意一些细节,一个是处理好注释嵌套的问题,另一个就是行注释可能会把代码里换行符一起注释掉,我们在删除块注释的同时,还需要处理没有换行符而要把两行拼接在一起的情况。

那大概了解情况以后我们就开始按行遍历代码,如果遇到了行注释,那倒比较简单,直接把本行的行注释后面的内容全删了,不过行注释不删换行符,我们不需要做合并代码行的操作。

如果遇到了块注释的开头标记"/*'',那么我们需要做两个操作,一个是记录当前坐标,用于删除注释,另一个是标记接下来的代码属于块注释的范围,只要没遇到块注释的结尾标记,则其他符号都是不用管的.

然后最关键的点在于遇到了块注释的结尾标记我们怎么处理,首先是我们之前有做块注释的开头标记的坐标的缓存,我们把块注释的首尾行号做比较,把它们中间的代码行全变成空字符串,至于为什么不直接删了,这是因为遍历行我们是用的for循环,直接删掉代码行会直接影响代码的行数,会影响for循环,所以我们这边是将删除的代码先变成空字符串,然后最后再遍历一次代码,把空字符串的行都删了.

其次是把块注释的开头标记的那一行代码中开头标记之后的代码删了,还有就是把块注释的结尾标记的那一行中结尾标记之前的代码都删了.

然后如果块注释的开头标记和结尾标记不在同一行,则块注释会把换行符删了,我们需要记录合并代码的那两行的行数.

遍历完代码之后我们还需要做一个收尾工作,第一个就是合并因为块注释删除了换行符而需要合并的两行.

最后就是把代码里的空字符串删除.

因为我们是原地修改的,因此直接把传入进来的代码再返回出去即可.

还有一个办法我就简单提一下,写出来也是屎山代码不过第第一种方法的代码少一点,但是运行速度满了好多.

就是先把代码拼接成一个字符串,然后在每行代码中间穿插一个特殊字符表示换行符,然后在同一行里处理注释会稍微方便一点,不用特地考虑换行符的问题,因为我们把换行符给具象了出来.

然后最后再按照我们设置的特殊字符来分割那个字符串即可.

代码:

class Solution {
public:
    vector<string> removeComments(vector<string>& source) {
        vector<int>block(0);    //记录块注释的开头坐标
        bool haveBolck=false;   //记录是不是在块注释中
        vector<vector<int>>needMerge;   //记录因为块注释删除了换行符而需要合并的两行
        for(int i=0;i<source.size();i++){
            int j=0;
            while(j<source[i].size()){  //因为遍历每行可能会删除一些元素,会改变source[i]的大小所以不能用for
                if(source[i][j]=='*'&&haveBolck&&source[i][j+1]=='/'){  //如果遇到了块注释的末尾,并且正在块注释中,则开始删除块注释
                    for(int c=block[0]+1;c<i;c++){
                        source[c]="";
                    }
                    if(block[0]+1<i) needMerge.push_back({block[0],i}); //记录需要合并的两行
                    if(block[0]==i){    //如果块注释在同一行
                        source[i].erase(block[1],j-block[1]+2);
                        j=block[1];
                    }else { //如果块注释不在 同一行
                        source[block[0]].erase(block[1],source[block[0]].size()-block[1]);
                        source[i].erase(0,j+2);
                        j=0;
                    }
                    haveBolck=false;
                    continue;
                }
                if(haveBolck){  //如果不是上面块注释的末尾,并且处于块注释中,直接跳过
                    j++;
                    continue;
                }
                if(source[i][j]=='/'){  //有/直接检查是否有注释
                    if(source[i][j+1]=='/'){    //行注释直接删除本行后面的部分
                        source[i].erase(j,source[i].size()-j);
                        break;
                    }else if(source[i][j+1]=='*'){  //块注释记录开头的坐标
                        haveBolck=true;
                        block={i,j};
                    }
                    j++;
                }
                j++;
            }
        }
        for(auto& a:needMerge){ //合并需要合并的行
            source[a[0]]+=source[a[1]];
        }
        for(int i=0;i<needMerge.size();i++){    //清除合并行之间的最后一行,因为上面合并是把下面的行加到上面的行
            source.erase(source.begin()+needMerge[i][1]+i);
        }
        int index=0;
        while(index<source.size()){ //清除空字符串的行
            if(source[index]=="") source.erase(source.begin()+index);
            else index++;
        }
        return source;
    }
};
//拼接字符串来做处理
        string newSourec="";
        for(auto& s:source){
            newSourec+=s+"&";
        }
        int index=0;
        bool b=false,h=false;
        while(index<newSourec.size()){
            if(b||h){
                if(h&&newSourec[index]=='&'){
                    index++;
                    h=false;
                }else if(b&&newSourec[index]=='*'&& newSourec[index+1]=='/'){
                    b=false;
                    newSourec.erase(index,2);
                }else{
                    newSourec.erase(index,1);
                }
                continue;
            }
            if(newSourec[index]=='/'){
                if(newSourec[index+1]=='/'){
                    newSourec.erase(index--,2);
                    h=true;
                }else if(newSourec[index+1]=='*'){
                    newSourec.erase(index--,2);
                    b=true;
                }
            }
            index++;
        }
        vector<string>res;
        string temp="";
        for(auto& c:newSourec){
            if(c=='&'){
                if(temp!=""){
                    res.push_back(temp);
                }
                temp="";
            }else{
                temp+=c;
            }
        }
        return res;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值