单调栈,顾名思义,是栈内元素保持一定单调性(单调递增或单调递减)的栈。这里的单调递增或递减是指的从栈底到栈顶单调递增或递减。既然是栈,就满足后进先出的特点,与之相对应的是单调队列。
(可以参考:https://blog.csdn.net/weixin_43283687/article/details/85164863,不过这个博客的单调性与我们这里的相反,不过无所谓,叫法不同而已)。
很多博客都提到了这个问题,包括上面的这个博客链接,但很多都不是很好理解。下面给我的个人理解:单调栈主要用来求解所有满足一定单调性的所有子区间。
比如:
对于单调递增栈,可以用来求解所有的凸型子区间(如leetcode 84题,907题); ,
单调递减栈可以求解所有的凹槽区间(如leetcode 42题 接雨水)
或者也可以说是:利用单调栈,可以找到从左/右遍历第一个比它小/大的元素的位置
比如,stk为单增栈,nums为输入序列,i为待入栈元素的索引,
此时,nums[i]已经不再大于stk.top(),那么,对于栈顶元素stk.top()来说,栈顶元素的前一个元素,到待入栈元素这个区间,就是待求区间!写成代码就是int curr_index = stk.pop();stk.pop(); ans = f(stk.top(),curr_index,i),其中f理解为一个函数即可,根据具体的需求确定。比如leetcode的第84题f就为:max_area = max(max_area,nums[curr_index]*(i - stk.top()-1));
907题也是类似的解法。
(Leetcode 84题:求柱状图中最大的矩形面积)
/*** 本代码对应的是单调递增栈,时间复杂度只有O(n)*共n个元素,编号为0~n-1*/class Solution {public:int largestRectangleArea(vector<int>& heights) {//将输入序列的首尾均补上足够小的值;heights.push_bac
Nginx服务器负责接收浏览器的请求并将请求传递给uWSGI服务器,静态资源则由Nginx自己处理,非静态资源的HTTP请求则由Nginx传递给uWSGi服务器,然后传递给Django应用,最后由Django处理并响应,从而完成一次web请求。
这里会用到一些linux命令,linux系列之常用运维命令整理
https://blog.csdn.net/u014427391/article/details/102785219
nginx的安装可以采用编译源码的方式(下次再装nginx的话,源码编译可装更新一点的nginx),或者apt-get,这里我们直接在base环境中,采用apt-get,装的是一个老一点的nginx版本:
sudo apt-get upgrade #可能会卡住,非必须,更新软件列表,成功则会安装更新版本的nginxsudo apt-get install nginx #会有点慢,需要多等会儿
安装目录默认在/etc/nginx/
利用配置文件启动nginx,命令:nginx -c /usr/local/nginx/conf/nginx.conf
重启服务:service nginx restart
快速停止或关闭Nginx:nginx -s stop
正常停止或关闭Nginx:nginx -s quit
配置文件修改重装载命令:nginx -s reload
启动成功,直接在浏览器输入当前主机ip(或者127.0.0.1或者0.0.0.0,不输入端口)即可看到nginx欢迎页面。
nginx实际上是个可执行文件,所以启动代码格式为:nginx安装目录地址 -c nginx配置文件地址
1、可以进入 /etc/nginx/sbin目录,执行:
nginx -c /path/to/nginx.conf
2、可以直接,执行:
/etc/nginx/sbin/nginx -c/usr/local/nginx/conf/nginx.conf
3、还可以采用默认配置(实际上包含多个地方的conf文件
(1)ubuntu 16.04 安装git的方法:
https://blog.csdn.net/qq282330332/article/details/51855252
主要指令:sudo apt-get install git
(2)ubuntu从github上克隆项目:
在终端的git指令(后面是网址),不用像VS2017中那样要先建一个空文件夹作为本地仓库,而是会自动生成在/home目录下:
git clone https://github.com/804463592/pytorch_siamese_minist.git
(3)为了更好地使用 git, 我们同时也记录每一个施加修改的人. 这样人和修改能够对应上. 所以我们在 git 中添加用户名 user.name 和 用户 email user.email:
$ git config --global user.name "804463592"
$ git config --global user.email "804463592@qq.com"
(4)clear 清理指令
(5)cd到桌面的某个文件夹,除了可以直接cd ~/desktop/gitTUT以外,还可以分两步执行cd ~/desktop和cd gitTUT,其他文件夹类似。
cd到某个特定的文件夹后,git init指令即可创建一个新的git本地仓库。此时在此文件夹就会创建一个.git的文件夹,而且是一个隐藏文件夹,这就是我们的本地仓库。通过ls -a查看所有文件,ctrl+h 直接显示隐藏文件
建立一个新的文件touch 1.py
现在我们能用 status 来查看版本库的状态:
指令:git status
现在 1.py 并没有被放入版本库中 (unstaged), 所以我们要使用 add 把它添加进版本库 (staged):
$ git add 1.py
再次git status可以发现已经添加了新文件,但是没有commit提交
如果想一次性添加文件夹中所有未被添加的文件, 可以使用这个:
$ git add .
我们
网址https://redis.io/download下载最新版本,按照官网步骤,解压,编译:
$ wget http://download.redis.io/releases/redis-5.0.7.tar.gz$ tar xzf redis-5.0.7.tar.gz #解压$ cd redis-5.0.7 #进入解压后的文件夹,当然,将其拷贝到其他位置$ make #编译
进入到src文件夹中可以看到redis-server,redis-cli等可执行文件:
$ src/redis-server #使用默认配置开启redis服务$ src/redis-server redis.conf #参数为指定的配置文件,可以加上路径,否则代表当前路径
进入客户端:
$ src/redis-cliredis> set foo barOKredis> get foo"bar"
查看redis进程:
ps -ef|grep redisps -ef|grep 6379
最简单的方式是在根目录下的 ./bashrc文件中添加,其中的路径为你编译redis的路径,这样在任意位置,终端都能输入redis-cli等命令:
export PATH=/usr/local/redis-5.0.7/src:$PATH
让redis以守护线程的方式启动:daemonize no改为daemonize yes
日志输出:logfile ""改为logfile "/home/lb/logs/myredis/redis_log.log"
redis数据存储路径:
dir ./ 改为dir /home/lb/logs/myredis/redis_dbfiles #你自己定义
为了让redis对上面两个文件有修改权,使用:
sudo chmod 777 redis_dbfilesudo chmod 777 logfile
否则可能需要sudo启动redis。
redis shutdown (error) ERR Errors try
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。在21世纪初,Douglas Crockford寻找一种简便的数据交换格式,能够在服务器之间交换数据。当时通用的数据交换语言是XML,但是Douglas Crockford觉得XML的生成和解析都太麻烦,所以他提出了一种简化格式,也就是Json。
json的格式和简单
1) 并列的数据之间用逗号(", ")分隔。
2) 映射用冒号(": ")表示。
3) 并列数据的集合(数组)用方括号("[]")表示。
4) 映射的集合(对象)用大括号("{}")表示。
JSON是设计成描述数据交换格式的,他也有自己的语法,这个语法是JavaScript的一个子集。
// 这是JSON字符串var strJson= '{ "prop": "val" }';// 这是对象字面量var objJson = { "prop": "val" };
目前JSON有2个静态方法:JSON.parse用来将JSON字符串反序列化成对象,JSON.stringify用来将对象序列化成JSON字符串
// 这是JSON字符串var strJson = '{ "prop": "val" }';// 将字符串反序列化成对象var objJson = JSON.parse(strJson);// 将对象序列化成JSON字符串var otherStrJson= JSON.stringify(objJson);
推荐看简书原文,参考地址:
https://www.jianshu.com/p/0c650630c3fc
html页面从数据库中读出DateTimeField字段时,显示的时间格式和数据库中存放的格式不一致,比如数据库字段内容为2017-06-03 13:00:00,但是页面显示的却是Apr. 03, 2017, 1 p.m或者其他形式.
为了页面和数据库中显示一致,需要在页面格式化时间,需要添加<td>{{ infor.updatetime|date:"Y-m-d H:i:s" }}</td> 类似的过滤器。刷新页面,即可正常显示。
当然,<td></td>标签不是重要的,重要的是过滤器。
例如:
<span>{{ article.publish_date }}></span>
改为:
<td>{{ article.publish_date|date:"Y-m-d H:i:s" }}</td>
pytorch中的tensor的高级索引,基本上是与numpy一致的,但是当使用numpy数组,来索引tensor的时候,就会遇到一些坑:
假设idx索引为:
idxarray([[0],[1],[2]])
a,b分别为形状和值都相同的tensor和ndarray:
b =np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])a =torch.tensor(b)
idxt为与idx值相同的tensor:
idxt =torch.tensor(idx)
按道理来说,a[idx] 和b[idx]应该是等效的,至少输出的值是一样的,但是:
b[idx]array([[[ 1, 2, 3, 4]],[[ 5, 6, 7, 8]],[[ 9, 10, 11, 12]]]) #维度增加了一维a[idx]Traceback (most recent call last):File "<input>", line 1, in <module>IndexError: too many indices for tensor of dimension 2
a[idx]报错,第二个维度上索引过多???
但是a[idxt]就不会报错,得到的结果值和形状与b[idx]一致,只是一个是ndarray,一个是tensor而已,为什么会这样?
ndarray是数组,那么作为tensor的索引的时候,就是当作数,一个一的来索引tensor的,因此当idx为数组
array([[0],[1],[2]])
时,a[idx]实际上相当于,a[0,1,2]或者a[0][1][2],如果是写作a[0][1][2]或者a[0,1,2]这种方式,那么与数组则完全一样了。但是,如果索引idx与被索引的是一样的类型,也就是说,a为tensor,idx也为tensor的话,那么就和numpy的数组高级索引是完全一致的,也就是说,idx为
tensor([[0],[1],[2]])
Linux screen命令用于多重视窗管理程序。
screen为多重视窗管理程序。此处所谓的视窗,是指一个全屏幕的文字模式画面。通常只有在使用telnet登入主机或是使用老式的终端机时,才有可能用到screen程序。
可以在本地的终端(或者远程ssh终端),创建screen:
screen # 创建默认sessionscreen -S yourname #新建一个叫yourname的session
创建完终端后,你可以在该终端中,执行相应的任务。保留会话但关闭窗口可以使用“Ctrl-A d”快捷键,这样下次你可以连接此会话。
使用下面指令查看会话列表:
screen -ls
可以看到有一个会话“不连接的”,对于本地终端来说,实际上就是在后台运行的,对于远程终端来说,就是运行在服务器上的进程:
There is a screen on:14360.pts-2.dl (2019年06月28日 14时13分50秒) (Detached)1 Socket in /var/run/screen/S-dl.
为了连接到该会话,使用指令(-r 理解为recovery):
screen -r 14360
如果不需要该会话,想杀死该进程,使用指令:
kill -9 14360
然后使用screen -ls查看可以发现该指令已经死掉,状态为dead,可以使用下列指令清除掉:
screen -wipe 14360 #注意,只有死掉的会话才可以wipe
screen 的一个很好的用处是,可以把瑞捷的联网的终端,隐藏到后台,免得被每次误关掉,关掉了可就连不上网了。对于服务器上跑的程序,有了screen,也不必每次都在本地开着终端才能跑了(本地可以关机,后面开机后通过screen -r 14360即可恢复),很方便。
更多可以参考:
python经常要进行字符串的拼接操作,下面是一些方法:
str = 'There are'+fruit1+','+fruit2+','+fruit3+' on the table'
str = 'There are %s, %s, %s on the table.' % (fruit1,fruit2,fruit3)
或者:
str = 'There are %(fruit1)s,%(fruit2)s,%(fruit3)s on the table' % {'fruit1':fruit1,'fruit2':fruit2,'fruit3':fruit3}
temp = ['There are ',fruit1,',',fruit2,',',fruit3,' on the table']2 ''.join(temp)
注意,与os.path.join()不是一回事,os.path.join()是拼接时会自动加上/的,因为是路径的拼接
>>>"{} {}".format("hello", "world") # 不设置指定位置,按默认顺序'hello world'>>> "{0} {1}".format("hello", "world") # 设置指定位置'hello world'>>> "{1} {0} {1}".format("hello", "world") # 设置指定位置'world hello world'
# 通过字典设置参数site = {"name": "菜鸟教程", "url": "www.runoob.com"}print("网站名:{name}, 地址 {url}".format(**site))# 通过列表索引设置参数my_list = ['菜鸟教程', 'www.runoob.com']print("网站名:{0[0]}, 地址 {0[1]}".format(my_list)) # "0" 是必须的
格式化数字:
>>> print("{:.2f}".f
在linux中,gcc a.c -o a,gcc a.c -o a.out, gcc a.c -o a.exe 甚至,gcc a.c -o a.ex生成文件都是可执行文件!
因为,一般来说,linux可执行文件没有扩展名。
Linux与Windows不同,不是根据扩展名来区分文件类型的。
事实上,Linux下的文件不需要扩展名。一切皆文件,包含设备文件、目录文件、普通文件等。
要知道是否是可执行文件,一般是通过 ls -l 命令看文件属性中是否包含可执行权限 (x)。
比如下面,a.ex,a.exe,a.out均是可执行文件:
-rw-rw-r-- 1 lb lb 365 6月 19 15:49 a.c-rwxrwxr-x 1 lb lb 8640 6月 19 15:50 a.ex-rwxrwxr-x 1 lb lb 8640 6月 19 15:50 a.exe-rw-rw-r-- 1 lb lb 351 6月 19 15:49 a.hdrwxrwxr-x 23 lb lb 4096 10月 2 2018 anaconda3-rw-rw-r-- 1 lb lb 1640 6月 19 15:49 a.o-rwxrwxr-x 1 lb lb 8640 6月 19 15:50 a.outdrwxrwxr-x 3 lb lb 4096 10月 6 2018 data-rw-r--r-- 1 lb lb 8980 9月 29 2018 examples.desktop-rw-rw-r-- 1 lb lb 123 10月 2 2018 on.shdrwxrwxr-x 11 lb lb 4096 10月 10 2018 pycharm-2018.2.4drwxrwxr-x 28 lb lb 4096 5月 22 15:49 PycharmProjects-rw-rw-r-- 1 lb lb 47 10月 11 2018 pycharm.shdrwxr-xr-x 4 lb lb 4096 10月 2 2018 rjsupplicant-rw-