普通视图

发现新文章,点击刷新页面。
昨天以前NoneData

算法刷题 6-10

2020年4月12日 08:00

算法刷题 6-10

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

6

比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:

L C I R E T O E S I I G E D H N

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3 输出: "LCIRETOESIIGEDHN"

示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4 输出: "LDREOEIIECIHNTSG" 解释:

L D R E O E I I E C I H N T S G

6.1

比较简单的一道题,除了看规律之外,还可以用给方向变量来做。

class Solution:
    def convert(s: str, numRows: int) -> str:
        if len(s) <= numRows or numRows == 1:
            return s
                    
        ans = ""
        for row in range(0,numRows):
            start = row
            
            if (row == 0) or (row == numRows-1):
                while True:
                    ans = ans + s[start]
                    start = start + 2*(numRows-1)
                    if start > len(s)-1:
                        break
                    
            else:
                while True:
                    print("here")
                    ans = ans + s[start]
                    start = start + 2*(numRows-1-row)
                    if start <= len(s)-1:
                        ans = ans + s[start]
                        start = start+2*row
                        if start > len(s)-1:
                            break
                    else:
                        break

            
        return ans
    

s = "A"

print(Solution.convert(s,3))

7

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 1:

输入: 123 输出: 321

示例 2:

输入: -123 输出: -321

示例 3:

输入: 120 输出: 21

注意:

假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231,  231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

7.1

简单,略过。

class Solution:
    def reverse(self, x: int) -> int:
        
        sign = ""
        if x < 0 :
            sign = "-"
            x = str(x)[1:]

        x = int(sign + str(x)[::-1])

        if x > 2**31 -1 or x < -2**31:
            return 0

        return x
	str_num = str(x)[::-1]
        if str_num.endswith('-'):
            str_num = '-' + str_num[:-1]
            return int(str_num) if int(str_num) >= -2**31 else 0
        return int(str_num) if int(str_num) <= 2**31 - 1 else 0

8

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:

如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。 假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。 该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。 注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0 。

提示:

本题中的空白字符只包括空格字符 ' ' 。 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231,  231 − 1]。如果数值超过这个范围,请返回  INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例 1:

输入: "42" 输出: 42

示例 2:

输入: " -42" 输出: -42 解释: 第一个非空白字符为 '-', 它是一个负号。   我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:

输入: "4193 with words" 输出: 4193 解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

示例 4:

输入: "words and 987" 输出: 0 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。 因此无法执行有效的转换。

示例 5:

输入: "-91283472332" 输出: -2147483648 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。   因此返回 INT_MIN (−231) 。

8.1

简单

lass Solution:
    def myAtoi( str: str) -> int:
        str = str.lstrip()

        sign = 0
        for index,letter in enumerate(str):
            if index == 0:
                if (letter == '-' and len(str) > 1) or (letter == '+' and len(str) > 1) or letter.isdigit():
                    sign = "-" if letter == '-' else letter
                    continue
                else:
                    break

            if letter.isdigit():
                sign += letter
            else:
                sign = sign if sign != "-" and sign != "+" else 0
                break
        
        sign = int(sign)
        sign = sign if sign <= 2**31-1 else 2**31-1
        sign = sign if sign >= -2**31 else -2**31
            
        return sign
    
    
str = '+-2'

print(Solution.myAtoi(str))

9

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例 1:

输入: 121 输出: true

示例 2:

输入: -121 输出: false 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

示例 3:

输入: 10 输出: false 解释: 从右向左读, 为 01 。因此它不是一个回文数。

进阶:

你能不将整数转为字符串来解决这个问题吗?

9.1

简单,注意一下进阶问题!

class Solution:
    def isPalindrome(self, x: int) -> bool:
        # 68 ms , 在所有 Python3 提交中击败了 84.98% 的用户
        x = str(x)
        flag = False
        if x == x[::-1]:
            flag = True

        return flag

进阶

	origin = x
        if x < 0 or (x % 10 == 0 and x != 0):
            return False

        revertedNumber = 0
        while True:
            revertedNumber = revertedNumber * 10 + x % 10
            x //= 10
            if x < 10:
                revertedNumber = revertedNumber * 10 + x % 10
                break

        return (origin == revertedNumber or origin == revertedNumber/10)

