【Trie树&AC自动机】P3879[TJOI2010]阅读理解 P3808 【模板】AC自动机(简单版)P3796 【模板】AC自动机(加强版).md

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

洛谷 P3879[TJOI2010]阅读理解


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int INF = 0x7fffffff, SCF = 0x3fffffff;
​ const int N = 5e6+4, M = 1e3+4;
​ int n,m,k;
​ int idx,len,ans;
​ int has[M];
​ char ss[22];
​ struct TT
​ {
​ int nxt[26],id;
​ }tree[N];
​ void jointree(int rt)
​ {
​ len = strlen(ss);
​ for(int i=0; i<len; i++){
​ int pp = ss[i]-‘a’;
​ if(!tree[rt].nxt[pp]){
​ tree[rt].nxt[pp] = idx++;
​ }
​ rt = tree[rt].nxt[pp];
​ }
​ tree[rt].id = 1;
​ }
​ void qry(int rt)
​ {
​ int root = rt;
​ for(int i=0; i<len; i++){
​ int pp = ss[i]-‘a’;
​ if(!tree[rt].nxt[pp]) return ;
​ rt = tree[rt].nxt[pp];
​ }
​ has[root] = tree[rt].id;
​ }
​ void solve()
​ {
​ memset(has,0,sizeof(has));
​ len = strlen(ss);
​ for(int i=1; i<=n; i++){
​ qry(i);
​ }
​ for(int i=1; i<=n; i++){
​ if(has[i]) printf("%d “,i);
​ }
​ printf(”\n");
​ }
​ int main()
​ {
​ scanf("%d",&n);
​ idx = n+1;
​ for(int i=1; i<=n; i++){
​ scanf("%d",&k);
​ for(int j=1; j<=k; j++){
​ scanf("%s",ss);
​ jointree(i);
​ }
​ }
​ scanf("%d",&m);
​ for(int i=0; i<m; i++){
​ scanf("%s",ss);
​ solve();
​ }
​ return 0;
​ }

洛谷 P3808 【模板】AC自动机(简单版)


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int INF = 0x7fffffff, SCF = 0x3fffffff;
​ const int N = 1e7+4, M = 1e3+4;
​ int n,idx;
​ char ss[N];
​ struct TT
​ {
​ int fail,id,nxt[26];
​ }tree[N];
​ void joinTree()
​ {
​ int len = strlen(ss), rt = 0;
​ for(int i=0; i<len; i++){
​ int pp = ss[i]-‘a’;
​ if(!tree[rt].nxt[pp]){
​ tree[rt].nxt[pp] = idx++;
​ }
​ rt = tree[rt].nxt[pp];
​ }
​ tree[rt].id += 1;
​ }
​ void getFail()
​ {
​ std::queue q;
​ int x,y,fail;
​ for(int i=0; i<26; i++){
​ y = tree[0].nxt[i];
​ if(y>0){
​ tree[y].fail = 0;
​ q.push(y);
​ }
​ }
​ while(!q.empty()){
​ x = q.front(); q.pop();
​ fail = tree[x].fail;
​ for(int i=0; i<26; i++){
​ y = tree[x].nxt[i];
​ if(y>0){
​ tree[y].fail = tree[fail].nxt[i];
​ q.push(y);
​ }
​ else tree[x].nxt[i] = tree[fail].nxt[i];
​ }
​ }
​ }
​ int ACgo()
​ {
​ int rt = 0,len = strlen(ss),ans = 0;
​ for(int i=0; i<len; i++){
​ rt = tree[rt].nxt[ss[i]-‘a’];
​ for(int j=rt; j && tree[j].id != -1; j=tree[j].fail){
​ ans += tree[j].id;
​ tree[j].id = -1;
​ }
​ }
​ return ans;
​ }
​ int main()
​ {
​ //freopen(“D:\EdgeDownloadPlace\P3808_2.in”,“r”,stdin);
​ idx = 1;
​ scanf("%d",&n);
​ while(n–){
​ scanf("%s",ss);
​ joinTree();
​ }
​ getFail();
​ scanf("%s",ss);
​ printf("%d",ACgo());
​ return 0;
​ }

洛谷 P3796 【模板】AC自动机(加强版)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
typedef long long int LL;
const int INF = 0x7fffffff, SCF = 0x3fffffff;
const int N = 1e6+4, M = 10550;
int n;
int idx;
struct TT
{
int fail,id,nxt[26];
}node[M];
char ss[N];
char sub[155][75];
int save[155];
void initial()
{
for(int i=0; i<=idx; i++){
memset(node[i].nxt,0,sizeof(node[i].nxt));
node[i].fail = 0;
node[i].id = 0;
}
idx = 0;
memset(save,0,sizeof(save));
}
void joinTree(int id)
{
int len = strlen(sub[id]) ,rt = 0;
for(int i=0; i<len; i++){
int ch = sub[id][i]-'a';
if(!node[rt].nxt[ch]) node[rt].nxt[ch] = ++idx;
rt = node[rt].nxt[ch];
}
node[rt].id = id;
}
void buildFail()
{
std::queue<int >q;
for(int i=0; i<26; i++){
if(node[0].nxt[i]>0) {
node[node[0].nxt[i]].fail = 0;
q.push(node[0].nxt[i]);
}
}
while(!q.empty()){
int cur = q.front(); q.pop();
int fail = node[cur].fail;
for(int i=0; i<26; i++){
int next = node[cur].nxt[i];
if(next>0){
node[next].fail = node[fail].nxt[i];
q.push(next);
}
else node[cur].nxt[i] = node[fail].nxt[i];
}
}
}
void ACgo()
{
int len = strlen(ss),rt = 0;
for(int i=0; i<len; i++){
rt = node[rt].nxt[ss[i]-'a'];
for(int j=rt; j; j=node[j].fail)
save[node[j].id] += 1;
}
}
int main()
{
//freopen("D:\\EdgeDownloadPlace\\P3796_1.in","r",stdin);
while(scanf("%d",&n)){
if(n == 0) break;
initial();
for(int i=1; i<=n; i++){
scanf("%s",sub[i]);
joinTree(i);
}
buildFail();
scanf("%s",ss);
ACgo();
int mx = 0;
for(int i=1; i<=n; i++){
mx = std::max(save[i],mx);
}
printf("%d\n",mx);
for(int i=1; i<=n; i++){
if(save[i] == mx){
printf("%s\n",sub[i]);
}
}
}
return 0;
}

【tarjin算法练习 缩点,割点,割边】洛谷_P3387缩点模板P3388割点模板 HDU4738 caocao‘bridge.md

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

洛谷 P3387缩点模板

vis数组是必要的,如果遇到vis[i]=false的点,说明此点对应的强连通已经被缩点过了,而访问的i的起点并不属于这一强连通分量。若这时执行low[x]
= std::min(low[x],dfn[y]);可能会导致一些点在栈内无法弹出。


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ //typedef std::pair<int ,int> PP;
​ const int N = 1e4+5, M = 1e5+5;
​ int vis[N],low[N],dfn[N],val[N],head[N],stk[N],suo[N],weight[N],hh[N],in[N],dp[N];
​ struct Edge
​ {
​ int to,nxt;
​ }edg[M<<1];
​ int n,m,u,v;
​ int idx,timer,top,id,tt;
​ void addEdge(int fr,int to)
​ {
​ edg[idx].to = to;
​ edg[idx].nxt = head[fr];
​ head[fr] = idx++;
​ }
​ void tarjin(int x)
​ {
​ low[x] = dfn[x] = timer;
​ stk[top] = x,vis[x] = 1;
​ for(int e=head[x]; e!=-1; e=edg[e].nxt){
​ int y = edg[e].to;
​ if(!dfn[y]){
​ tarjin(y);
​ low[x] = std::min(low[x],low[y]);
​ }
​ else if(vis[y]){
​ low[x] = std::min(low[x],dfn[y]);
​ }
​ }
​ if(low[x] == dfn[x]){
​ id += 1;
​ while(true){
​ vis[stk[top]] = 0;
​ suo[stk[top]] = id;
​ weight[id] += val[stk[top]];
​ if(x == stk[top–]) break;
​ }
​ }
​ }
​ void rebuild()
​ {
​ for(int i=1; i<=n; i
){
​ for(int e=head[i]; e!=-1; e=edg[e].nxt){
​ int y = edg[e].to;
​ int ii = suo[i],yy = suo[y];
​ if(ii != yy){
​ in[yy] += 1;
​ edg[idx].to = yy;
​ edg[idx].nxt = hh[ii];
​ hh[ii] = idx
;
​ }
​ }
​ }
​ }
​ int tpsort()
​ {
​ std::queue q;
​ for(int i=1; i<=id; i++){
​ if(!in[i]){
​ q.push(i);
​ dp[i] = weight[i];
​ }
​ }
​ while(!q.empty()){
​ int cur = q.front(); q.pop();
​ for(int e=hh[cur]; e!=-1; e=edg[e].nxt){
​ int to = edg[e].to;
​ dp[to] = std::max(dp[to],dp[cur]+weight[to]);
​ in[to] -= 1;
​ if(!in[to]) q.push(to);
​ }
​ }
​ int ans = 0;
​ for(int i=1; i<=id; i++){
​ ans = std::max(ans,dp[i]);
​ }
​ return ans;
​ }
​ int main()
​ {
​ memset(head,-1,sizeof(head));
​ memset(hh,-1,sizeof(hh));
​ scanf("%d%d",&n,&m);
​ for(int i=1; i<=n; i++){
​ scanf("%d",&val[i]);
​ }
​ for(int i=0; i<m; i++){
​ scanf("%d%d",&u,&v);
​ addEdge(u,v);
​ }
​ for(int i=1; i<=n; i++){
​ if(!dfn[i]) tarjin(i);
​ }
​ rebuild();
​ printf("%d",tpsort());

return 0;
}

洛谷P3388割点模板

trajin中的形参意义为(此点,上一个点),最好改为(此点,过来的边),在做caocao‘s bridge的时候暴露了一些问题


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int N = 2e4+5, M = 2e5+5;
​ int n,m,u,v;
​ int ans;
​ int idx,timer;
​ int head[N];
​ int low[N],dfn[N],flag[N];
​ struct Edge
​ {
​ int to,nxt;
​ }edg[M];
​ void addEdge(int fr,int to)
​ {
​ edg[idx].to = to;
​ edg[idx].nxt = head[fr];
​ head[fr] = idx++;
​ }
​ void tarjin(int x,int fa)
​ {
​ low[x] = dfn[x] = timer;
​ int son = 0;
​ for(int e=head[x]; e!=-1; e=edg[e].nxt){
​ int to = edg[e].to;
​ if(!dfn[to]){
​ son += 1;
​ tarjin(to,x);
​ low[x] = std::min(low[x],low[to]);
​ if(fa && dfn[x] <= low[to] && !flag[x]){
​ flag[x] = 1;
​ ans += 1;
​ }
​ }
​ else if(to != fa)low[x] = std::min(low[x],dfn[to]);
​ }
​ if(!fa && son>=2 && !flag[x]){
​ flag[x] = 1;
​ ans += 1;
​ }
​ }
​ int main()
​ {
​ //freopen(“D:\EdgeDownloadPlace\P3388_4.in”,“r”,stdin);
​ memset(head,-1,sizeof(head));
​ scanf("%d%d",&n,&m);
​ for(int i=0; i<m; i
){
​ scanf("%d%d",&u,&v);
​ addEdge(u,v); addEdge(v,u);
​ }
​ for(int i=1; i<=n; i++){
​ tarjin(i,0);
​ }
​ printf("%d\n",ans);
​ for(int i=1; i<=n; i++){在这里插入代码片
​ if(flag[i]) printf("%d ",i);
​ }
​ return 0;
​ }

HDU4738 caocao’bridge

坑点:

  1. 你需要判断图是否是全部联通的,若不是输出0
  2. 若需要派出0个人,则要输出1,至少需要1人才能炸桥

——————
最开始在tarjin记录(此点,上一个点),一直wa,猜测可能是有重边,改为记录(此点,过来的边)ac。懒得动脑以后再想。


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int N = 1005, M = 1000005,INF = 1e6;
​ int n,m,u,v,p;
​ int ans;
​ int head[N],low[N],dfn[N],pp[M];
​ int idx,timer;
​ struct Edge
​ {
​ int to,nxt,p;
​ }edg[M];
​ void addEdge(int u,int v,int p)
​ {
​ edg[idx].to = v;
​ edg[idx].nxt = head[u];
​ edg[idx].p = p;
​ head[u] = idx++;
​ }
​ void initial()
​ {
​ idx = timer = 0;
​ ans = INF;
​ memset(head,-1,sizeof(head));
​ memset(low,0,sizeof(low));
​ memset(dfn,0,sizeof(dfn));
​ memset(pp,0,sizeof(pp));
​ }
​ void tarjin(int x,int bri)
​ {
​ low[x] = dfn[x] = timer;
​ for(int e=head[x]; e!=-1; e=edg[e].nxt){
​ if((e^1) == bri) continue;
​ int y = edg[e].to;
​ if(!dfn[y]){
​ tarjin(y,e);
​ low[x] = std::min(low[x],low[y]);
​ if(dfn[x] < low[y]) pp[e] = pp[e^1] = 1;
​ }
​ else low[x] = std::min(low[x],dfn[y]);
​ }
​ }
​ int main()
​ {
​ while(scanf("%d%d",&n,&m)){
​ if(n == 0 && m == 0) break;
​ initial();
​ for(int i=0; i<m; i
){
​ scanf("%d%d%d",&u,&v,&p);
​ addEdge(u,v,p); addEdge(v,u,p);
​ }
​ tarjin(1,-1);
​ bool judge = false;
​ for(int i=1; i<=n; i++){
​ if(!dfn[i]){
​ judge = true;
​ break;
​ }
​ }
​ if(judge) printf(“0\n”);
​ else{
​ for(int e=0; e<idx; e++){
​ if(pp[e] == 1) ans = std::min(ans,edg[e].p);
​ }
​ if(!ans) ans += 1;
​ else if(ans == INF) ans = -1;
​ printf("%d\n",ans);
​ }
​ }
​ return 0;
​ }

洛谷P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ typedef std::pair<int ,int> PP;
​ const int N = 1e4, M = 5e4+5, INF = 0x7fffffff;
​ int n,m,u,v,su,sv,cnt;
​ int idx,timer,counter;
​ int head[N],low[N],dfn[N],vis[N],suo[N],num[N],out[N];
​ PP qry[M];
​ std::stack stk;
​ struct Edge
​ {
​ int to,nxt;
​ }edg[M];
​ void initial()
​ {
​ idx = 2;
​ }
​ void addEdge(int fr,int to)
​ {
​ edg[idx].to =to;
​ edg[idx].nxt = head[fr];
​ head[fr] = idx++;
​ }
​ void tarjin(int x)
​ {
​ dfn[x] = low[x] = timer;
​ vis[x] = true;
​ stk.push(x);
​ for(int e=head[x]; e; e=edg[e].nxt){
​ int y = edg[e].to;
​ if(!dfn[y]){
​ tarjin(y);
​ low[x] = std::min(low[x],low[y]);
​ }
​ else if(vis[y]) low[x] = std::min(low[x],dfn[y]);
​ }
​ if(low[x] == dfn[x]){
​ counter += 1;
​ while(true){
​ int t = stk.top(); stk.pop();
​ suo[t] = counter;
​ num[counter] += 1;
​ vis[t] = false;
​ if(t == x) break;
​ }
​ }
​ }
​ int main()
​ {
​ initial();
​ scanf("%d%d",&n,&m);
​ for(int i=0; i<m; i
){
​ scanf("%d%d",&qry[i].first,&qry[i].second);
​ addEdge(qry[i].first,qry[i].second);
​ }
​ for(int i=1; i<=n; i++) if(!dfn[i]) tarjin(i);
​ for(int i=0; i<m; i++){
​ u = qry[i].first , v = qry[i].second;
​ su = suo[u] , sv = suo[v];
​ if(su == sv) continue;
​ out[su] += 1;
​ }
​ for(int i=1; i<=counter; i++){
​ if(!out[i]){
​ cnt += 1;
​ u = i;
​ if(cnt > 1) break;
​ }
​ }
​ if(cnt == 1) printf("%d",num[u]);
​ else printf(“0”);
​ return 0;
​ }

【二叉树】 给出二叉树的中序遍历 和先序遍历或后序遍历 确定二叉树.md

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

讨论的内容如题

分析

拿中序遍历和后序遍历的组合举例子
设数组last[]储存后续遍历 in[]中序遍历,它们的长度都是n(数组从1开始计,下标范围是1-n)

树根自然为last[n]
,这时我们遍历in[]数组,在in[]数组中找到last[n]的值的下标idx,因为in[]储存的是中序遍历,显然我们以idx为界把in数组的序列分成两份[1,idx-1],[idx+1,n],分别为两颗子树上的节点。

之后我们便可以在分出的两个区间之中重复上述操作,分别找目前子树的根节点,再二分区间,直到获得完整的二叉树

可以使用递归来完成 函数(区间左,区间右,根节点,偏移量)

此时注意一个问题:当区间被二分之后,我们发现后面的区间在in[]数组和last[]数组中的下标“对不齐”了,即下标发生了偏移,如下图。所以要引入一个变量shift来记录偏移量。(偏移量最开始是0,递归时前面的区间继承原偏移量,后面的区间偏移量为原偏移量+1)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201008231828150.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dsZGNtenk=,size_16,color_FFFFFF,t_70#pic_center)
(在前序遍历和中序遍历的组合中,下标发生偏移的是前面的区间)

例题 后序遍历和中序遍历的组合

https://vjudge.net/contest/386054#problem/E


#include
#include
#include
struct Node
{
int l,r;
};
Node treeN[10010];
int inorder[10010],postorder[10010];
int len,rt,least,lstPos;
int input()//返回数组长度
{
int n,idx=1;
char ch;
while(scanf("%d",&n)!=EOF)
{
inorder[idx++]=n;
ch=getchar();
if(ch==’\n’)
break;
}
idx=1;
while(scanf("%d",&n)!=EOF)
{
postorder[idx++]=n;
ch=getchar();
if(ch==’\n’)
break;
}
return idx-1;
}
int makeTree(int l,int r,int root,int n)
{
if(l>r)
return -1;
int idx=-1;
for(int i=l; i<=r; i++)
{
if(inorder[i]root)
{
idx=i;
break;
}
}
if(idx>0)
{
treeN[root].l=makeTree(l,idx-1,postorder[idx-n-1],n);
treeN[root].r=makeTree(idx+1,r,postorder[r-n-1],n+1);
}
return root;
}
void add(int root,int base)
{
int total=base+root;
if(treeN[root].l
-1 && treeN[root].r==-1)
{
if(lstPos==-1)
{
least=total;
lstPos=root;
}
else
{
if(total<least)
{
least=total;
lstPos=root;
}
}
return ;
}
if(treeN[root].l>0)
{
add(treeN[root].l,total);
}
if(treeN[root].r>0)
{
add(treeN[root].r,total);
}
}

int main()
{
    while((len=input())>0)
    {
        memset(treeN,-1,sizeof(treeN));
        lstPos=-1;
        rt=makeTree(1,len,postorder[len],0);
        add(rt,0);
        std::cout << lstPos << std::endl;
    }
    return 0;
}

例题 前序遍历和中序遍历的组合

<https://pintia.cn/problem-
sets/1303281293857476608/problems/1303281404742291466>


#include
#include
#include
#include
#include
#include
#include
#include

const int N=32;
int n;
struct Node
{
    int l,r;
}treeN[N];
int pre[N],in[N];

int fff(int root,int l,int r,int shift)
{
    if(l>r) return -1;
    int i;
    for(i=l; i<=r; i++) if(root==in[i]) break;
    if(i<=r)
    {
        treeN[root].l=fff(pre[l+1+shift],l,i-1,shift+1);
        treeN[root].r=fff(pre[i+1+shift],i+1,r,shift);
    }
    return root;
}

void rev(int root)
{
    if(root==0) return ;
    treeN[root].r=treeN[root].r^treeN[root].l;
    treeN[root].l=treeN[root].r^treeN[root].l;
    treeN[root].r=treeN[root].r^treeN[root].l;
    rev(treeN[root].l);
    rev(treeN[root].r);
}

void gogogo(int root)
{
    std::queue<int >q;
    std::cout << root;
    if(treeN[root].l!=-1) q.push(treeN[root].l);
    if(treeN[root].r!=-1) q.push(treeN[root].r);
    while(!q.empty())
    {
        root=q.front(); q.pop();
        std::cout << " " << root;
        if(treeN[root].l!=-1) q.push(treeN[root].l);
        if(treeN[root].r!=-1) q.push(treeN[root].r);
    }
}

int main()
{
    std::cin >> n;
    for(int i=0; i<n; i++) std::cin >> in[i];
    for(int i=0; i<n; i++) std::cin >> pre[i];
    int root=fff(pre[0],0,n-1,0);
    rev(root);
    gogogo(root);
    return 0;
}

【二分图匹配 练习】洛谷P3386【模板】二分图最大匹配P2756飞行员配对方案问题P1129矩阵游戏P1559运动员最佳匹配问题P4014分配问题P1640连续攻击游戏.md

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

洛谷 P3386【模板】二分图最大匹配


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int N = 505;
​ int mp[N][N],link[N],vis[N];
​ int n,m,e,u,v,ans;
​ bool dfs(int x)
​ {
​ for(int i=1; i<=m; i++){
​ if(!vis[i] && mp[x][i]){
​ vis[i] = 1;
​ if(!link[i] || dfs(link[i])){
​ link[i] = x;
​ return true;
​ }
​ }
​ }
​ return false;
​ }
​ int main()
​ {
​ scanf("%d%d%d",&n,&m,&e);
​ for(int i=0; i<e; i++){
​ scanf("%d%d",&u,&v);
​ mp[u][v] = 1;
​ }
​ for(int i=1; i<=n; i++) {
​ memset(vis,0,sizeof(vis));
​ ans += dfs(i);
​ }
​ printf("%d",ans);
​ return 0;
​ }

洛谷 P2756飞行员配对方案问题


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int N = 105;
​ int mp[N][N],vis[N],link[N];
​ int n,m,u,v,ans;
​ bool dfs(int x)
​ {
​ for(int i=1; i<=n; i++){
​ if(!vis[i] && mp[x][i]){
​ vis[i] = 1;
​ if(!link[i] || dfs(link[i])){
​ link[i] = x;
​ return true;
​ }
​ }
​ }
​ return false;
​ }
​ int main()
​ {
​ scanf("%d%d",&m,&n);
​ n-=m;
​ while(scanf("%d%d",&u,&v)){
​ if(u == -1 && v == -1) break;
​ mp[u][v-m] = 1;
​ }
​ for(int i=1; i<=m; i++) {
​ memset(vis,0,sizeof(vis));
​ ans += dfs(i);
​ }
​ printf("%d\n",ans);
​ for(int i=1; i<=n; i++){
​ if(link[i]) printf("%d %d\n",link[i],i+m);
​ }
​ return 0;
​ }

洛谷 P1129 [ZJOI2007] 矩阵游戏


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int N = 205;
​ int mp[N][N],vis[N],link[N];
​ int t,n,ans;
​ bool dfs(int x)
​ {
​ for(int i=1; i<=n; i++){
​ if(!vis[i] && mp[x][i]){
​ vis[i] = 1;
​ if(!link[i] || dfs(link[i])){
​ link[i] = x;
​ return true;
​ }
​ }
​ }
​ return false;
​ }
​ int main()
​ {
​ scanf("%d",&t);
​ while(t–){
​ memset(link,0,sizeof(link));
​ ans = 0;
​ scanf("%d",&n);
​ for(int i=1; i<=n; i++){
​ for(int j=1; j<=n; j++){
​ scanf("%d",&mp[i][j]);
​ }
​ }
​ for(int i=1; i<=n; i++){
​ memset(vis,0,sizeof(vis));
​ ans += dfs(i);
​ }
​ printf(ans == n ? “Yes\n” : “No\n”);
​ }
​ return 0;
​ }

洛谷P1559 运动员最佳匹配问题

两种敲代码方法,一种dfs完算tmp,一种在dfs中算tmp。不确定是否一种比另一种更优,这道题后者时间占优,然而下一道题 洛谷 P4014
分配问题
前者时间占优。


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int N = 205,INF = 0x7fffffff;
​ int mp[N][N],lx[N],ly[N],visx[N],visy[N],link[N];
​ int n,tmp,v;
​ bool dfs(int x)
​ {
​ visx[x] = 1;
​ for(int i=1; i<=n; i++){
​ if(!visy[i] && lx[x]+ly[i]==mp[x][i]){
​ visy[i] = 1;
​ if(!link[i] || dfs(link[i])){
​ link[i] = x;
​ return true;
​ }
​ }
​ }
​ return false;
​ }
​ int one()
​ {
​ int ans = 0;
​ for(int i=1; i<=n; i++) for(int j=1; j<=n; j++){
​ lx[i] = std::max(lx[i],mp[i][j]);
​ }
​ for(int i=1; i<=n; i++){
​ while(true){
​ memset(visx,0,sizeof(visx));
​ memset(visy,0,sizeof(visy));
​ tmp = INF;
​ if(dfs(i)) break;
​ for(int i=1; i<=n; i++) if(visx[i]){
​ for(int j=1; j<=n; j++) if(!visy[j]){
​ tmp = std::min(tmp,lx[i]+ly[j]-mp[i][j]);
​ }
​ }
​ for(int j=1; j<=n; j++){
​ if(visx[j]) lx[j] -= tmp;
​ if(visy[j]) ly[j] += tmp;
​ }
​ }
​ }
​ for(int i=1; i<=n; i++){
​ ans += ly[i] + lx[link[i]];
​ //std::cout << “ly[” << i << “] = " << ly[i] << " lx[” << link[i] << “] = " << lx[link[i]] << " ans = " << ans << std::endl;
​ }
​ return ans;
​ }
​ int main()
​ {
​ //freopen(“D:\EdgeDownloadPlace\P4014_1.in”,“r”,stdin);
​ scanf(”%d",&n);
​ for(int i=1; i<=n; i++) for(int j=1; j<=n; j++){
​ scanf("%d",&v);
​ mp[i][j] = -v;
​ }
​ for(int i=0; i<N; i++) lx[i] = -INF;
​ printf("%d\n",-one());
​ for(int i=1; i<=n; i++) for(int j=1; j<=n; j++){
​ mp[i][j] = -mp[i][j];
​ }
​ memset(lx,0,sizeof(lx));
​ memset(ly,0,sizeof(ly));
​ memset(link,0,sizeof(link));
​ printf("%d\n",one());
​ return 0;
​ }



​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int N = 23,INF = 0x7fffffff;
​ int mp[N][N],vm[N],vf[N],vism[N],visf[N],link[N];
​ int n,v,ans,tmp;
​ bool dfs(int x)
​ {
​ vism[x] = 1;
​ for(int i=1; i<=n; i++){
​ if(!visf[i]){
​ int t = vm[x]+vf[i]-mp[x][i];
​ if(t==0){
​ visf[i] = 1;
​ if(!link[i] || dfs(link[i])){
​ link[i] = x;
​ return true;
​ }

}
else if(t>0){
tmp = std::min(t,tmp);
}
}
}
return false;
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) {
scanf("%d",&mp[i][j]);
}
for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) {
scanf("%d",&v);
mp[j][i] *= v;
}
for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) {
vm[i] = std::max(vm[i],mp[i][j]);
}
for(int i=1; i<=n; i++){
while(true){
memset(visf,0,sizeof(visf));
memset(vism,0,sizeof(vism));
tmp = INF;
if(dfs(i))break;
for(int i=1; i<=n; i++){
if(visf[i]) vf[i] += tmp;
if(vism[i]) vm[i] -= tmp;
}
}
}
for(int i=1; i<=n; i++){
ans += vf[i] + vm[link[i]];
}
printf("%d",ans);
return 0;
}

