每日一题 11.11 删除注释

每日一题 11.11 删除注释

一、题目概述

今天早上起床的时候,我看见每日一题的群里有人说,今天这个题我根本看不懂,我就很慌,觉得群里大佬都不会我感觉我也不能会。。。但是到了教室,看了一眼,发现是中档题,涉及到数组和字符串,我又感觉我行了,打开题目真正开始写,发现我一个测试点都没过,我感觉我才是真正的消愁。。。

顺便说一下,双十一采购的东西已经到了一部分了,其中包括一个我觉得能顺利叫我起床的华为手环,七十块钱,也能记录日常跑步的数据,蛮划算的,今天就是他把我叫起来的。

二、个人思路

我的思路是这样的,因为题目把代码设计成一组字符串的形式,那我只需要看这个字符串的前两个字符就好了,要是前两个字符是 “//” ,那我们直接删除那个字符串,用vector.erase()函数,如果前两个字符是 “/*” ,那我们就需要找最后两个字符是 “*/” 的字符串,然后把这中间(包括两端)的字符串全部删掉,我的代码也确实是这样的实现。

class Solution {
public:
    vector<string> removeComments(vector<string>& source) {
        for(int i=0;i<source.size();i++){
            if(source[i][1]=='/'&&source[i][2]=='/'){
                source.erase(source.begin()+i);
            }
            if(source[i][1]=='/'&&source[i][2]=='*'){
                while(source[i][source[i].length()-1]=='*'&&source[i][source[i].length()]=='/'){
                    source.erase(source.begin()+i);
                    i++;
                }
            }
        }
        return source;
    }
};

但是一个测试点都没过,我不知道为什么,是因为我string库函数不对吗,不应该呀。

希望有大佬能帮帮我看一下。。。谢谢大家

(追更:我发现了一个很低级的错误,字符串的开头的位置是0,但是我写成了1,很影响判断。。。虽然把这个错误改了,也只通过了一个点,但这个问题很低级也很严重,我要更细心才是。)

三、大佬思路

这个题的风评好像也不是很好。。。不少人说这个题出的多少沾点hhhh,我不过多评价了,我能学到知识就好。

我找到了两种思路,一种是分类讨论法,一种是我从没见过的船新思路——状态机法。

我们先看第一种,分类讨论法:


class Solution {
public:
    vector<string> removeComments(vector<string>& source) {
        bool isComment = false;
        vector<string> res;
        string curr = "";
        for (string s : source)
        {
            // cout << s << endl;
            int i = 0;
            if (!isComment)
            {
                curr = "";
            }
            int n = s.size();
            while (i < n)
            {
                if (!isComment && i < n-1 && s[i] == '/' && s[i+1] == '*')
                {
                    isComment = true;
                    // 继续找下去,这里实际要+2,但是后面会+1
                    ++i;
                }
                else if (isComment && i < n-1 && s[i] == '*' && s[i+1] == '/')
                {
                    isComment = false;
                    // 继续找下去,这里实际要+2,但是后面会+1
                    ++i;
                }
                else if (!isComment && i < n-1 && s[i] == '/' && s[i+1] == '/')
                {
                    break;
                }
                else if (!isComment)
                {
                    curr += s[i];
                    // cout << curr<< " " << endl;
                }
                
                ++i;
            }
            if (!isComment && !curr.empty())
            {
                res.push_back(curr);
            }
        }
        return res;
    }
};

作者:ffreturn
链接:https://leetcode.cn/problems/remove-comments/solution/722-cchao-100de-fen-lei-tao-lun-jie-fa-b-ktak/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

其中isComment是标志位,如果当前字符串是注释“/**/”形式,那么标志位置true,直到找到最后两个是*/的,我们再把标志位置false。如果是注释“//”形式,那么不用管。如果不是注释,那么将当前字符串载入到一个新的vector容器。

跟我那个思路差不多,但是实现方式不太一样,看来我还是要多学习大佬的编码方式。

第二个方法,状态机法:

这个方法我没理解,我把代码粘在这里了,好像跟编译原理有关?我还没学暂时看不懂。

class Solution {
public:
    vector<string> removeComments(vector<string>& source) {
        string cur, status = "str";
        vector<string> res;
        for (string s : source) {
            for (char ch : s) {
                if (status == "str") {
                    if (ch == '/') {
                        status = "pre";
                    }
                    else cur += ch;
                }
                else if (status == "pre") {
                    if (ch == '/') {
                        status = "str";
                        break;
                    }
                    else if (ch == '*') {
                        status = "block";
                    }
                    else {
                        status = "str";
                        cur += '/';
                        cur += ch;
                    }
                }
                else if (status == "block") {
                    if (ch == '*') status = "block_end_pre";
                }
                else if (status == "block_end_pre") {
                    if (ch == '/') status = "str";
                    else if (ch != '*') status = "block";
                }
            }
            if (status == "pre") {
                cur += '/';
                status = "str";
            }
            else if (status == "block_end_pre") status = "block";
            //cout << status << endl;
            if (cur.size() != 0 && status == "str") {
                res.push_back(cur);
                cur = "";
            }
        }
        return res;
    }
};

作者:charon____
链接:https://leetcode.cn/problems/remove-comments/solution/c-0ms-zhuang-tai-ji-by-charon____/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

四、总结 

这个题目没什么好总结的,因为没学到什么新语法新知识。

主要想表达一下最近的计划。因为期末临近嘛,然后我这边计划是数学就先放一放,优先学两个专业课,这两个专业课我确实是想加油满绩,所以中心要往那边靠。但每日一题不会断,可能质量会下降吧,我也不好说,我尽量两边都兼顾。

就这样,大家加油。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值