10 ❌

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

'.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

说明:

s 可能为空,且只包含从 a-z 的小写字母。 p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。

示例 1:

输入: s = "aa" p = "a" 输出: false 解释: "a" 无法匹配 "aa" 整个字符串。

示例 2:

输入: s = "aa" p = "a*" 输出: true 解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。

示例 3:

输入: s = "ab" p = "." 输出: true 解释: "." 表示可匹配零个或多个('*')任意字符('.')。

示例 4:

输入: s = "aab" p = "cab" 输出: true 解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。

示例 5:

输入: s = "mississippi" p = "misisp*." 输出: false

10.1

看不懂下面的算法

# 回溯
class Solution(object):
    def isMatch(self, text, pattern):
        if not pattern:
            return not text

        first_match = bool(text) and pattern[0] in {text[0], '.'}

        if len(pattern) >= 2 and pattern[1] == '*':
            return (self.isMatch(text, pattern[2:]) or
                    first_match and self.isMatch(text[1:], pattern))
        else:
            return first_match and self.isMatch(text[1:], pattern[1:])
# 动态规划
class Solution(object):
    def isMatch(self, text, pattern):
        memo = {}
        def dp(i, j):
            if (i, j) not in memo:
                if j == len(pattern):
                    ans = i == len(text)
                else:
                    first_match = i < len(text) and pattern[j] in {text[i], '.'}
                    if j+1 < len(pattern) and pattern[j+1] == '*':
                        ans = dp(i, j+2) or first_match and dp(i+1, j)
                    else:
                        ans = first_match and dp(i+1, j+1)

                memo[i, j] = ans
            return memo[i, j]

        return dp(0, 0)

CAP、AR、ROC、AUC、KS 监控模型的区分能力

2020年4月9日 08:00

CAP、AR、ROC、AUC、KS 监控模型的区分能力

AR值(Accuracy Ratio)和KS值(Kolmogorov-Smirnov)主要是为了监控模型的区分能力。

CAP Introduction

The cumulative accuracy profile (CAP) is used in data science to visualize the discriminative power of a model. The CAP of a model represents the cumulative number of positive outcomes along the y-axis versus the corresponding cumulative number of a classifying parameter along the x-axis (i.e. for a point (0.1,0.3) on the cap means that the worst 10% borrower given by the model includes 30% of defautls). The CAP is distinct from the receiver operating characteristic (ROC), which plots the true-positive rate against the false-positive rate.

An example is a model that predicts whether a borrower is default (positive outcome) by each individual from a group of people (classifying parameter) based on factors such as their working status, annual income, loan purpose etc.

If group members would be contacted at random, the cumulative number of defaults would rise linearly toward a maximum value corresponding to the total number of borrowers within the group. This distribution is called the "random" CAP.

A perfect prediction, on the other hand, determines exactly which group members will buy the product, such that the maximum number of products sold will be reached with a minimum number of calls. This produces a steep line on the CAP curve that stays flat once the maximum is reached (contacting all other group members will not lead to more products sold), which is the "perfect" CAP.

The CAP profiles for the perfect, good and random model predicting the default borrowers from a pool of 100 individuals.

A successful model predicts the likelihood of default individuals and ranks these probabilities to produce a list of potential customers to be contacted first. The resulting cumulative number of sold products will increase rapidly and eventually flatten out to the given maximum as more group members are contacted. This results in a distribution that lies between the random and the perfect CAP curves.

Modified by Xuan, By Victoriaweller - Own work, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=61434256

Analyse CAP

Analyzing a CAP The CAP can be used to evaluate a model by comparing the curve to the perfect CAP in which the maximum number of positive outcomes is achieved directly and to the random CAP in which the positive outcomes are distributed equally. A good model will have a CAP between the perfect CAP and the random CAP with a better model tending to the perfect CAP.

The accuracy ratio (AR) is defined as the ratio of the area between the model CAP and the random CAP and the area between the perfect CAP and the random CAP. For a successful model the AR has values between zero and one, with a higher value for a stronger model.