洛谷 P4014 分配问题

全WA,我的输出莫名其妙出现了"-",洛谷判题机的锅?
破案了,one()里的ans没初始化,Windows自动给个0,Linux就挂了,初始化成0就好了


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int N = 105,INF = 0x7fffffff;
​ int mp[N][N],lx[N],ly[N],visx[N],visy[N],link[N];
​ int n,tmp,v;
​ bool dfs(int x)
​ {
​ visx[x] = 1;
​ for(int i=1; i<=n; i++){
​ if(!visy[i] && lx[x]+ly[i]==mp[x][i]){
​ visy[i] = 1;
​ if(!link[i] || dfs(link[i])){
​ link[i] = x;
​ return true;
​ }
​ }
​ }
​ return false;
​ }
​ int one()
​ {
​ int ans;
​ for(int i=1; i<=n; i++) for(int j=1; j<=n; j++){
​ lx[i] = std::max(lx[i],mp[i][j]);
​ }
​ for(int i=1; i<=n; i++){
​ while(true){
​ memset(visx,0,sizeof(visx));
​ memset(visy,0,sizeof(visy));
​ tmp = INF;
​ if(dfs(i)) break;
​ for(int i=1; i<=n; i++){
​ if(visx[i]){
​ for(int j=1; j<=n; j++){
​ if(!visy[j]){
​ tmp = std::min(tmp,lx[i]+ly[j]-mp[i][j]);
​ }
​ }
​ }
​ }
​ for(int j=1; j<=n; j++){
​ if(visx[j]) lx[j] -= tmp;
​ if(visy[j]) ly[j] += tmp;
​ }
​ }
​ }
​ for(int i=1; i<=n; i++){
​ ans += ly[i] + lx[link[i]];
​ }
​ return ans;
​ }
​ int main()
​ {
​ //freopen(“D:\EdgeDownloadPlace\P4014_1.in”,“r”,stdin);
​ scanf("%d",&n);
​ for(int i=1; i<=n; i++) for(int j=1; j<=n; j++){
​ scanf("%d",&v);
​ mp[i][j] = -v;
​ }
​ for(int i=0; i<N; i++) lx[i] = -INF;
​ printf("%d\n",-one());
​ for(int i=1; i<=n; i++) for(int j=1; j<=n; j++){
​ mp[i][j] = -mp[i][j];
​ }
​ memset(lx,0,sizeof(lx));
​ memset(ly,0,sizeof(ly));
​ memset(link,0,sizeof(link));
​ printf("%d\n",one());
​ return 0;
​ }

