Contents

ARST打卡第246周

lc2788_按分隔符拆分字符串 Solana Whitepaper Explained 如何压缩与解压.tar.gz格式的文件 RPC server端回包是不用显示调用发包的,一般由框架封装

Algorithm

lc2788_按分隔符拆分字符串

思路就是直接模拟. 然后得注意细节.

  1. 空不返回
  2. 首尾处理
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public:
    vector<string> splitWordsBySeparator(vector<string>& words, char separator) {
        vector<string> ans;
        // Line 11: Char 44: error: no member named 'sub_str' in 'std::basic_string<char>'
        // It is `substr(start, start+cnt)`
        for (auto& word : words) {
            int pre_i = -1;
            int word_size = word.size();
            for (int i = 0; i < word_size; i++) {
                if (word[i] == separator) {
                    if (i - 1 > pre_i) {
                        ans.push_back(word.substr(pre_i + 1, i - 1 - pre_i));
                    }
                    pre_i = i;
                }
            }
            if (pre_i != word_size - 1) {
                ans.push_back(word.substr(pre_i + 1, word_size - 1 - pre_i));
            }
        }
        return ans;
    }
};

看题解发现都是直接使用封装好的函数…这有开挂违背出题人原意的感觉…

不过c 题解直接现场撸了一个vector,秀。

学习一下。所以只实现基本功能其实好像也是不难的,不要把问题想复杂了…对当年的自己的告知

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Solution {
public:
    vector<string> splitWordsBySeparator(vector<string>& words, char separator) {
        vector<string> res;
        for (string &word : words) {
            stringstream ss(word);
            string sub;
            while (getline(ss, sub, separator)) {
                if (!sub.empty()) {
                    res.push_back(sub);
                }
            }
        }
        return res;
    }
};
// 链接:https://leetcode.cn/problems/split-strings-by-separator/solutions/2595926/an-fen-ge-fu-chai-fen-zi-fu-chuan-by-lee-bti9/
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
typedef struct {
    char **data;
    int size;
    int capacity;
} vector;

void append(vector *v, char *sub) {
    if (v->capacity == v->size) {
        if (v->capacity == 0) {
            v->capacity = 4;
        } else {
            v->capacity *= 2;
        }
        char **data1 = (char **)malloc(sizeof(char *) * v->capacity);
        if (v->data != NULL) {
            memcpy(data1, v->data, sizeof(char *) * v->size);
        }
        free(v->data);
        v->data = data1;
    }
    char *p = (char *)malloc(sizeof(char) * (strlen(sub) + 1));
    strcpy(p, sub);
    v->data[v->size++] = p;
}

char **splitWordsBySeparator(char **words, int wordsSize, char separator, int *returnSize) {
    const char sep[2] = {separator};
    vector v;
    memset(&v, 0, sizeof(vector));
    for (int i = 0; i < wordsSize; i++) {
        // man strtok to learn more.
        for (const char *sub = strtok(words[i], sep); sub != NULL; sub = strtok(NULL, sep)) {
            if (strlen(sub) != 0) {
                append(&v, sub);
            }
        }
    }
    *returnSize = v.size;
    return v.data;
}
// 链接:https://leetcode.cn/problems/split-strings-by-separator/solutions/2595926/an-fen-ge-fu-chai-fen-zi-fu-chuan-by-lee-bti9/

Review

Solana Whitepaper Explained

In this vedio, I learn that solana used CP model which sacrifices some availability.

Tips

如何压缩与解压.tar.gz格式的文件

  1. 压缩命令:

tar -zcvf 压缩文件名.tar.gz 被压缩文件名...[多个则空格分隔]

可先切换到当前目录下,压缩文件名和被压缩文件名都可加入路径。

  1. 解压缩命令:

tar -zxvf 压缩文件名.tar.gz [-C 指定目录]

解压缩后的文件只能放在当前的目录 [-C 指定目录]。

个人加深理解

tar --help 得到常用的一些选项的释义。

  • z 是处理 tar.gz 而不是单独 tar
    • -z, –gzip, –gunzip, –ungzip filter the archive through gzip
  • c 创建 tar 压缩
    • -c, –create create a new archive
  • v 输出打印
    • -v, –verbose verbosely list files processed
  • f 使用文件
    • -f, –file=ARCHIVE use archive file or device ARCHIVE
  • x 提出文件
    • -x, –extract, –get extract files from an archive
  • C 提到制定目录, –directory=DIR change to directory DIR CACHEDIR.TAG, except for the tag file itself

Share

RPC server端回包是不用显示调用发包的,一般由框架封装

比如以下 Echo 示例中,当 EchoMessage 方法中执行 return EchoResponse(echoed_message=echoed_message) 时,这个返回语句触发了 gRPC 框架自动将响应发送回客户端。

总体来说,gRPC 非常方便地封装了底层的通信细节,使得开发者可以更专注于业务逻辑而不用过多关心网络通信的细节。

Echo实例

定义 Protocol Buffers 文件 echo.proto

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
syntax = "proto3";

service EchoService {
  rpc EchoMessage (EchoRequest) returns (EchoResponse);
}

message EchoRequest {
  string message = 1;
}

message EchoResponse {
  string echoed_message = 1;
}

然后,使用 Protocol Buffers 编译器生成 gRPC 代码:

1
protoc --proto_path=. --python_out=. --grpc_out=. --plugin=protoc-gen-grpc=$(which grpc_python_plugin) echo.proto

接下来,编写服务端代码 server.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import grpc
from concurrent import futures
from echo_pb2 import EchoRequest, EchoResponse
from echo_pb2_grpc import EchoServiceServicer, add_EchoServiceServicer_to_server

class EchoServiceHandler(EchoServiceServicer):
    def EchoMessage(self, request, context):
        echoed_message = request.message
        return EchoResponse(echoed_message=echoed_message)

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    add_EchoServiceServicer_to_server(EchoServiceHandler(), server)
    server.add_insecure_port('[::]:50051')
    print("Server listening on port 50051...")
    server.start()
    server.wait_for_termination()

if __name__ == '__main__':
    serve()

最后,编写客户端代码 client.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import grpc
from echo_pb2 import EchoRequest
from echo_pb2_grpc import EchoServiceStub

def run():
    with grpc.insecure_channel('localhost:50051') as channel:
        stub = EchoServiceStub(channel)
        request = EchoRequest(message="Hello, gRPC!")
        response = stub.EchoMessage(request)
        print("Received echoed message:", response.echoed_message)

if __name__ == '__main__':
    run()

确保在运行代码之前,你已经安装了 gRPC 和 Protocol Buffers 的 Python 插件:

1
pip install grpcio protobuf

然后,先运行服务端代码 python server.py,再运行客户端代码 python client.py。你应该能够看到客户端发送消息给服务端,服务端将消息回显给客户端的效果。