Another indication of the model strength is given by the cumulative number of positive outcomes at 50% of the classifying parameter. For a successful model this value should lie between 50% and 100% of the maximum, with a higher percentage for stronger models.

ROC Introduction

The ROC curve is created by plotting the true positive rate (TPR) against the false positive rate (FPR) at various threshold settings. The true-positive rate is also known as sensitivity, recall or probability of detection in machine learning. The false-positive rate is also known as probability of false alarm and can be calculated as (1 − specificity).

To draw an ROC curve, only the true positive rate (TPR) and false positive rate (FPR) are needed (as functions of some classifier parameter). The TPR defines how many correct positive results occur among all positive samples available during the test. FPR, on the other hand, defines how many incorrect positive results occur among all negative samples available during the test.

An ROC space is defined by FPR and TPR as x and y axes, respectively, which depicts relative trade-offs between true positive (benefits) and false positive (costs). Since TPR is equivalent to sensitivity and FPR is equal to 1 − specificity, the ROC graph is sometimes called the sensitivity vs (1 − specificity) plot. Each prediction result or instance of a confusion matrix represents one point in the ROC space.

The best possible prediction method would yield a point in the upper left corner or coordinate (0,1) of the ROC space, representing 100% sensitivity (no false negatives) and 100% specificity (no false positives). The (0,1) point is also called a perfect classification. A random guess would give a point along a diagonal line (the so-called line of no-discrimination) from the left bottom to the top right corners (regardless of the positive and negative base rates). An intuitive example of random guessing is a decision by flipping coins. As the size of the sample increases, a random classifier's ROC point tends towards the diagonal line. In the case of a balanced coin, it will tend to the point (0.5, 0.5).

The diagonal divides the ROC space. Points above the diagonal represent good classification results (better than random); points below the line represent bad results (worse than random). Note that the output of a consistently bad predictor could simply be inverted to obtain a good predictor.

Let us look into four prediction results from 100 positive and 100 negative instances:

Plots of the four results above in the ROC space are given in the figure. The result of method A clearly shows the best predictive power among A, B, and C. The result of B lies on the random guess line (the diagonal line), and it can be seen in the table that the accuracy of B is 50%. However, when C is mirrored across the center point (0.5,0.5), the resulting method C′ is even better than A. This mirrored method simply reverses the predictions of whatever method or test produced the C contingency table. Although the original C method has negative predictive power, simply reversing its decisions leads to a new predictive method C′ which has positive predictive power. When the C method predicts p or n, the C′ method would predict n or p, respectively. In this manner, the C′ test would perform the best. The closer a result from a contingency table is to the upper left corner, the better it predicts, but the distance from the random guess line in either direction is the best indicator of how much predictive power a method has. If the result is below the line (i.e. the method is worse than a random guess), all of the method's predictions must be reversed in order to utilize its power, thereby moving the result above the random guess line.

Area Under the ROC Curve (AUC)

When using normalized units, the area under the curve (often referred to as simply the AUC) is equal to the probability that a classifier will rank a randomly chosen positive instance higher than a randomly chosen negative one (assuming 'positive' ranks higher than 'negative').

  • Meanings: Beacuse we calculate area in 1x1 area, so AUC must between 0 and 1. Assign positive for values over threshold, and negative for below. Randomly choose a positive sample and a negative sample, the AUC is the probability of the classifier successfully classify positive sample than negative sample. To sum up, a classifier with higher AUC will have higher accuracy.

  • Criterion: AUC = 1,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。 0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。 AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。 AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。

但是如果只用AUC来判断的话,要注意:AUC can hide performance issuces

notice
notice

KS = max(TPR-FPR)

CAP其他参考文章

Receiver operating characteristic

Cumulative accuracy profile

KS

非 root 权限安装 FFmpeg 和 FFmpeg 的常用命令

2020年1月25日 08:00

非 root 权限安装 FFmpeg 和 FFmpeg 的常用命令

