LeetCodeGOGOGO刷题记03——代码优化(利用字符串流和c++11新功能来处理字符串)

819. Most Common Word

难度:

Medium

思路:

字符串处理问题,预先排除一部分单词,组成单词库(banned),要求找出一篇文章中出现最多的非banned单词(大小写不敏感)。

这题思路也十分清晰,首先处理文章,将其处理成一个一个单词,并全部转化为小写,然后依次插入unordered_map中,最后遍历map得到结果

其实这题的难度不大,然而常规代码并不简单,洋洋洒洒一不小心五六十行就下来了

代码:

/*
Author Owen_Q
*/

class Solution {
public:
    string mostCommonWord(string paragraph, vector<string>& banned) {
        re.clear();
        int st = 0;
        int plen = paragraph.size();
        while(st<plen)
        {
            if(ischa(st,paragraph))
            {
                int pos = 0;
                string words = "";
                for(;st+pos<plen;pos++)
                {
                    if(ischa(st+pos,paragraph))
                    {
                        if(isupcha(st+pos,paragraph))
                            paragraph[st+pos] += 'a'-'A';
                        words += paragraph[st+pos];
                    }
                    else
                        break;
                }
                if(find(banned.begin(),banned.end(),words)==banned.end())
                {
                    re[words]++;
                    //cout << words <<endl;
                }
                st += pos+1;
            }
            else
                st++;
        }
        
        string rewords;
        int renum = 0;
        for(auto it=re.begin();it!=re.end();it++)
        {
            if((*it).second>renum)
            {
                renum = (*it).second;
                rewords = (*it).first;
            }
        }
        return rewords;
    }
private:
    unordered_map<string,int> re;
    
    bool ischa(int a, string paragraph)
        {
            if((paragraph[a]>='a'&&paragraph[a]<='z')||(paragraph[a]>='A'&&paragraph[a]<='Z'))
                return true;
            else
                return false;
        }
    
    bool isupcha(int a, string paragraph)
        {
            if(paragraph[a]>='A'&&paragraph[a]<='Z')
                return true;
            else
                return false;
        }
    
};

于是下面来研究一下代码的优化

 

字符串流和字符串处理函数回顾:

istringstream:

istringstream(string str)

字符串流并不是c++11的新功能,但确实是一个很容易被忽略却又十分好用的功能

该字符串流以空格作为分隔,可以将一个完整字符串分隔成多个小字符串,类似于标准输入流那样,这样就使得字符串的分隔变得十分容易,而不用再想原来那样按字符串内元素一个个手动分隔

ctype.h:

ctype.h这个库函数里确实有很多很巧的函数,虽然实现起来也不难,但充分运用这些函数可以使得代码变得十分简洁

主要有这些常用函数:

isalpha()判断字符是否为字母(大小写)

isnum()判断字符是否为数字;

ispunct()判断字符是否为特殊符号

islower()判断字符是否为小写字母

isupper()判断字符是否为大写字母

tolower()将大写字母转换为小写字母

toupper()将小写字母转换为大写字母

c++11知识回顾:

auto:

自动类型判断,其实这个功能十分简单,主要就是不用在自己定义变量类型,而是编译器可以根据传入变量的值自动判断。这个功能的好处主要就体现在长变量声明的简洁性上,比如iterator的声明,使用auto就完全可以省略冗长的iterator声明,使得代码变得十分清晰简洁

for:

for(declaration:expression)

c++11也对for循环进行了升级,除了最原始的for( ; ; )使用方式,现在也可以使用类似于python中for循环in的使用方式。这使得数组遍历变得,尤其是字符串处理变得十分方便

注意,若想改变declaration的值,记得加入引用符号

代码提升:

首先当然是字符串处理,利用for的新特性,将所有大写字母处理成小写字母,将所有非字母处理成空格用于字符串流的分隔

接着转成字符串流进行处理,对于每个单词依旧扔入unordered_map中,并在每次传入的过程中均进行一次判断,以剩下最后统一判断的代码

简单两步即可完成,整个代码变得十分清晰美观

代码:

/*
Author Owen_Q
*/

class Solution {
public:
    string mostCommonWord(string paragraph, vector<string>& banned) {
        for(auto &c: paragraph)
            c = isalpha(c)? tolower(c): ' ';
        istringstream iss(paragraph);
        string words, rewords;
        int renum = 0;
        re.clear();
        while(iss >> words)
        {
            if(find(banned.begin(),banned.end(),words)==banned.end())
            {
                re[words]++;
                if(re[words]>renum)
                {
                    renum = re[words];
                    rewords = words;
                }
            }
        }
        return rewords;
    }
private:
    unordered_map<string,int> re;
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值