ARTS-for-week9-20181214

2024-08-27 01:48
文章标签 arts week9 20181214

本文主要是介绍ARTS-for-week9-20181214,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

阅读文本大概需要 10 分钟。

每周完成一个ARTS:

Algorithm 来源 LeetCode 5.Longest Palindromic Substring

Review 阅读了 Medium 上的一篇关于学习的文章

Tip 总结自己在台式机安装中标麒麟 V5 操作系统以及配置 Qt 环境的一些注意事项

Share 分享一篇关于 ZIP 压缩算法详细分析及解压实例解释

ps:由于公众号不支持添加外链,所以大家遇到有链接的地方滑到文章最下面点击阅读原文就可以访问了哈,如果觉得文章不错,欢迎分享给周围的朋友们哈

又到周末啦,大家该吃该喝该玩,同时也不要抽点时间忘了学习呀。

下面更新 ARTS 第 九 周的内容。

1.Algorithm

LeetCode 5.Longest Palindromic Substring 链接 难度:[Medium]

【题意】

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

1
2
3
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.

Example 2:

1
2
Input: "cbbd"
Output: "bb"

【思路一】

首先解释下什么是回文串,就是正反读起来都一样的字符串,比如 “bob”, “lovevol”, “moom” 等等。我们知道传统的验证回文串的方法就是判断一下当前和其对称位置验证值是否相等,那么对于找回文字串的问题,我们可以以每一个字符为中心,像两边扩散来寻找回文串,这个算法的时间复杂度是O(n*n),这里注意奇偶情况,由于回文串的长度可奇可偶,比如”bob”是奇数形式的回文,”moom”就是偶数形式的回文,两种形式的回文都要搜索。

对于奇数情况,我们就从遍历到当前位置为中心,向两边进行扩散。

对于偶数情况,我们就把当前位置和下一个位置当作偶数行回文串的最中间两个字符,然后向两边进行扩散。

【思路二】

我们可以直接在一个函数中解决这个问题,首先定义两个变量 start 和 maxLen,分别表示最长回文子串的起点跟长度,在遍历 s 中的字符的时候,我们首先判断剩余的字符数是否小于等于maxLen 的一半,是的话说明 maxLen 无法再变长了,直接 break 掉,否则就要继续判断。为什么要这样做呢?因为这点巧妙之处在于既然是回文串,所以必须有对称的特点!一旦剩余的字符数长度小于等于maxLen 的一半,说明之后这部分字符无法再贡献长度了

接着,我们用两个变量 l 和 r 分别指向当前位置,为了后面可以同时处理奇数和偶数的回文串,我们先要做的是向右遍历跳过重复的字符,这个操作很必要,比如对于 moom,i 在第一个o的位置,如果我们以 o 为最中心往两边扩散,是无法得到长度为 4 的回文串的,只有先跳过重复,此时 l 指向第一个 o,r 指向第二个 o,然后再向两边扩散。而对于 bob,i 在第一个 o 的位置时,无法向右跳过重复,此时 l 和 r 同时指向 o,再向两边扩散也是正确的,所以,之后的操作就是更新 start 和 maxLen ,跟上面的操作一样,参见代码如下:

【参考代码】

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <bits/stdc++.h>
using namespace std;/*最开始想到的常规做法,时间复杂度是 O(n^2),空间复杂度是O(n),Time:16ms*/
class Solution1 {
public:string findPalindrome(string s,int l,int r) {int len = s.size();while (l>=0 && r<=len-1 && s[l] == s[r]) {l--;r++;}return s.substr(l+1, r-l-1);
}string longestPalindrome(string s) {int len = s.size();if(len<=1) return s;string longestStr,tmpStr;for(int i=0; i<len-1; ++i){tmpStr=findPalindrome(s,i,i);//奇数回文串的情况,保存最长回文串if(tmpStr.size()>longestStr.size()) longestStr=tmpStr;tmpStr=findPalindrome(s,i,i+1);//偶数回文串的情况,保存最长回文串if(tmpStr.size()>longestStr.size()) longestStr=tmpStr;}return longestStr;}         
};/*考虑进一步优化 时间复杂度是 O(n^2),空间复杂度是O(n),Time:12ms*/
class Solution2 {
public:void findPalindrome(string s,int l,int r,int &start,int &maxLen) {int len = s.size();while ( l>=0 && r<len && s[l] == s[r]) { // 向两边扩散寻找回文串l--;r++;}if( r-l-1 > maxLen){ //记录最大回文串长度开始和长度maxLen = r-l-1;start = l+1;}
}string longestPalindrome(string s) {int len = s.size();if(len<=1) return s;int start=0,maxLen=0;for(int i=0; i<len-1; ++i){findPalindrome(s,i,i,start,maxLen);//奇数回文串的情况findPalindrome(s,i,i+1,start,maxLen);//偶数回文串的情况}return s.substr(start,maxLen);}
};
/*时间复杂度是 O(n^2),空间复杂度是O(1),Time:4ms*/
class Solution3 {
public:string longestPalindrome(string s) {if (s.size() < 2) return s;int n = s.size(), maxLen = 0, start = 0;for (int i = 0; i < n; ) {if ( n - i <= maxLen / 2) break;//判断剩余的字符数是否小于等于maxLen 的一半int l = i, r = i;while (r < n - 1 && s[r + 1] == s[r]) ++r;//向右遍历跳过重复的字符i = r + 1;while (r < n - 1 && l > 0 && s[r + 1] == s[l - 1]) {++r; --l;}if (maxLen < r - l + 1) {//更新 start 和 maxLenmaxLen = r - l + 1;start = l;}}return s.substr(start, maxLen);}
};string stringToString(string input) {assert(input.length() >= 2);string result;for (int i = 1; i < input.length() -1; i++) {char currentChar = input[i];if (input[i] == '\\') {char nextChar = input[i+1];switch (nextChar) {case '\"': result.push_back('\"'); break;case '/' : result.push_back('/'); break;case '\\': result.push_back('\\'); break;case 'b' : result.push_back('\b'); break;case 'f' : result.push_back('\f'); break;case 'r' : result.push_back('\r'); break;case 'n' : result.push_back('\n'); break;case 't' : result.push_back('\t'); break;default: break;}i++;} else {result.push_back(currentChar);}}return result;
}int main() {string line;while (getline(cin, line)) {string s = stringToString(line);string ret = Solution().longestPalindrome(s);string out = (ret);cout << out << endl;}return 0;
}

2.Review

Why you learn the most when you feel like you’re struggling as a developer。(英文)

本次 Review 阅读了 Medium 上的一篇关于学习的文章。关于如何面对学习中碰到的困难和挫折,如何选择一种积极的心态去面对它们,如何更好的了解我们心中的想法并且跟随自己的想法去采取行动,去付出实践。

1.一个人通过努力和持续的努力才能成为更好的开发者。

如果有人对你说:有人天生就会某种技能,有人一生下来就会使用某种编程语言,熟练使用一些软件和技能。

你会怎么想?你赞同有些人刚出生就是伟大的开发者,还是认为人们通过一步步的努力成为伟大的开发者?有人说不否认有些天赋异禀的人,一出生就会某种技能。

在作者看来,这个问题的真正答案可能没人知道,所以作者宁愿选择相信一个人通过自己的努力才能成为一个好的开发者。

回到现实中来,这将是一个更有用的观点。这意味着,如果我努力学习某些东西,我就能学到它,如果我努力工作,我就能得到一份工作。这也意味着我必须接受的观点是,很多事情往往并不总是看起来那么简单或有趣。努力工作是必需的。

2. 当你第一次做某件事的时候,往往是最困难的时候

作为一名程序员,作者分享了自己的故事

”我有时会感到沮丧,因为我遇到了一些我不理解的东西,我觉得我应该理解它。曾经有一段时间我加入了一家使用 git 且被 git 专家包围的公司。有一段时间我终于不得不面对我的 SQL 技能不是很好的事实。在每一个实践机会中,我都觉得自己应该擅长这些技能。毕竟,我是一位拥有多年经验的高级全栈工程师,事实是,虽然我是一名经验丰富的工程师,但没有多少经验可以改变我的现实 ,我第一次学习这些技能的细节,起初我对他们中的任何一个都不是那么擅长。虽然有时新事物很容易,但有时却不容易。“

从而发现一个有用的观点是,当你第一次做某件事的时候,你是不擅长这件事本身的。就像这样……

“我以前从未用 Java 编程 - 我不应该擅长它。这就是为什么我要上这堂课“

“我以前从未将代码提交给 git repo 我不应该知道如何去做。这就是为什么我要求我的同事寻求帮助“

这种想法会逐渐消除了你脑海中的声音,比如之前你可能经常会想:说不准我会失败;我很可能会失败;我可能做不好这件事;我不应该做得好 。

这就是为什么作者建议在这种情况下,你更应该鼓起勇气,对自己说:我要试一试 !只有去试一试,你才能有机会把事情做得更好。

3 处理代码并不总是很有趣,即使任务不好玩,它仍然可以完成

作者分享到:

“有时我会遇到软件开发中没有乐趣的任务。我的 Spark 集群中的某些数据处理代码导致节点随机失败,或者无论我做什么,一些应该工作的库都无法工作。这些时刻并不好玩,有时我真的宁愿做任何事情,除了花时间去弄清楚发生了什么。问题是,我知道编码并不总是很有趣,有时我只需要卷起袖子并“做好工作”。虽然这样的时间很难,但我发现它们通常都有一线希望 ,事实证明,碰到困难的时候是我们学到最多的东西的时候。”

4.当你面对最大的挑战的时候,是你学得最多的时候 - 有时这样的失败是正常的

当你通过尝试做一些对你来说太难的事情挑战自己时,到最后你会发现那正是你真正学习的时刻。这些经历中的每一个痛苦的时刻,意味着你可能要走很多死胡同,比如说代码删了又写,写了又删。你尝试了很多种方法,而且失败了很多次。但是这种压力教会了你新的技能并使你成为一个更好的开发者。如果没有那种压力,你可能就不会吸取教训。当经历了这些过来之后,你选择相信,当你感到压力,挣扎,有点紧张时,这是一件好事。俗话说,没有压力就没有动力,你正在努力,所以你正在学习。而且慢慢学会接纳那些紧张的感觉,虽然它们令人不安,但是在另一种程度上,它们给了你向前进步的动力和鞭策,使得你能够持续的学习。

5.思维是一个强大的工具

你可以选择你所相信的东西,你的信念可以帮助你克服在成为更好的开发者的道路上不可避免的挑战。我希望这些心理框架(或你自己的一些)对于帮助你克服自己的挣扎是有用的。不要放弃。继续。

当你不理解某些事情时,继续努力并不断尝试去理解它。如果你试试,你会惊讶于你的能力。

个人 review

当你的领导,导师给你一个难题,让你去做一件你没做过的事情时,你应该珍惜这个机会,这绝对是提升你个人能力的一次机会,所以,不光要习惯被赶鸭子上架,还要去争取这样的机会。

在这个世界上,只有两样东西是别人抢不走的:一个是吃进肚子里的饭,一个是装进脑子里的经验。一个别人不想抢,不稀罕;一个谁都想抢,但是抢不走。

有句俗话这样说,温水煮青蛙,当自己觉得挺好的,每天过过日子,上班下班,也不学习,也不用提高自己,工作又能胜任,这时候,往往是最危险的时候。

还记得当年 20 岁生日的时候,我给自己写过这么一段话

“当你觉得自己很疲惫,觉得自己很无知,觉得自己怎么什么事都做不好的时候,你就要成长了;当你什么事都做得非常好,轻车熟路,把每件事都安排得井井有条的时候,证明你已经停止进步了,因为你的能力已经完全能够胜任现在所有的事了”。

共勉~

3.Tip

踩坑记~

台式机安装中标麒麟 V5 操作系统 以及 配置 Qt 环境记录

最近由于项目的需要,需要在实验室几台台式机安装中标麒麟的操作系统以及配置 Qt 环境,这里将自己的一些安装的过程记录下来,方便有需要的人可以提供一个参考, 结果在实际操作中发现还是会碰到一些问题。步骤如下:

Step 1 – 制作一个光盘镜像,安装系统

将 中标麒麟 V5 操作系统 下载地址 中标麒麟 刻录到光盘,完成之后将光驱插入到台式机,开机进入 Boot 设置光驱第一启动项,重启进入安装界面,开始安装系统。

Step 2 – rpm 包安装 G++

默认的中标麒麟 V5 操作系统自带 GCC 但是没有 G++ 环境 ,需要额外安装 ,一般在安装盘里面找到 对应的 SDK ,也就是工具包,复制到台式机某个目录下,这里需要注意的是,不同的环境有不同的 SDK,SDK 里面的 rpm 包也有不同的版本,首先查看安装好的中标麒麟操作系统的 GCC 版本,在桌面打开终端,输入

1
2
> $ gcc -v
>

显示对应的版本,我的版本是 gcc-4.9.2 ,然后选择相应的 SDK,我的 SDK 版本是 V5-x86-NeoKylin-sdk,从光盘拷贝到台式机之后,我们可以看到有几个文件夹,包括 packages 等,进入 packages 目录的 C-developments 目录 我们可以看到有一个 g++-gcc-4.9.2.rpm 包,说明这个 g++ 安装包跟我们的 gcc 版本一致,接着在对应的目录打开终端,我们执行以下命令执行安装脚本

1
2
> $ sh install.sh
>

终端显示你要选择的数字,不同的数字对应不同的安装功能,我们选择安装 C-developments 前对应的数字,安装过程等待十几秒之后,我们再在终端输入

1
2
> $ g++ -v
>

显示 g++(4.9.2),OK,表示 G++ 环境已经配置完毕。

Step 3 – 安装 Qtcreator

根据需要,选择不同的 SDK 安装不同版本的 Qt,我这里安装 Qt4.8.5版本,打开 V5-x86-NeoKylin-sdk 工具包,在当前目录下打开终端,同样执行以下命令执行安装脚本

1
2
> $ sh install.sh
>

终端显示你要选择的数字,我们选择安装 Qt 前对应的数字,安装过程等待十几秒之后,我们再在终端输入

1
2
> $ qtcreator
>

系统打开 qtcreator IDE ,OK,说明 IDE安装成功。

Step 4 – 安装 Qt

源码编译 Qt-4.8.5

从 Qt 官网下载 Qt-everywhere-4.8.5.tar.gz 到台式机,进入目录,解压缩进入解压缩的目录,终端依次输入

1
2
3
4
5
6
> $ ./configure -prefix /usr/local/Qt-4.8.5 
> $ o
> $ yes 
> $ gmake
> $ gmake install
>

等待源码编译依次不报错之后。

终端输入

1
2
> $ vim /etc/profile
>

在打开的文件的最后,在 vim 的 Normal 模式下按小写字母 o 添加几行如下

1
2
3
4
5
> QTDIR=/usr/local/Qt-4.8.5
> PATH=$QTDIR/bin:$PATH
> LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
> export QTDIR PATH LD_LIBRARY_PATH
>

输入 :wq 保存之后

1
2
> $ source /etc/profile
>

使得配置文件生效

最后,在终端输入

1
2
> $ qmake -v
>

显示出对应版本说明 Qt 安装成功。

4.Share

ZIP压缩算法详细分析及解压实例解释(中文)

我们在日常生活中,需要传输文件,资料的时候,相对较小的文件往往很快的就传输过去了,比较大的文件传输的过程可能就没有那么快了,万一再碰上网络延迟,网络不好的情况,传输时间花个几分钟也是经常有可能的,在万一遇到比较紧急的情况,文件太大传输很慢,那么文件压缩在这种场合就迫切需要了。

其中一个原因是压缩后的数据容量减小后,磁盘访问 IO 的时间也缩短,尽管压缩和解压缩过程会消耗 CPU 资源,但是 CPU 计算资源增长得很快,但是磁盘 IO 资源却变化得很慢,比如目前主流的SATA 硬盘仍然是 7200 转,如果把磁盘的 IO 压力转化到 CPU 上,总体上能够提升系统运行速度。

压缩作为一种非常典型的技术,会应用到很多很多场合下,比如文件系统、数据库、消息传输、网页传输等等各类场合。

这篇文章详细的介绍了 ZIP 压缩算法,压缩格式的原理和实现。


推荐阅读

编程界十大天神

ARTS-for-week8-20181207

爱学习,爱技术

这篇关于ARTS-for-week9-20181214的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1110295

相关文章

ARTS-for-week8-20181207

阅读文本大概需要 17 分钟。 每周完成一个ARTS:本周的 Algorithm 来源 LeetCode 3. Longest Substring Without Repeating Characters 本次 Review 阅读了 Medium 上的一篇关于面向对象编程的文章 Tip 自己折腾的 Ubuntu14.04 更新原装系统的 Python2.7 版本到 Python3.6 Sha

ARTS-for-week7-20181130

阅读文本大概需要 8 分钟。 每周完成一个ARTS:每周至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tip、Share 简称ARTS) ps:由于公众号不支持添加外链,所以大家遇到有链接的地方滑到文章最下面点击阅读原文就可以访问了哈,如果觉得文章不错,欢迎分享给周

ARTS-for-week6-20181124

阅读文本大概需要 12 分钟。 每周完成一个ARTS:每周至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tip、Share 简称ARTS) ps:由于公众号不支持添加外链,所以大家遇到有链接的地方滑到文章最下面点击阅读原文就可以访问了哈,如果觉得文章不错,欢迎分享给

ARTS-for-week4-20181109

每周完成一个ARTS:每周至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tip、Share 简称ARTS) 第四周了,哇咔咔。时间过得好快^_^由于微信不支持添加外链,所以大家访问有链接的地方直接滑到文章最底部点击阅读原文就可以访问了^_^ 一  Algorithm

ARTS Tip5 数据结构基本概念

数据结构的研究内容: 研究数据元素之间的逻辑结构研究数据在计算机内部的存储结构研究如何在数据的逻辑结构和存储结构中实施有效的操作和处理 数据结构中数据之间的关系分为: 线性关系非线性关系(非线性关系又分为:树关系和图关系) 数据之间的结构分为: 逻辑结构:体现数据元素之间的逻辑关系 存储结构(物理结构):数据在计算机内的表示,包含数据元素的表示和关系的表示。 存储结构又可以分为:

ARTS Review6 IPv4和IPv6地址解剖

原文链接:https://medium.com/@josephcardillo/a-beginners-guide-to-ipv4-and-ipv6-anatomy-fcc9444b0d4d 这篇文章,作者主要剖析了IPv4和IPv6地址的区别: IPv在IPv4和IPv6中代表什么? 代表网络协议版本。 为什么不存在IPv1, IPv2, IPv3 and IPv5? 因为IPv4是第

ARTS Review7 编写可测试代码

原文链接:https://medium.com/feedzaitech/writing-testable-code-b3201d4538eb 这篇文章,作者主要讲了如何编写可测试的代码,一般人不愿意测试,是因为代码之间的耦合度太高,所以我们可以学习编写低耦合的代码,来方便我们开发项目。 编写可测试的代码需要遵循下面的一些原则和指导路线: SOLID design principles Si

ARTS leetcode7 Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.Example:Input: 1->2->4, 1->3->4Output: 1->1->2->3->4->4

ARTS Share5 Java数组

数组: 在Java中,数组是用来存储一组数据类型相同的变量的值,这些变量共用一个变量名。Java中的数组可以是一维数组也可以是多维数组,其中一维数组使用的频率比较高。 一维数组: 一维数组的声明: type array-name[] = new type[size];或者type[] array-name = new type[size]; type :表示数组的数据类型 array-n

ARTS Share4 mysql中autocommit

MySQL中的事务(自动提交,显示和隐式),在MySQL中事务控制数据操作语句以确保它们是原子的。什么叫做原子的,也就是说这个事务要么成功,要么失败。 什么时候算事务成功或者失败? 当向数据库事务发送commit命令的时候,说明事务提交成功;相反,如果向数据库事务发送rollback命令,那么就说明此次的事务提交失败,所有执行过的SQL,数据会进行回滚到最初的状态。 当对数据库数据进行修改的