ARTS打卡活动——第五周
1.Algorithm 做一个leetcode的算法题
28. Implement strStr()
Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Example 1:
Input: haystack = "hello", needle = "ll"
Output: 2
Example 2:
Input: haystack = "aaaaa", needle = "bba"
Output: -1
Clarification:
What should we return when needle is an empty string? This is a great question to ask during an interview.
For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf().
解答:这是一道很简单的题,基本上暴力搜索都能过,做这道题的目的主要是练练手,想尝试用BM、Sunday、KMP三种算法实现。其中KMP是一种时间复杂度相对稳定O(n+m)的单模匹配算法,BM和Sunday在极端的情况下,时间复杂度可以去到O(n/m)或者O(nm),然而大部分情况下比KMP算法要快几倍,考虑到Sunday算法比BM要简单,而且效率也比BM要高,所以这里只写了KMP和Sunday两种算法。
- KMP算法:
class Solution {
public:
int strStr(string haystack, string needle) {
int n = haystack.length();
int m = needle.length();
if (m == 0) {
return 0;
}
if (n < m) {
return -1;
}
int *next = getNexts(needle);
int j = 0;
for (int i = 0; i < n; i++) {
while (j > 0 && needle[j] != haystack[i]) {
j = next[j - 1] + 1;
}
if (needle[j] == haystack[i]) {
++j;
}
if (j == m) {
return i - m + 1;
}
}
return -1;
}
private:
int* getNexts(string m) {
int len = m.length();
int* next = new int[len];
int k = -1;
next[0] = -1;
for (int i = 1; i < len; i++) {
while (k > -1 && m[k + 1] != m[i]) {
k = next[k];
}
if (m[k + 1] == m[i]) {
++k;
}
next[i] = k;
}
return next;
}
};
- Sunday算法
class Solution {
public:
int strStr(string haystack, string needle) {
int m = needle.length();
if (m == 0) return 0;
int s = haystack.length();
if (s < m) return -1;
for (int i = 0; i < 128; i++) {
shift[i] = m + 1;
}
for (int i = 0; i < m; i++) {
shift[needle[i]] = m - i;
}
for (int i = 0; i <= s - m;) {
int j = 0;
while(j < m && needle[j] == haystack[i + j]) {
j++;
}
if (j == m) return i;
i += shift[haystack[i + m]];
}
return -1;
}
private:
int shift[128];
};
2.Review 阅读并点评至少一篇英文技术文章
这周读的外文是Sarvesh Mathi写的What Makes It Possible To Browse The Internet At 35,000 Feet?
这篇文章并不是纯粹的技术文章,而是一篇关于飞机WIFI的科普文章。文章主要讲述了两种能让乘客在飞机飞行途中能上网的方案。
-
第一种是空到地系统(ATG)。在飞机底部安装一个ATG信号天线,地上的信号塔将无线电频向上投射给飞机,飞机的ATG天线收到后,通过调制解调器转换成网络信号,通过飞机内部的WIFI热点,乘客就可以连接上网。其中,地上的信号塔辐射的范围有限,当飞机超过相应的辐射范围,就会重新选择就近的一个信号塔继续连接。这种方案的最大优势在于设施的建设成本比较低,然而存在两个比较大的劣势:
- 使用的频段比较低(800MHz),峰值的带宽才到10Mbps。当多个用户同时使用时,这个网速只允许检查邮箱;
- 地上信号塔比较分散,尤其是在海域上空或者大沙漠上空,这样会导致网络中断。这也是ATG系统不受欢迎的一个重要原因。
-
第二种是卫星系统。卫星系统相对ATG来说更加复杂,但同时也更快更可靠。更ATG相反,卫星接收天线是安装在飞机上方,因为飞机和卫星都是在快速移动,而且相距35,000 km,所以卫星天线需要经常矫正位置,保证能够接收信号。基于卫星系统有两个好处:
- 信号覆盖面广,基本上除了南北极,全世界其他地方都能覆盖到;
- 使用的频段比较高,拥有更快的速度和更高的带宽。主流的两个频段为Ku-band(12-18GHz)和Ka-band(26-40GHz)。每架飞机的峰值带宽可以达到30到100Mbps,是ATG的10倍。
-
然而卫星系统也存在不少缺点:
- 建设成本更高,包括设备、维护和带宽费用,这点也导致该系统在小的航班公司和地区航线不受欢迎;
- 因为飞机到卫星的距离太远,会导致网络连接延迟增大,表现在用户刚开始连接页面会有卡顿,当然连接好之后,后面的网页加载就比较快,而ATG的表现则刚好相反。这里说下我关于这种现象的理解:一开始我简单的认为,距离长,不仅体现在连接延迟多,也应该体现加载数据时间长,但是后面仔细想了下,加载数据时间并不单单取决于距离,还取决于带宽。比如我要加载一张100K的图片,如果带宽超过100K,那么我只要请求一次数据(一个来回)就可以,而如果带宽只有10K,那要加载完这张图片,就需要10个来回,虽然一个来回的时间短,但是乘上10之后就很长了;
- 航空动力学的影响,因为卫星接收天线是安装在飞机上面,在飞机运行的过程中会产生一定的空气阻力,需要消耗额外的燃油,从而增加额外的成本。这里有两个疑惑点:1.ATG的接收天线也是安装在飞机外部,只不过是在飞机下面,根据空气动力学,一样的物品,安装在飞机下面和飞机上面,所产生的空气阻力是否有很大的差别呢?2.既然安装在外部会产生阻力,为什么不给飞机挖个槽,将天线嵌进去,保持飞机表面平齐?当然这样有可能加大了安装成本,损坏飞机本身部件,甚至这样会导致信号接收率降低。
关于飞机WIFI未来的趋势:更快更可靠。改善措施有以下几种:
- 更高效的利用卫星提供的频段。使用一种新的天线接收技术(依赖点波而不是宽波),宽波虽然能服务到更多的飞机,但是平摊下来每架飞机能用的带宽很少,如果采用点波,一个点波只服务少数飞机,这样飞机享受到的带宽就大很多;
- ATG系统也将改善,Gogo公司准备在2021年前将5G技术应用到装有ATG系统的飞机上。
相信不久的将来,飞机WIFI会发展的越来越好,到时可能全面覆盖。不过,到那个时候,你就无法因为“上飞机而错过邮件”来给自己找借口了。
3.Tip 学习至少一个技术技巧
作为程序员,平时写代码最花时间的事情并不是编码,也不是框架设计,而是命名。往往为了起一个优雅又专业的名字(变量名、函数名、类名等等),要查很多资料,纠结老半天。为此,我专门上网搜了下,看有没有快速起名的工具,结果还真的找到,就是codelf,这个搜索工具会在github代码库里面搜索关键词的相关英文名字,具体的展示如下(搜索符文,比较专业的名字是Rune):
4.Share 分享一篇有观点和思考的技术文章
分享一篇关于游戏里面聊天系统的设计方案聊一聊游戏服务器架构设计-聊天功能的那些事
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。