洛谷 P1640连续攻击游戏

匈牙利优化 每次memset置零vis数组太慢了,TLE,直接开一个变量timmer当作时间计数,当timmer-
vis[x]>0就说明在这次dfs中x节点没有访问过。
.
初始timmer为1, 每次dfs后timmer自增1


​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ #include
​ typedef long long int LL;
​ const int INF = 0x7fffffff, SCF = 0x3fffffff;
​ const int N = 1e6+5, M = 220, K = 1e6+4;
​ int head[N],link[N],vis[N];
​ int n,idx,a,b,timmer;
​ struct Edge
​ {
​ int to,nxt;
​ }edg[N<<1];
​ void addE(int fr,int to)
​ {
​ edg[idx].to = to;
​ edg[idx].nxt = head[fr];
​ head[fr] = idx++;
​ }
​ bool dfs(int x)
​ {
​ for(int e=head[x]; e; e=edg[e].nxt){
​ int y = edg[e].to;
​ if(timmer-vis[y]>0){
​ vis[y] = timmer;
​ if(!link[y] || dfs(link[y])){
​ link[y] = x;
​ return true;
​ }
​ }
​ }
​ return false;
​ }
​ int main()
​ {
​ idx = 2;
​ scanf("%d",&n);
​ for(int i=1; i<=n; i++){
​ scanf("%d%d",&a,&b);
​ addE(a,i);
​ addE(b,i);
​ }
​ int i;
​ for(i=1; i<=n; i++){
​ timmer = i;
​ if(!dfs(i)) break;
​ }
​ printf("%d",i-1);
​ return 0;
​ }

