MySQL题目:
如果熟悉case end流程函数的话,这道题还是不难的。我做这道题的时候,首先想如何解决新字段名该怎么设置,回忆以往做的习题和经验,我就联想到case end流程函数。紧接着我先敲一些代码看看结果输出如何。代码如下图所示:
select id ,
(case when month = "Jan" then revenue end) 'Jan_Revenue',
(case when month = "Feb" then revenue end) 'Feb_Revenue',
(case when month = "Mar" then revenue end) 'Mar_Revenue'
from Department
group by id;
结果运行:
这是我中间解题过程中的卡住的点,在想着如何将下面id为1的两条数据整合到第一条数据呢?后来思索了一会终于想到了聚合函数sum(),max()。这两种聚合都是可以将数据整合在一起的。以下是别人更为详细的解释。
最后总的代码如下:
select id ,
sum(case when month = "Jan" then revenue end) 'Jan_Revenue',
sum(case when month = "Feb" then revenue end) 'Feb_Revenue',
sum(case when month = "Mar" then revenue end) 'Mar_Revenue',
sum(case when month = "Apr" then revenue end) 'Apr_Revenue',
sum(case when month = "May" then revenue end) 'May_Revenue',
sum(case when month = "Jun" then revenue end) 'Jun_Revenue',
sum(case when month = "Jul" then revenue end) 'Jul_Revenue',
sum(case when month = "Aug" then revenue end) 'Aug_Revenue',
sum(case when month = "Sep" then revenue end) 'Sep_Revenue',
sum(case when month = "Oct" then revenue end) 'Oct_Revenue',
sum(case when month = "Nov" then revenue end) 'Nov_Revenue',
sum(case when month = "Dec" then revenue end) 'Dec_Revenue'
from Department
group by id;
运行结果如下:
总结:
1、新的字段设计其实可以用case end流程函数也可以用ifnull(),if()等这些来设置,不过具体情况具体分析。
2、如果将几条数据整合在一起,可以用聚合函数。聚合函数并不是那种把所有数据累加那么简单单一的功能,也能整合多条数据。
Java题目:
大二那时候的我也做过这道题,当时单纯的我只会认为“万物皆可暴力”,没有考虑时间复杂度这些,哈哈哈哈哈哈。如果再看这篇文章的您也是这种想法,答应我,咱们多用用别的方法。把BF算法改成KMP算法也好。如果您对这个不熟悉,可以在B站搜索青岛大学王卓老师的数据结构视频,KMP算法在字符串那部分,可自行查看,她讲数据结构还是比较不错的,至少比我的大学老师讲的好太多倍了(小小吐槽一下)。对于KMP算法,可以自行了解哟,毕竟还是有些需要理解的。
王卓老师讲解KMP算法 https://www.bilibili.com/video/BV1nJ411V7bd?p=67&vd_source=0c35f70dcef0a3e5043b0c7a794c3f5a快速理解KMP算法https://www.bilibili.com/video/BV1AY4y157yL/?spm_id_from=333.337.search-card.all.click
如果您看完视频,大概对KMP算法有更深的了解。其实KMP算法主要是计算出搜索字符串的next[]数组。根据next数组我们可以不用讲匹配失败的源字符串和搜索字符串重新拉回,从而将时间复杂度O(m*n)优化成O(m+n)。对于next数组的求法,以及源字符串和搜索字符串的匹配等视频连接有更详细的讲解。最后的代码如下所示:
class Solution {
public int strStr(String haystack, String needle) {
int[] next =new int[needle.length()];
int prefix_len=0;
next[0]=0;
int i=1;
while (i<needle.length()){
if(needle.charAt(i)==needle.charAt(prefix_len)){
prefix_len+=1;
next[i]=prefix_len;
i+=1;
}else {
if (prefix_len==0){
next[i]=0;
i+=1;
}else{
prefix_len=next[prefix_len-1];
}
}
}
i=0;
int j=0;
while (i<haystack.length()){
if (haystack.charAt(i)==needle.charAt(j)){
i++;
j++;
}else if (j>0){
j=next[j-1];
}else {
i+=1;
}
if (j==needle.length()){
return i-j;
}
}
return -1;
}
}
代码虽然不比BF算法的代码少,但是我们确实让时间复杂度更加优化。直到我看到别人的代码时候,确实让我感觉好心累呀!
class Solution {
public int strStr(String haystack, String needle) {
return haystack.indexOf(needle);
}
}
看到别人的代码,我的心里只有......,OK fine。果然能躺着就不要站着。后来我去看了indexOf的底层代码,让我更加佩服别人对代码的理解和深度。底层代码如下图所示:
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}
char first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
if (source[i] != first) {
while (++i <= max && source[i] != first);
}
/* Found first character, now look at the rest of v2 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j]
== target[k]; j++, k++);
if (j == end) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
return -1;
}
底层代码写的更加丝滑和全面,对于起始索引比源字符串更大和搜索字符串为0的情况进行了判断,而且代码中没有next[]数组,并且对max匹配次数变量计算,以减少无用匹配次数从而提高匹配效率。
这两段截取代码让我对for循环和while循环等控制结构有了新的认知,既能判断又能循环,并且这些循环结构没有复杂多余的代码体。果然大神就大神,写的相当丝滑,这些优秀的代码需要不断的回味。总的来说还得继续加油努力呀。