算法设计与应用基础 - Week01

算法设计与应用基础 - Week01

博客动机

其实一直挺想开个技术博客,一方面可以整理自己的知识库,一方面也可以通过交流、填坑来激励自己的成长。不过就像林老师说的那样,觉得发表到博客上的东西必须经得起考验,而自己恰恰没有那么扎实的基础,所以迟迟没有行动。

这次因为课程的原因,不得不把自己浅薄的见解发表于此,希望能够以此为契机,养成写博客的习惯:);也希望自己能够成为一个负责任的博主,博文里大概会有许多错误,希望各位朋友、同学能够指出,我会坚持修补的 √

第一周目标

自数据结构课程结束以来几乎就没有用过C++了,要么是操作系统实验里连库都要自己写的C语言,要么是实验室里的Python,总的来说,C++已经完全荒废了…orz

所以前几周主要是让自己重新熟悉C++,不去挑选特定类别的题目,而是使用LeetCode的Pick One功能来随机选择。

LeetCode 385. Mini Parser

抽到的第一题题意很直观,也就是解析字符串并用题目给定的类表示出来;字符串有两种类型,一种表示单整数,另一种表示嵌套列表类型。

观察给定类的接口

因为题目要求最终结果用给定的类表示,首先要理清给定类的接口。简单梳理一下类的接口,可以表示成下面的结构图(这种表示方法或许不太规范,如果同学们有简明规范的表示方法,希望能给我安利一下~)。

class NestedInteger
  |--- Constructor
  |    |--- NestedInteger()
  |    |--- NestedInteger(int value)
  |
  |--- Single Integer
  |    |--- isInteger(): bool const
  |    |--- getInteger(): int const
  |    |--- setInteger(int value): void
  |
  |--- Nested Integer
  |    |--- add(const NestedInteger &ni): void
  |    |--- getList(): const vector<NestedInteger> & const

因为这题只涉及列表的构造,基本上只需要用到两个构造函数以及成员函数add,其他暂时就不需要理会了。

解析单整数

单整数的解析非常简单,题目给出

String contains only digits 0-9, [, - , ,, ].

因此负数也包括在内,解析单整数的时候需要先判断符号,然后依次解析数字。用一个成员函数表示如下:

int parseNum(string s) {
    if (s.empty()) return 0;

    bool is_neg = false;
    int i, num = 0;

    if (s[0] == '-') is_neg = true, i = 1;
    else i = 0;

    for (; i < s.size(); i++) {
        num *= 10;
        num += (s[i] - '0');
    }

    return is_neg == true ? -num : num;
}

使用递归解析嵌套列表

解决嵌套问题一个最直观的方法便是递归,递归基可以是单个整数,也可以是空。前面已经写出了单整数的解析函数,这部分只要把递归步表示出来就可以了。

问题在于如何表示递归步。可以观察到,一个嵌套列表总是由成对 [] 包围,处理一个嵌套列表的字符串时,只需要考虑字符串下标为 [1, size - 1) 的部分就可以了。

如果元素是单整数,那么子串的首位一定不是 [ ,遇到字符 , 或字符串遍历完成则表示到达子串的尾部,得到子串在字符串中的首位和尾部即可以将其作为递归步的输入。

beg = i;
/* other codes */
// A single integer
else if (s[i] != '[') {
    i++;
    for (; i < s.size() - 1; i++) {
        if (s[i] == ',') break;
    }
    out.add( deserialize( s.substr(beg, i - beg) ) );
}

如果元素是嵌套列表,那么要统计 [] 出现的次数。使用变量 cnt 进行计数,遇到字符 [ 时变量 cnt 加1,遇到字符 ] 时变量 cnt 减1,一旦变量 cnt 的值为0,则表示获得了一个嵌套列表子串。

// A nested list
else {
    cnt = 1; i++;
    for (; i < s.size() - 1; i++) {
        if (s[i] == '[') cnt++;
        else if (s[i] == ']') {
            cnt--;
            if (cnt == 0) {
                i++;
                break;
            }
        }
    }
    out.add( deserialize( s.substr(beg, i - beg)) );
}

完整代码如下:

class Solution {
public:
    NestedInteger deserialize(string s) {
        if (s.empty()) return NestedInteger();
        if (s[0] != '[') return NestedInteger( parseNum(s) );

        NestedInteger out;
        int beg, cnt;

        for (int i = 1; i < s.size() - 1; i++) {
            beg = i;

            if (s[i] == ',');
            else if (s[i] == ']');

            // A single integer
            else if (s[i] != '[') {
                i++;
                for (; i < s.size() - 1; i++) {
                    if (s[i] == ',') break;
                }
                out.add( deserialize(s.substr(beg, i - beg)) );
            }

            // A nested list
            else {
                cnt = 1; i++;
                for (; i < s.size() - 1; i++) {
                    if (s[i] == '[') cnt++;
                    else if (s[i] == ']') {
                        cnt--;
                        if (cnt == 0) {
                            i++;
                            break;
                        }
                    }
                }
                out.add( deserialize( s.substr(beg, i - beg)) );
            }
        }

        return out;
    }

    int parseNum(string s) {
        if (s.empty()) return 0;

        bool is_neg = false;
        int i, num = 0;

        if (s[0] == '-') is_neg = true, i = 1;
        else i = 0;

        for (; i < s.size(); i++) {
            num *= 10;
            num += (s[i] - '0');
        }

        return is_neg == true ? -num : num;
    }
};

第一次写太过啰嗦了…有空的时候精简一下…orz

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值