【区间DP练习】洛谷 P1880[NOI1995]石子合并 P1063能量项链P2654 原核生物培养.md

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

洛谷 P1880[NOI1995]石子合并

https://www.luogu.com.cn/problem/P1880
环形的石子合并,可以把环形拆开,在末尾接一份自己的复制当线形来做
dp数组也需要在右端外接一份自己的复制
犯错:
因为dp公式会访问到j+1的下标,,刚开始用的if(j>=n)判断越界 ,在j=n-1时会访问到下标为n的位置导致越界,所以一直出错
应该改为if(j+1>=n)


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long LL;
typedef std::pair<int ,int> PP;
const int N = 105;
int n,qu[N],dx[N][N<<1],dn[N][N<<1],sum[N<<1];

int main()
{
   memset(dn,1,sizeof(dn));

   std::cin >>n;
   for(int i=0; i<n; i++){
      std::cin >> qu[i];
   }

   for(int i=1; i<n; i++){
      sum[i] = sum[i-1] + qu[i];
   }
   for(int i=0; i<n; i++){
      sum[n+i] = sum[n+i-1] + qu[i];
   }
   for(int i=0; i<n; i++){
      dn[i][i] = 0;
   }
   for(int i=1; i<n; i++){
      for(int st=0; st<n; st++){
         int ed = st+i;
         for(int j=st; j<ed; j++){
            int gain = sum[ed]-sum[st]+qu[st];
            if(j+1>=n){
               dn[st][ed] = std::min(dn[st][ed],dn[st][j]+dn[j-n+1][ed-n]+gain);
               dx[st][ed] = std::max(dx[st][ed],dx[st][j]+dx[j-n+1][ed-n]+gain);
            }else{
               dn[st][ed] = std::min(dn[st][ed],dn[st][j]+dn[j+1][ed]+gain);
               dx[st][ed] = std::max(dx[st][ed],dx[st][j]+dx[j+1][ed]+gain);
            }
         }
      }
   }
   int mx=0,mn=1e7;
   for(int i=0; i<n; i++){
      mx = std::max(dx[i][n-1+i],mx);
      mn = std::min(dn[i][n-1+i],mn);
   }
   std::cout << mn << std::endl << mx <<std::endl;
   return 0;
}

洛谷 P1063 能量项链

https://www.luogu.com.cn/problem/P1063
同样时环形类石子合并dp
刚开始dp公式dp[st][ed] =
std::max(dp[st][ed],dp[st][j]+dp[j+1-n][ed-n]+gain);中的dp[j+1-n][ed-n]写成了dp[j+1-n][ed],当场暴毙


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long LL;
typedef std::pair<int ,int> PP;
const int N = 105;
LL n,qu[N<<1],dp[N][N<<1];

int main()
{
   std::cin >> n;
   for(int i=1; i<=n; i++){
      std::cin >>qu[i];
      qu[i+n] = qu[i];
   }
   qu[n<<1|1] = qu[1];
   for(int i=1; i<n; i++){
      for(int st=1; st<=n; st++){
         int ed = st+i;
         for(int j=st; j<ed ;j++){
            int gain = qu[st]*qu[j+1]*qu[ed+1];
            if(j+1>n){
               dp[st][ed] = std::max(dp[st][ed],dp[st][j]+dp[j+1-n][ed-n]+gain);
            }else{
               dp[st][ed] = std::max(dp[st][ed],dp[st][j]+dp[j+1][ed]+gain);
            }
         }
      }
   }
   LL mx = -1;
   for(int i=0; i<n; i++){
      mx = std::max(mx,dp[1+i][n+i]);
   }
   std::cout << mx << std::endl;

   return 0;
}

上面这个思路开了2倍的dp空间。下面改一个开4倍dp空间的(与线形区间合并更加相似)
只需要把st的限制条件从st<=n 改成st<=(n<<1)-i (-i保证下标不越界),再把循环里面判断j+1>n的分支去掉就可以了


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long LL;
typedef std::pair<int ,int> PP;
const int N = 105;
LL n,qu[N<<1],dp[N<<1][N<<1];

int main()
{
   std::cin >> n;
   for(int i=1; i<=n; i++){
      std::cin >>qu[i];
      qu[i+n] = qu[i];
   }
   qu[n<<1|1] = qu[1];
   for(int i=1; i<n; i++){
      for(int st=1; st<=(n<<1)-i; st++){
         int ed = st+i;
         for(int j=st; j<ed ;j++){
            int gain = qu[st]*qu[j+1]*qu[ed+1];
               dp[st][ed] = std::max(dp[st][ed],dp[st][j]+dp[j+1][ed]+gain);
         }
      }
   }
   LL mx = -1;
   for(int i=0; i<n; i++){
      mx = std::max(mx,dp[1+i][n+i]);
   }
   std::cout << mx << std::endl;

   return 0;
}