这学习发现了学校的High Performance Computing (HPC),没有限制使用时间,也没有限制院系。虽然感觉硬件配置挺差的,但是比我的笔记本还是好了太多。另外,带宽很足,上传下载都能达到30MB/s。所以要是想做一些事情,还是很不错的。也不用心疼自己的电脑,还可以放在后台跑。最最主要的是,虽然本来只能在

学校一共对外提供了5台机器,都是HP Xeon,一台4核,两台6核,一台12核,一台20核。只有20核的安装了Centos 7.5。其他都是很老的Centos 6。因为没有提供root 权限,所以安装软件比较麻烦,只能使用编译好的,或者自己make。但是自己make的坑太多了,一般还是拿别人编译好的 release 来用。

我试着安装过anaconda,也是可以不用root权限的。我主要用的也就是python了。这次我用了FFmpeg来试了一下性能。转一个3840x2160(2160p,4K)视屏从VFR到CFR。我在我的老Mac上差不多只有0.5x的速度。而在20核上面可以达到3.5X。想比去年我在本科学校的电脑i7-7700k上一个1080P视频,大约2x的速度,还是快了很多的。我也试过12核的服务器,速度差不多2.5X(4K)。

对于FFmpeg,只要去下载编译好的release,上传,解压缩,解压完后将路径写入.bashrc就可以直接用ffmpeg命令了,很方便。

补充几个FFmpeg常用的命令:

ffmpeg -i input.mp4 output.mp4 #VFR 转 CFR 使用默认参数
ffmpeg -i in.mp4 -map 0 -c:a copy out.mp4 #VFR 转 CFR 貌似效率更高
ffmpeg -ss 00:02:06 -i in.mp4 -f image2 -y out.jpg #视频截图 秒
ffmpeg -ss 00:30:14 -i Novoland.Eagle.Flag.EP01-56.2019.WEB-DL.2160p.HEVC.AAC-HQC/06.mp4 -r 10 -f image2 %05d.bmp #bmp 格式截图
ffmpeg -ss 00:30:14 -i Novoland.Eagle.Flag.EP01-56.2019.WEB-DL.2160p.HEVC.AAC-HQC/06.mp4 -y -f image2 -s 3840x2160 -pix_fmt rgb48 %05d.tiff #tiff格式截图

Vue如何优雅地实现下拉到底部自动加载(无限滚动)

2019年12月30日 08:00

Vue如何优雅地实现下拉到底部自动加载(无限滚动)

今天在制作闲言碎语页面时,想要一个无限滚动的功能。本来想用Element UI自带的无限滚动,但是发现这个貌似需要有一个定高的容器,那就很不适合我了。我想要的是整个页面的无限滚动,而不是容器内的无限滚动。所以在网上找到了一篇很不错的文章,来分享一下,根据自己需求修改就好。

首先在目录下新建一个utils文件夹,在该文件夹下新建一个screen.js,将公用方法写入,你也可以考虑其他的封装方式。

//滚动条在Y轴上的滚动距离
export function getScrollTop(){
  var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0;
  if(document.body){
    bodyScrollTop = document.body.scrollTop;
  }
  if(document.documentElement){
    documentScrollTop = document.documentElement.scrollTop;
  }
  scrollTop = (bodyScrollTop - documentScrollTop &gt; 0) ? bodyScrollTop : documentScrollTop;
  return scrollTop;
}

//文档的总高度
export function getScrollHeight(){
  var scrollHeight = 0, bodyScrollHeight = 0, documentScrollHeight = 0;
  if(document.body){
    bodyScrollHeight = document.body.scrollHeight;
  }
  if(document.documentElement){
    documentScrollHeight = document.documentElement.scrollHeight;
  }
  scrollHeight = (bodyScrollHeight - documentScrollHeight &gt; 0) ? bodyScrollHeight : documentScrollHeight;
  return scrollHeight;
}

//浏览器视口的高度
export function getWindowHeight(){
  var windowHeight = 0;
  if(document.compatMode == "CSS1Compat"){
    windowHeight = document.documentElement.clientHeight;
  }else{
    windowHeight = document.body.clientHeight;
  }
  return windowHeight;
}

在要使用的页面中进行引入

import {getScrollHeight,getScrollTop,getWindowHeight} from "../../utils/screen";