洛谷 P2654 原核生物培养

很显然(真的很显然)是优先队列+区间dp,别忘了每次dp完之后还要往队列里面push一个
题目让求最小值,一开始一直再求max,差点WA傻了


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long int LL;
const int N = 1e4+5,M=11,INF = 0x7fffffff;
int dp[M][M<<1],pos[M],qu[M],sum[M<<1];
std::priority_queue<int,std::vector,std::greater > q;
int n,m,k,v;
LL ans;
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=0; i<n; i++){
scanf("%d",&v);
q.push(v);
}
while(k–){
for(int i=1; i<=m; i++) for(int j=1; j<=(m<<1); j++) dp[i][j] = INF;
for(int i=1; i<=m; i++){
scanf("%d",&pos[i]);
}
for(int i=1; i<=m; i++){
qu[pos[i]] = q.top();
q.pop();
}
for(int i=1; i<=m; i++) sum[i] = sum[i-1]+qu[i];
for(int i=1; i<=m; i++) sum[i+m] = sum[i+m-1]+qu[i];
for(int i=1; i<=m; i++) dp[i][i] = 0;
for(int i=1; i<m; i++){
for(int st=1; st<=m; st++){
int ed = st+i;
for(int j=st; j<ed; j++){
if(j+1>m) dp[st][ed] = std::min(dp[st][ed],dp[st][j]+dp[j+1-m][ed-m]+sum[ed]-sum[st-1]);
else dp[st][ed] = std::min(dp[st][ed],dp[st][j]+dp[j+1][ed]+sum[ed]-sum[st-1]);
}
}
}
int mx = INF;
for(int i=1; i<=m; i++){
mx = std::min(mx,dp[i][m+i-1]);
}
ans += mx;
q.push(sum[m]);
}
printf("%lld",ans);
return 0;
}

【单源最短路 spfa Dijkstra】 _ 洛谷 P3371 【模板】单源最短路径(弱化版)_

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

洛谷 P3371 【模板】单源最短路径(弱化版)

Dijkstra


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long int LL;
const int N = 1e4+5, M = 5e5+5,INF = 0x7fffffff;
int n,m,u,v,d,s;
int idx;
int head[N],dis[N];
bool vis[N];
struct Edge
{
int to,nxt,d;
}edg[M];
void addEdge(int fr,int to,int d)
{
edg[idx].to = to;
edg[idx].nxt = head[fr];
edg[idx].d = d;
head[fr] = idx++;
}
struct PPP
{
int val,dis;
bool operator < (const PPP &x) const{
return dis > x.dis;
}
};
std::priority_queue q;
int main()
{
//freopen(“D:\EdgeDownloadPlace\P3371_2.in”,“r”,stdin);
memset(head,-1,sizeof(head));
for(int i=0;i<N; i++) dis[i] = INF;
scanf("%d%d%d",&n,&m,&s);
for(int i=1; i<=m; i++){
scanf("%d%d%d",&u,&v,&d);
addEdge(u,v,d);
}
dis[s] = 0;
q.push((PPP){s,0});
while(!q.empty()){
PPP cur = q.top(); q.pop();
int x = cur.val;
if(vis[x]) continue;
vis[x] = true;
for(int e=head[x]; e!=-1; e=edg[e].nxt){
int y = edg[e].to;
if(dis[y] > dis[x]+edg[e].d){
dis[y] = dis[x]+edg[e].d;
q.push((PPP){y,dis[y]});
}
}
}
for(int i=1; i<=n; i++){
printf("%d ",dis[i]);
}
return 0;
}

spfa(个人感觉就是纯bfs)


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long int LL;
const int N = 1e4+5, M = 5e5+5,INF = 0x7fffffff;
int dis[N],head[N];
bool vis[N];
int n,m,u,v,d,s;
int idx;
struct Edge
{
int to,nxt,d;
}edg[M];
void addEdge(int fr,int to,int d)
{
edg[idx].to = to;
edg[idx].nxt = head[fr];
edg[idx].d = d;
head[fr] = idx++;
}
std::queue q;
int main()
{
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
for(int i=0; i<N; i++) dis[i] = INF;
scanf("%d%d%d",&n,&m,&s);
for(int i=0; i<m; i++){
scanf("%d%d%d",&u,&v,&d);
addEdge(u,v,d);
}
dis[s] = 0;
q.push(s);
while(!q.empty()){
int x = q.front(); q.pop(); vis[x] = false;
for(int e=head[x]; e!=-1; e=edg[e].nxt){
int y = edg[e].to;
if(dis[y] > dis[x]+edg[e].d){
dis[y] = dis[x]+edg[e].d;
if(!vis[y]){
vis[y] = true;
q.push(y);
}
}
}
}
for(int i=1; i<=n; i++){
printf("%d ",dis[i]);
}
return 0;
}

洛谷P4779 【模板】单源最短路径(标准版)


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long int LL;
const int N = 1e5+5, M = 2e5+5,INF = 0x7fffffff;
int n,m,u,v,d,s;
int idx;
int head[N],dis[N];
bool vis[N];
struct Edge
{
int to,nxt,d;
}edg[M];
void addEdge(int fr,int to,int d)
{
edg[idx].to = to;
edg[idx].nxt = head[fr];
edg[idx].d = d;
head[fr] = idx++;
}
struct PPP
{
int val,dis;
bool operator < (const PPP &x) const{
return dis > x.dis;
}
};
std::priority_queue q;
int main()
{
//freopen(“D:\EdgeDownloadPlace\P3371_2.in”,“r”,stdin);
memset(head,-1,sizeof(head));
for(int i=0;i<N; i++) dis[i] = INF;
scanf("%d%d%d",&n,&m,&s);
for(int i=1; i<=m; i++){
scanf("%d%d%d",&u,&v,&d);
addEdge(u,v,d);
}
dis[s] = 0;
q.push((PPP){s,0});
while(!q.empty()){
PPP cur = q.top(); q.pop();
int x = cur.val;
if(vis[x]) continue;
vis[x] = true;
for(int e=head[x]; e!=-1; e=edg[e].nxt){
int y = edg[e].to;
if(dis[y] > dis[x]+edg[e].d){
dis[y] = dis[x]+edg[e].d;
q.push((PPP){y,dis[y]});
}
}
}
for(int i=1; i<=n; i++){
printf("%d ",dis[i]);
}
return 0;
}

【学习记录】【Python】【cv2】自学cv2 的简单记录(已经腰斩换新的).md

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

1.图像的载入、显示、保存


​ import cv2

#读入图像 cv2.imread(filepath,flags)
#flags参数的取值:
#cv2.IMREAD_COLOR:默认,载入一个彩色图像,忽略透明度 可用1代替
#cv2.IMREAD_GRAYSCALE:载入一个灰阶图像 可用0代替
#cv2.IMREAD_UNCHANGED:载入一个包含 Alpha 通道(透明度)的图像 可用-1代替
img1=cv2.imread(‘img_chess.jpg’,0)

#显示图像   cv2.imshow(wname,img)
#wname  窗口的名字 window name
#img 要显示的图像 窗口他大小为自动调整图片大小
cv2.imshow('image_one',img1)
key=cv2.waitKey(0)                  #等待键盘输入,单位毫秒,0为无限等待  没有这句话窗口只会闪一下就消失
if key==27:
    print('您按了ESC')
#cv2.destroyAllWindows()            #销毁所有窗口
cv2.destroyWindow('image_one')      #指定窗口名字销毁窗口


​ #保存图像 cv2.imwrite(file,img,num)
​ #file 文件名
​ #img 要保存的图像
​ #num 对于JPEG,其表示的是图像的质量,用0 - 100的整数表示,默认95;对于png 用0-9 ,第三个参数表示的是压缩级别。默认为3.
​ cv2.imwrite(‘img_chess_gray.jpg’,img1,[cv2.IMWRITE_JPEG_QUALITY,0])
​ cv2.imwrite(‘img_chess_gray.png’,img1,[cv2.IMWRITE_PNG_COMPRESSION,0])
​ # jpg属于有损压缩,是以图片的清晰度为代价的,数字越小,压缩比越高,图片质量损失越严重
​ # png属于无损压缩,数字0-9,数字越低,压缩比越低

input(‘按回车退出程序’)

那张保存为jpg格式的图片惨不忍睹

2.简单的图片操作 反转、复制、缩放、裁剪

flip copy resize


​ import cv2

img1=cv2.imread(‘img_chess.jpg’)

#图片反转 cv2.flip(img,flipcode)
#flipcode >0 沿x轴 flipcode=0 沿y轴 flipcode<0 xy轴同时反转
img1_flipx=cv2.flip(img1,1)
img1_flipy=cv2.flip(img1,0)
img1_flipxy=cv2.flip(img1,-1)

cv2.imshow('1fx',img1_flipx)
cv2.imshow('1fy',img1_flipy)
cv2.imshow('1fxy',img1_flipxy)
cv2.waitKey(0)
cv2.destroyAllWindows()