将窗口的滚动进行监听,划到底部的时候就进行加载,但是页面关闭的同时,记得将这个监听器关闭,节省性能

mounted(){
    window.addEventListener('scroll', this.load);
},
destroyed(){
    window.removeEventListener('scroll', this.load, false);
},

this.load()就是写的加载数据的方法,到底部的时候先判断下一页是否还有数据,pages就是我从后台拿到的总页数,和当前页进行对比,只有下一页还有数据的时候,我才会拉取后台的接口。

//无限滚动加载
load(){
    let vm=this;
    if(getScrollTop() + getWindowHeight() >= getScrollHeight()){
        if(vm.queryList.pageNum &lt; vm.pages){      //先判断下一页是否有数据  
            vm.queryList.pageNum+=1;         //查询条件的页码+1
            vm.getList();              //拉取接口数据
        }else{
            //到底了
        }
    }
},

WordPress Nuxt 主题 Lareina Version 1.1

2019年12月26日 08:00

WordPress Nuxt 主题 Lareina Version 1.1

唯一的不同,就是处处不同

好久没写博客了,这次来更新一下主题。大体上没有什么变化,但是细节上优化了了很多。

问题修复

  • 修复评论表情不可用问题
  • 修复黑色和棕色模式下显示覆盖不全面的问题
  • 首页、文章页头图动画优化
  • 主体设计语言统一与现代化
  • 文章页设计优化
  • 评论区设计优化
  • 添加一部分图标
  • 部分交互逻辑优化
  • npm依赖包更新
  • html2canvas
  • bug修复
  • 评论区不再显示未审核的评论

功能新增

  • 新增文章、评论内链
  • 新增一套评论表情
  • 图片懒加载
  • 阅读模式
  • 私密评论
  • 闲言碎语功能(写了个简单的php和数据库,还可以发表私密文字。)
  • 在线人数和打开页面数量统计
  • 在线实时推送
  • 添加了评论区issue
  • tracker,用于更好的监测用户评论时出现的exceptions。
  • 新增鼠标滚轮平滑滚动
  • 新增Latex公式显示
  • 新增文章自动加空格,更美观

备忘

更换评论头像挂件:修改default.vue中的图片链接,修改大小,本地npm run build,选择.nuxt, static,package.json,nuxt.config.js四个,本地npm install,然后打包上传即可。pm2 restart all来更新主题。

使用supervisor后台运行celery

2019年8月2日 08:00

使用supervisor后台运行celery

最近打算上线一个B站相关的网站,采用了 celery 来处理任务队列,在本地的时候,那是可以多开,一直开着终端。但是线上生产环境肯定不行。所以需要使用supervisor。

先安装supervisor

安装命令:

$ pip install supervisor

对supervisor进行配置

先在etc目录下生成一个supervisor文件夹,然后生成默认配置文件:

$ echo_supervisord_conf > /etc/supervisor/supervisord.conf

修改配置文件

用vim修改一下:

$ vim /etc/supervisor/supervisord.conf

在最底下改成:

[include]
files = /etc/supervisor/supervisord.conf.d/*.conf

然后创建并进入supervisord.conf.d文件夹,创建 celeryd_worker.conf 文件并进行如下配置:

[program: ProjectName]
command=celery -A bookstore worker -l info ; 运行程序的命令
directory=/root/Publishing/PublishOutput/ ; 命令执行的目录
autorestart=true ; 程序意外退出是否自动重启
autostart=true ; 是否自动启动
stderr_logfile=/var/log/ProjectName.err.log ; 错误日志文件
stdout_logfile=/var/log/ProjectName.out.log ; 输出日志文件
environment=ASPNETCORE_ENVIRONMENT=Production ; 进程环境变量
user=root ; 进程执行的用户身份
stopsignal=INT
startsecs=1 ; 自动重启间隔 

启动 supervisor

$ supervisord -c /etc/supervisor/supervisord.conf

如果遇到报错信息为端口正在被占用的话运行下面的命令:

$ unlink /var/run/supervisor.sock
# 或者
$ unlink /tmp/supervisor.sock

用 supervisorctl 即可监视状态。

❌
❌