​ #图像复制
​ img1_cp=img1.copy()
​ cv2.imshow(‘1cp’,img1_cp)
​ cv2.waitKey()
​ cv2.destroyAllWindows()


​ #图像的缩放
​ img_info=img1.shape
​ height=img_info[0]
​ width=img_info[1]
​ img1_resized=cv2.resize(img1.copy(),(int(width1.2),int(height0.6)))
​ cv2.imshow(‘1resized’,img1_resized)
​ cv2.waitKey(0)
​ cv2.destroyAllWindows()

#图像的裁剪
img1_cut=img1[350:800,60:500]
h,w,n=img1.shape
img1_cut2=img1[int(h/4):int(h3/4),int(w/4):int(w3/4)]
cv2.imshow(‘1cut’,img1_cut)
cv2.imshow(‘1cut2’,img1_cut2)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.图像通道的分离与合成

分离:
img1B,img1G,img1R=np.dsplit(img1,3)
img1B,img1G,img1R=cv2.split(img1)都可以
合成:
cv2.merge([b,g,r])
cv2.merge([zeros, zeros, img1R])

注意倒数第五句的注释


​ import cv2
​ import numpy as np

def showone(img):
cv2.imshow(‘show image’,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
def showone_color(img,color):
zeros=np.zeros(img.shape[:2],dtype=‘uint8’) #记得调整格式
if color == ‘B’:
cv2.imshow(‘blue’,cv2.merge([img1B,zeros,zeros]))
elif color == ‘G’:
cv2.imshow(‘green’, cv2.merge([zeros, img1G, zeros]))
elif color == ‘R’:
cv2.imshow(‘red’, cv2.merge([zeros, zeros, img1R]))
cv2.waitKey(0)
cv2.destroyAllWindows()
def showone_merge(b,g,r):
cv2.imshow(‘merge’,cv2.merge([b,g,r]))
cv2.waitKey(0)
cv2.destroyAllWindows()


​ img1=cv2.imread(‘theimg.png’,1)

img1B,img1G,img1R=np.dsplit(img1,3)
#img1B,img1G,img1R=cv2.split(img1)

print(img1B.dtype)          #矩阵元素的格式为uint8



​ showone(img1B) #这里图像为灰色,原因是当调用cv2.imshow的时候G、R两个通道被默认设为了与B通道一样,三通道一样时显示灰度图


​ showone_color(img1B,‘B’)
​ showone_color(img1G,‘G’)
​ showone_color(img1R,‘R’)

showone_merge(img1B,img1G,img1R) #合成后是原图

【学习记录】【Python】【numpy】自学简要记录(未完).md

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

自学记录,不专业

1.很基础的操作

010.建立一个数组以及查看它的一些属性

看就完了,奥里给


import numpy as np

lst=[i for i in range(6)]

#---------------------------------------------------
input('\n\n1.创建两个数组,类型为numpy.ndarray\n')
array1=np.array(lst)
array2=np.array([[[1,2,3],[4,5,6]],[[0,0,1],[1,1,2]]],dtype=np.int8)#dtype参数规定数组中数据的数据类型

print(type(array1),type(array2))

#----------------------------------------------------
input('\n\n2.查看数组的维度和形状\n')
print('维度:',array1.ndim,array2.ndim)
print('形状:',array1.shape,array2.shape)



#-----------------------------------------------------
input(’\n\n3.改变数组形状\n’)
array1_re=array1.reshape(2,3)
print(‘改变后:’,array1_re)
print(‘改变前:’,array1)


#-----------------------------------------------------
input(’\n\n4.查看数组数据类型\n’)
print(array1.dtype,array2.dtype)


#-----------------------------------------------------
input(’\n\n5.查看数组的大小(貌似就是元素个数)\n’)
print(array1.size,array2.size)

011.最简单的提取信息

提取第几行第几列


import numpy as np

array=np.array([i for i in range(18)]).reshape(3,6)#reshape的作用是把np.array中创建的一维数组变形
print('原数组array:\n',array)


#----------------------------------------------
input(’\n\n1.取原数组的0-1行,1-3列\n’)
array1=array[0:2,1:4]
print(array1)

#----------------------------------------------
input('\n\n2.取原素组1-末行的首-4列\n')
array2=array[1:,:4]
print(array2)


#----------------------------------------------
input(’\n\n3.取原数组首-末行的2-末列\n’)
array3=array[:,2:]
print(array3)

012.最简单的矩阵运算

加减乘 转置


import numpy as np

array1=np.array([i for i in range(18)]).reshape(3,6)
array2=np.array([i*3 for i in range(18)]).reshape(3,6)
print('原数组:\n',array1,'\n\n',array2,sep='')


#-----------------------------------------------
input(’\n\n两数组相加\n’)
print(array1+array2)


#-----------------------------------------------
input(’\n\n两数组相减\n’)
print(array1-array2)


#-----------------------------------------------
input(’\n\n两数组相乘,注意不是矩阵乘法,只是把对应位置的数相乘\n’)
print(array1*array2)


#-----------------------------------------------
input(’\n\narray1+2\n’)
print(array1+2)

#-----------------------------------------------
input('\n\narray1转置\n')
print(array1.T)

矩阵乘法
numpy.matmul(a,b)
numpy.dot(a,b)

01a.精度

元素为float16类型的数组和元素为float64类型的数组记录同样的值,扩大10000倍后不一样
通过 set_printoptions(precision=?) 来设置精度


import numpy as np

array_float16=np.array([[2.2,4.4],[6.6,8.8]],dtype=np.float16)
array_float64=np.array([[2.2,4.4],[6.6,8.8]],dtype=np.float64)


#------------------------------------------------------------------------
input(’\n\n1.精度不同,值会存在误差\n’)
print(‘原数组:\n’,array_float16,’\n\n’,array_float64,sep=’’)

input('\n如果把里面的元素都扩大10000倍\n\n')
print('扩大后:\n',array_float16*10000,'\n\n',array_float64*10000,sep='')


#------------------------------------------------------------------------
input(’\n\n2.通过 set_printoptions(precision=?) 来设置精度\n\n’)
np.set_printoptions(precision=6)
print(array_float64/3)

01b.数组元素默认的数据类型

int:默认int32
float:默认float64


import numpy as np

array1=np.array([1,2])
array2=np.array([1.0,2.0])

print(array1.dtype,array2.dtype)

1.5快速创建数组1

zeros 创建指定形状和类型的全 0 数组
zeros_like 创建另一个数组的形状和类型创建全 0 数组
ones 创建指定形状和类型的全 1 数组
ones_like 创建另一个数组的形状和类型创建全 1 数组
empty 创建指定形状和类型的空数组,不对数据进行初始化
empt_like 根据另一个数组的形状和类型创建空数组,不对数据尽兴初始化
full 创建指定形状和类型的数组,全部填上指定的值
full_like 根据另一个数组的形状和类型创建空数组,全部填上指定的值


import numpy as np

array=np.arange(48).reshape(4,4,3)
spt=np.dsplit(array,3)

input('\n\nnp.zeors,参数给数组形状')
zero1=np.zeros((4,4,1),dtype=np.int8)
print(zero1)

input('\n\nnp.zeros_like参数给一个数组,创建一个相同形状的数组')
zero2=np.zeros_like(spt[0],dtype=np.int8)
print(zero2)



import numpy as np

array=np.arange(48).reshape(4,4,3)
spt=np.dsplit(array,3)

input('\n\nnp.ones,参数给数组形状')
one1=np.ones((4,4,1),dtype=np.int8)
print(one1)

input('\n\nnp.ones_like参数给一个数组,创建一个相同形状的数组')
one2=np.ones_like(spt[0],dtype=np.int8)
print(one2)



import numpy as np

array=np.arange(48).reshape(4,4,3)
spt=np.dsplit(array,3)

input('这两种方法不对数据进行初始化')

input('\n\nnp.empty,参数给数组形状')
empty1=np.empty((4,4,1),dtype=np.int8)
print(empty1)

input('\n\nnp.empty_like参数给一个数组,创建一个相同形状的数组')
empty2=np.empty_like(spt[0],dtype=np.int8)
print(empty2)



import numpy as np

array=np.arange(48).reshape(4,4,3)
spt=np.dsplit(array,3)

input('以下两种方法建立某种形状且值全为给定值的数组')

input('\n\nnp.full,参数给数组形状')
ful=np.full((4,4,1),25,dtype=np.int8)
print(ful)

input('\n\nnp.full_like参数给一个数组,创建一个相同形状的数组')
fulll=np.full_like(spt[0],12,dtype=np.int8)
print(fulll)

1.6快速创建数组2

快速创建固定步长等差递变数组

arange(开始,结束,步长) 创建等差递变数组


import numpy as np

input('numpy.arange(),下面的三个参数分别为开始,结束,步长')
arr=np.arange(-15,23,0.25)
print(arr)

快速创建有固定元素个数的等差递变数组

linspace(开始,结束,元素个数)


import numpy as np

print(np.linspace(-20,72,104))

2.比较基础的东西

020.基础索引 、切片


import numpy as np

array=np.array([i for i in range(125)]).reshape(5,5,5)
print('原数组:\n',array,sep='')


#-----------------------------------------------------
input(’\n\n获取第2块,第3行,第4列的元素,以下两种方法等效:\n’)
print(array[2][3][4])
print(array[2,3,4])

#-----------------------------------------------------
input('\n\n指定步长的索引:获取第0、3块,第0、2、4行,第3列(基于python列表基础)\n')
print(array[::3,::2,3])

#-----------------------------------------------------
input('\n\n中括号表示在该维度上取特定的元素:eg1:获取第0、3、4块,后4行,所有列\n')
print('eg1:\n',array[[0,3,4],1:],sep='')
input('\n\n然而当我们箱获得第0,1,2,4块,第0,2,3,4行,只得到了一块四行的数据\n')
print('eg2:\n',array[[0,1,2,4],[0,2,3,4]],sep='')

021.索引 numpy.ix_()


import numpy as np

array=np.array([i for i in range(125)]).reshape(5,5,5)


#-----------------------------------------------------
input(’\n\n解决上面(020)的问题,随心所欲取块行列\n’)
#用np.ix_()包裹[0,1,2,4],[0,2,3,4]
print(array[np.ix_([0,1,2,4],[0,2,3,4])])

#-----------------------------------------------------
input('\n\n顺便看一下np.ix_([0,1,2,4],[0,2,3,4])是什么\n')
print(np.ix_([0,1,2,4],[0,2,3,4]))

#-----------------------------------------------------
input('\n\n把[0,1,2,4],[0,2,3,4]中的[0,1,2,4]换成[[0,1,2,4]]再转置效果也能达到这个效果\n')
tmp=np.array([[0,1,2,4]]).T
print(array[tmp,[0,2,3,4]])

022.组合


import numpy as np

lst1=[0,1,2,3,4]
lst2=[4,5,6,7,8]
lst3=[9,8,7,5,6]


array1=np.array([lst1,lst2,lst3])
print(array1)

input( 'next ')
arr1=np.array(lst1)
arr2=np.array(lst2)
arr3=np.array(lst3)
array2=np.array([arr1,arr2,arr3])

print(array2)

023.bool索引


import numpy as np

array=np.arange(100)#相当于np.array([i for i in range(100)])


#-------------------------------------
input(’\n\nbool索引\n’)
array_bool=array%3==0
print(array_bool)

#-------------------------------------
input('\n\n保留3的倍数\n')
array_mod3=array[array_bool]
print(array_mod3)

3.数组存入文件、从文件中导入数组

030.导入txt文件、数组储存为txt文件


import numpy as np

#--------------------------------------------------
input('\n\n读取txt文件\n')
array1=np.genfromtxt('abc.txt',dtype=np.str)
print(array1)

#delimiter  分隔符
array2=np.genfromtxt('abc.txt',dtype=np.int16,delimiter=' &QAQ& ')
print(array2)


#--------------------------------------------------
input(’\n\n读取txt文件,用numpy.loadtxt貌似和numpy.genfromtxt差不多\n’)
print(‘但貌似genfromtxt功能强一些,下方改为dtype=np.int16会报错,而genfromtxt不会’)
array3=np.loadtxt(‘abc.txt’,dtype=np.str,delimiter=’ &QAQ& ')
print(array3)


#--------------------------------------------------
input(’\n\n保存数组为txt\n’)
array1[0,0]=0
np.savetxt(‘abc_2.txt’,array1,fmt=’%s’,delimiter=’ &QAQ& ')
#参数依次为 保存为txt文件的名字 要保存的数组的名字 元素储存格式 分隔符
print(‘保存完成’)

031.二进制储存、导入一个数组


import numpy as np

array1=np.arange(48).reshape(6,8)
array2=array1.reshape(8,6)

print('二进制读写')

#--------------------------------------------------
input('\n\n储存一个数组,array1\n')
np.save('abc-b.sadfsd',array1)
print('储存完成')
print('你会发现储存后文件的后缀名永远是npy(如果不是,会自动补上)')


#--------------------------------------------------
input(’\n\n读取一个数组,格式npy\n’)
array9=np.load(‘abc-b.sadfsd.npy’)
print(array9)

032.对于多个数组


import numpy as np

array1=np.arange(48).reshape(6,8)
array2=array1.reshape(8,6)

#--------------------------------------------------
input('\n\n储存多个数组,用numpy.savez()\n')
np.savez('abc-b.sadfsd',giao=array1,cxkjntm=array2)
#giao 和 cxknjntm是数组的key值(类似字典),下面会说
print('储存完成')
print('你会发现储存后文件的后缀名永远是npz(如果不是,会自动补上)')


#---------------------------------------------------
input(’\n\n读取一个或多个数组(读取一个npz文件)\n’)
array_home=np.load(‘abc-b.sadfsd.npz’)
print(array_home)
print(‘发现这样读出了一个地址’)

#---------------------------------------------------
input('\n\n分别输出之前存入的array1 array2\n')
print(array_home['giao'])
print(array_home['cxkjntm'])

4.数组的合并与拆分

040.列合并1 np.c_[]


import numpy as np

array1=np.arange(16).reshape(4,4)
array2=np.array([111,222,333,444])

print('注意array2是个一个四行一列向量,是个列向量:array2.shape:',array2.shape)
input()

input('列合并,注意np.c_[]中的括号是方括号')
combie1=np.c_[array1,array2]
combie2=np.c_[array2,array1]

print(combie1,"\n\n",combie2)

041.列合并2 np.column_stack()

注意参数是元组形式


import numpy as np

arr1=np.arange(4)
arr2=np.arange(4,8)
arr3=np.arange(8,12)

input('列叠加若干个一维列向量\n\n')
combie1=np.column_stack((arr1,arr2,arr3))
print(combie1)

input('按列合并数组')
mid1=np.column_stack((arr1,arr2))
combie2=np.column_stack((mid1,arr3))
combie3=np.column_stack((combie2,combie2))

print(combie3)

042.行合并1 np.r_[]


import numpy as np

array1=np.arange(16).reshape(4,4)
array2=np.array([111,222,333,444])

print('注意array2是个一个四行一列向量,是个列向量:array2.shape:',array2.shape)
print('如果使用行合并np.r_[]需要先把array2转化称行向量')
input()

input('行合并,注意np.r_[]中的括号是方括号')
combie1=np.r_[array1,array2.reshape(1,4)]
combie2=np.r_[array2.reshape(1,4),array1]

print(combie1,"\n\n",combie2)

043.行合并2 np.row_stack()

注意参数是元组形式


import numpy as np

arr1=np.arange(4)
arr2=np.arange(4,8)
arr3=np.arange(8,12)

input('行叠加若干个一维列向量\n\n')
combie1=np.row_stack((arr1,arr2,arr3))
print(combie1)
print("注意这里不用先把列向量转化为行向量,因为一维列向量会在函数内转化称二维行")

input('按行合并数组')
mid1=np.row_stack((arr1,arr2))
combie2=np.row_stack((mid1,arr3))
combie3=np.row_stack((combie2,combie2))

print(combie3)

044.拆分split


import numpy as np

#新建0-63的4x4x4三维数组
array1=np.arange(64).reshape(4,4,4)
print(array1)


input(“用 split方法拆分数组,参数见注释\n”)
#用split(ary, indices_or_sections, axis=0)拆分

#axis表示分割轴的方向
#(解释沿某方向:假设二维数组沿水平方向切割,可以想象有一条水平方向的轴线,沿着找条水平轴线的方向把轴线竖切称若干份,得到若干份数组)
#关于axis: 自己实验发现axis=0表示以最高维度方向为分割方向,如三维数组沿深度方向分割,二位数组沿垂直方向分割
#axis=1 ,沿第二高的维度方向分割 以此类推

#当indices_or_sections为整数x,则把数组平分成x份,若不能平分则报错
#当indices_or_sections为列表,则按照列表中的元素为轴拆分数组
arr1=np.split(array1,4,2)
print(arr1,'\n\n')
arr2=np.split(array1,[1,3],2)
print(arr2)

045.拆分hsplit,vsplit,dsplit


import numpy as np

#新建0-63的4x4x4三维数组
array1=np.arange(64).reshape(4,4,4)
print(array1)

print('分别使用hsplit,vsplit,dsplit分割\n(horizontally,vertically,depth)\n')
print('注意:hsplit相当于axis=1,vsplit相当于axis=0,dsplit相当于axis=2')
print('\n\n\n分别使用h,v,d方法拆分三维数组:')

input('hsplit(ary, indices_or_sections),两参数同split一样\n')
print(np.hsplit(array1,[1,2,3]))

input('vsplit(ary, indices_or_sections),两参数同split一样\n')
print(np.vsplit(array1,4))

input('dsplit(ary, indices_or_sections),两参数同split一样\n')
print(np.dsplit(array1,4))

#貌似拆分数组维度不变

046.根据拆分类比多维数组的合并


import numpy as np

类比 split      hsplit vsplit dsplit
有 concatenate  hstack vstack dstack

np.vstack((a,b))  
效果大概同  
np.concatenate((a,b),axis=0)#注意(a,b)是元组形式的

v:axis=0
h:axis=1
d:axis=2

【学习记录】【Python】【numpy】自学numpy库的简要记录帖(已经腰斩换新的).md

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

1.极其基础的操作


import numpy as np

#创建一个数组 数组的类型为numpy.ndarray,其中数据的类型为numpy.int32s
array1=np.array([[[1,2,3],[4,5,6],[7,8,9]],[[10,11,12],[13,14,15],[16,17,18]]],dtype=np.int32)
print(array1,'\ntype of array1 is:',type(array1))

#查看数组维数
print('dimensions of array1:',array1.ndim)

#查看数组形状
print('shape of array1:',array1.shape)

#改变数组形状
array2=array1.reshape(6,3)
print(array2)

#提取数据(array2是二维数组)
print(array2[1:4,0:2])          #2、3、4行前两列
print(array2[1:4][0:2])         #两次切片  [1:4]切完后再[0:2]
print(array2[:,2])              #第三列
print(array2[:4])               #前四行
print(array2[:4,:])             #前四行

#数组的大小
print('size of array1 and array2:',array1.size,array2.size)

#矩阵计算
print(array1+array2.reshape(2,3,3))     #矩阵相加
print(array1*array2.reshape(2,3,3))     #矩阵相乘
print(array1+2)                         #矩阵元素+2

2.索引


import numpy as np

array1=np.array([[[1,2,3],[4,5,6],[7,8,9]],[[10,11,12],[13,14,15],[16,17,18]]],dtype=np.int32)


#取元素 第一维的一、二项,第二维的第一项,第三维的一、三项
array2=array1[np.ix_([0,1],[0],[0,2])]
print(array2)

#取 array1[0,0,0],以及 array1[1,2,1](最终取出两个数,1和17:[1,17])
array3=array1[[0,1],[0,2],[0,1]]
print(array3)

#顺序变的
array4=array1.reshape(6,3)[[0,5,3,1]]
print(array4)

#bool索引
array3=np.array(range(100))     #建立一个0-99的一维数组
print(array3)

array3Bool=array3%3==0          #意会
print(array3Bool)

array3Final=array3[array3Bool]          #得到array3中是3的倍数的项
print(array3Final)
array3Final_another=array3[array3%3==0] #得到array3中是3的倍数的项
print(array3Final_another)

3.简单文件储存


import numpy as np

#txt
x=np.genfromtxt('abc.txt',delimiter='&&',dtype=np.str,usecols=1)        #载入文件
print(x)
#delimiter 分割值
#dtype 数据类型
#usecols 不太清楚

y=np.loadtxt('abc.txt',delimiter='&&',dtype=np.str,usecols=1)           #载入文件
print(y)

np.savetxt('bca.txt',y,fmt='%s')


print(‘分割线-----------------------’)
#二进制

np.save('b_bca.npyy',y)                     #使用此方法保存的后缀名文件总为npy:  b_bca.npyy.npy

np.savez('b_z_bca.npz',the_x=x,the_y=y)     #此方法可以保存多个数组,后缀名为npz  the_x等形参名对应导入后的操作的键名

tmp_a=np.load('b_bca.npy')
print(tmp_a)

tmp_b=np.load('b_z_bca.npz')
print(tmp_b)
print(tmp_b['the_x'])                   #类似字典,key值为先前保存时的形参名,如the_x
print(tmp_b['the_y'])

4.简单练习 && 矩阵的合并与转置


import numpy as np

np.set_printoptions(precision=1,threshold=3000,suppress=True)
#precision控制小数点位数
#threshold控制输出值的个数,其他的以...代替(查的资料上这么说的,实际没看出效果)
#suppress=True 取消使用科学计数法


array1=np.genfromtxt(r’D:\0我的下载\上证指数\上证指数副本.txt’,usecols=(0,4,6),)
print(array1)

daySpan=(array1[:,0]>=20180901)&(array1[:,0]<20190101)  #筛选出其中2018年9月1日至2019年1月1日的信息
array2=array1[daySpan]                                  #筛选出其中2018年9月1日至2019年1月1日的信息
print(array2)

#纵向合并
#把array1第三列大于0的设为1,不大于0的设为-1,添加至数组最右边
tmp=array1[:,2].copy()
tmp[tmp>0]=1
tmp[tmp<=0]=-1
array_new=np.c_[array1,tmp]#等同于array_new=np.column_stack((array1,tmp))
print(array_new)

#横向合并
arr1=np.array([[1,2,3],[4,5,6],[7,8,9]])
arr2=np.array([['x','x','x']])

arr_new=np.r_[arr1,arr2]#等同于arr_new=np.row_stack((arr1,arr2))
print(arr_new)

#一维数组默认时列向量,要转化为行向量才能横向合并
#eg:[1,2,3]这是一个列向量 (3,)
#eg:[[1,2,3]]这时一个行向量(1,3)



#矩阵的转置
print(arr_new.T)

5.矩阵的切割


import numpy as np

#新建0-15的数组
array1=np.arange(16).reshape(4,4)
print(array1)


#用hsplit(ary,indices_or_sections)拆分 (相当于split的axis参数=1)
#纵向拆分
#第二个参数:如果时整数x,则把数组平均分成x份,不能平均分会报错
#第二个参数,如果时列表,会以列表中的值为轴拆分
h_arr1=np.hsplit(array1,4)
print(h_arr1)
h_arr2=np.hsplit(array1,[1,3])
print(h_arr2)


#用split(ary, indices_or_sections, axis=0)拆分
#用法基本同hsplit一样,只不过hsplit只能纵向拆分,split可以定义拆分维度
#axis=0第一维,即横向拆分,axis=1第二维,即纵向拆分
arr1=np.split(array1,4,0)
print(arr1)
arr2=np.split(array1,[1,3],0)
print(arr2)

6.图像通道的分离与合成

分离:
img1B,img1G,img1R=np.dsplit(img1,3)
img1B,img1G,img1R=cv2.split(img1)都可以
合成:
cv2.merge([b,g,r])
cv2.merge([zeros, zeros, img1R])

注意倒数第五句的注释


import cv2
import numpy as np

def showone(img):
    cv2.imshow('show image',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
def showone_color(img,color):
    zeros=np.zeros(img.shape[:2],dtype='uint8') #记得调整格式
    if color == 'B':
        cv2.imshow('blue',cv2.merge([img1B,zeros,zeros]))
    elif color == 'G':
        cv2.imshow('green', cv2.merge([zeros, img1G, zeros]))
    elif color == 'R':
        cv2.imshow('red', cv2.merge([zeros, zeros, img1R]))
    cv2.waitKey(0)
    cv2.destroyAllWindows()
def showone_merge(b,g,r):
    cv2.imshow('merge',cv2.merge([b,g,r]))
    cv2.waitKey(0)
    cv2.destroyAllWindows()


img1=cv2.imread(‘theimg.png’,1)

img1B,img1G,img1R=np.dsplit(img1,3)
#img1B,img1G,img1R=cv2.split(img1)

print(img1B.dtype)          #矩阵元素的格式为uint8



showone(img1B) #这里图像为灰色,原因是当调用cv2.imshow的时候G、R两个通道被默认设为了与B通道一样,三通道一样时显示灰度图


showone_color(img1B,‘B’)
showone_color(img1G,‘G’)
showone_color(img1R,‘R’)

showone_merge(img1B,img1G,img1R)        #合成后是原图

【学习记录】【Python】【openpyxl】简要学习openpyxl 的 记录----未完待续.md

说明 - 2022-05-05

本篇博客为本人原创, 原发布于CSDN, 在搭建个人博客后使用爬虫批量爬取并挂到个人博客, 出于一些技术原因博客未能完全还原到初始版本(而且我懒得修改), 在观看体验上会有一些瑕疵 ,若有需求会发布重制版总结性新博客。发布时间统一定为1111年11月11日。钦此。

现阶段进行了简单的了解,不打算深究(后期来补: pandas挺好用的)

1.创建一个xls文件,随便写点东西,并保存


import openpyxl

wb  = openpyxl.Workbook()   #创建一个工作表

ws1 = wb.active             #获取“活跃的”表单
ws1.title='sheeeet1'         #更改表单的名字

ws1['B7']=15                           #给单元格赋值
ws1['C4']='CFour'
ws1['A2']='ttt'
ws1['A8']='AaAaAaAa'
ws1.append([1,2,'sfaf',56,'ABC'])       #给一行中的多个单元格赋值
ws1.append([1,1,1,11,1,1,1,1])

print(ws1.max_row)                      #最大行
print(ws1.max_column)                   #最大列

print(ws1['A2'].value)              
print(ws1['B14'].value)
print(ws1['B13'].value)                 #单元格无数据返回None


ws2 = wb.create_sheet(‘sheeeet2’) #创建一个表单
ws2[‘C3’]=‘ws2C3’


wb.save(‘xls_try1.xls’) #保存为xls文件

目测openpyxl.worksheet.worksheet.Worksheet类的append方法的添加位置是:最后有内容的一行 的下一行
即openpyxl.worksheet.worksheet.Worksheet.max_row的下一行

2.打开一个xls文件,随便进行点操作


import openpyxl

wb = openpyxl.load_workbook('xls_try1.xlsx')

ws_one = wb['sheeeet1']
print(ws_one['A2'].value)       #输出一个单元格的值

for each_row in ws_one['A9':'F10']:
    for each_cell in each_row:
        print(each_cell.value)      #输出多个单元格的值