Python,Java,Regex

Python

先看Python速成,剩下的是STL对各种语言的映射.

初等函数

str(),int(),float() 格式转换
ord() 求一个字(或字符)的编码(字母返回ascii码,中文返回Unicode码,必须传参传一个字或字符)
chr() 上述求编码的逆操作,对数字求编码出来的字符
len(x) 求一个字符串的长度
a.sort() 会对数列a进行排序
sorted(a) 会对a进行排序,同时返回一个新的排好序的列表
b=list(reversed(a)) 返回一个反转的列表,原列表不会改变.
round(xx,eps)把x舍入到小数点后eps位
eval() 可以取变量值,比如 eval(n3) 能返回n3这个变量的值

namespace

在指定名字空间内执行语句.

1
2
namespace={'a':2,'b':3}
eval('a+b',namespace)

标准库

set()

a=set() 创建一个无序但是不重复的集合.

add() 添加一个元素
update() 添加多个元素
remove() 删除元素,如果不存在会发生错误
discard() 删除元素不会引发错误
clear() 删除所有元素
| 集合的并运算(好高级啊)
& 集合的交运算
- 差集
^ 对称差集(只在一个集合中出现的元素)

math

log(a,b) 求 $\log_ba$
sqrt(x) 开根.

mpmath

比math库更高精度的任意位数高精度库.

1
2
mpmath.mp.dps=100 #设置精度位数是100位
mpmath.cos(x) #计算cos

decimal

十进制定点和浮点运算库,具有完全正确的十进制浮点运算结果,而且可以修改精度.

1
2
3
4
from decimal import *
getcontext().prec=6 #修改精度为小数点后六位
res=Decimal(1).sqrt() #Decmial是一个对象,内部函数的开根比math库精确
if res==Decimal(str(res)).to_integral_value(): # 判断一个数是不是整数

草台班子库,以后用就用 gmpy2.mpz

gmpy2

很好用的数学库.

1
n=gmpy2.mpz('一个9000位的数字')

直接输入会爆sys,怎么改也没用,只能使用别的库绕过.

类class

首先了解几个宏:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A:
def __init__(self,xx):
# 合构函数,变量在这里声明
self.x=xx # 在这里声明变量和参数作为类的内部变量(public)
def __del__(self): # 析构函数

def __lt__(self,other):
# < 自定义比较器,然后这个类就能用sorted()
return self.val<other.val
def __gt__(self,other): # >
def __le__(self,other): # <=
def __ge__(self,other): # >=
def __eq__(self,other):

def __repr__(self):
# 这个是类的自定义"标准单个输出",用于接输出流
return f"A{self.x}"

其他函数写起来就不难了.

数组

一维数组:

1
2
a=[]
a.append(114)

一维数组预留空间:(注意里面一定要有元素,否则30个空列表也是空列表)
1
a=30*[0]

二维数组:
1
2
array=[[0 for _ in range(2)] for _ in range(3)]
# in C: array[3][2]

技巧/特性

  1. 读多个一行用空格隔开的整数:知道有多少个数:
    1
    a,b,c=map(int,input().split())
    不知道有多少个数:
    1
    num_list=list(map(int,input().split()))
  2. Python re了可能是因为很大的整数转字符串爆了(有最大限制),用这个取消限制:
    1
    sys.set_int_max_str_digits(0)
  3. 和其他大多数程序一样,按Ctrl+C立刻结束程序.

  4. int('1')=1 Python的字符串1转成数字1直接就是1,不是ascii码

  5. 函数返回值的特性:

    1
    math.cos(Decimal(114514))

    的返回值是 float 不是 Decimal (感觉Decimal也是草台班子库,比不了mpmath半根)

  6. try except 上一句执行失败抛错误了就执行下面的东西,在base16,32,64的随机加密然后找flag有奇效(密码经常可能解密失败出现乱码)

  7. Python直接写入二进制,比如直接写入一个 0xAA 之类的数字:

    1
    2
    3
    4
    5
    with open('res.bin','wb') as f:
    a=10
    f.write(bytes([a]))

    # 在这里(非一层缩进)写代码文件会被关闭.
  8. Crypto.Util.number.getPrime(114) 用于生成二进制位是 114 的随机质数.

  9. enumerate(dat) 用于将一个数组加一个下标,形成类似”下标-数据”的格式.

  10. 数组冒号用法: a[j:k] 一个冒号是切片,返回区间的数组,出现负数表示倒数第某个位置.
    a[i:j:k] 新增的k表示步长,负数表示倒着枚举.

  11. type() 输出一个变量的类型

  12. 在Python中,字符串是 不可变的 ,如果想使用类似string的要把字符串转换成列表,然后对列表进行操作,然后再转回字符串,如:

    1
    2
    3
    4
    5
    s='abcdef'
    ss=list(s)
    ss[0]='z'
    s=''.join(ss)
    print(s) #zbcdef
  13. 算一个一元函数的最小值点:使用 scipy.optimizefminbound(func,l,r) 秒了(精度默认1e-5),谁还退火啊…

  14. 写欧拉筛的时候碰到的问题:

    1
    2
    3
    4
    5
    ptop=0
    def sieve(n):
    # global ptop
    ...
    ptop+=1

    变量类型的ptop默认不能访问全局变量,然后就报错.解法:ptop加上全局标签,表示使用全局的那个ptop(数组是默认使用全局的,因为复制的开销可能很大)

  15. 字典的遍历:

    1
    2
    3
    4
    5
    dic={1:'A',2:'B'}
    for i in dic:
    print(i)# 1 2
    for i,j in dic.items():
    print(i,j)# 1 A 2 B
  16. numpy的矩阵使用:
    1
    2
    3
    4
    5
    mat=numpy.array([
    [1,2], # 1 2
    [3,4], # 3 4 创建一个这么矩阵
    ])
    mat@maat # 这个是矩阵乘法,不是*号

opencv2

opencv2存储图像的本质是一个numpy数组,所以两个图像的严格比较记得写 .any().all()

1
2
3
4
5
6
7
8
9
10
11
12
image = cv2.imread('out2.png') # 读图像
if image is None: # 判空
exit()
iimg=image[y_begin:y_end,x_begin:x_end]
iiimg=image[????]
if (iimg==iiimg).all(): # 图像完全一致
xx

cv2.imwrite('a.png',iimg) # 写入文件
cv2.imshow('Cropped Image',iimg) # 弹窗展示你的图片
cv2.waitKey(0) # 等待用户按键
cv2.destroyAllWindows() # 结束

Java

先看Java速成.

输入

1
2
3
4
5
6
7
8
import java.util.Scanner;
public class Main{
public static void main{
Scanner sc=new Scanner(System.in);
int t;
t=sc.nextInt();
}
}

多维数组

1
int [][][][][][]dat=new int[1][2][3][4][5][6];

指针

除了Java的几种基本类型(int string float double long byte boolean short)在函数中是复制传参的之外,所有类型的传递参数都是引用.也就是说,函数传参int,改变不会影响外部的值,传参abc(自定义类)传的是一个指针,abc怎么变不影响abc.(里面的东西),但是abc.xx变了会影响外部.

auto

使用 var 关键字可得到类似效果.

Regex(正则表达式)

原则

  1. 一个字符最多只能被匹配一次,匹配上之后不会再参与后续匹配.
  2. 正则表达式总是倾向于单次匹配最少的字符,如 1?1?1 匹配 1111 结果是得到一个 111 而不是字符更多的四个 1

正则入门
正则测试
正则交互学习

开始

[] 里面划定字符集,匹配一个,里面可以 a-z 这么用.
[^] 否定字符集.

字符后面加上下面的字符控制前面一个字符的出现数量:
+ $[1,+\infty)$
* $[0,+\infty)$
? $[0,1]$
{a,b} $[a,b]$ 精确次数控制,ab可以不填,表示0或infty

C_Regex

新的C++标准已经加上了regex(虽然时间复杂度比较玄学)

1
2
3
4
string s;
cin>>s;
s=regex_replace(s,regex(R"A"),"B");
cout<<s;

Java板子

严正声明:算竞少用Java,太慢了!!!
笔者的线段树1板子的C++跑了195ms,然而Java近乎完全相同的写法直接用Scanner被卡常了,参考这个改过之后跑了6.96s,慢20倍还真不是开玩笑的.

IO

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
import java.io.*;
import java.util.*;
public class Main{
static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter pw=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static int Int() throws IOException {
st.nextToken();
return (int) st.nval;
}
static long Long() throws IOException {
st.nextToken();
return (long) st.nval;
}
public static void main(String[] args) throws IOException{
try{
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
st.nextToken();int n=(int)st.nval;//输入n

//代码主体

PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
pw.println(n);//输出n
pw.flush();
pw.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}

线段树(lazy)

支持区间加的板子.

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
class SegTree{
public class node{
int l,r;
long val,lazy;
}
public long[] ddat;
public node[] dat;
public int top;
public SegTree(){
top=0;
ddat=new long[100010];
dat=new node[300010];
for(int i=0;i<dat.length;i++){
dat[i]=new node();
}
}
public int bbuild(int l,int r){
if(l>=r){
++top;
dat[top].val=ddat[l];
dat[top].lazy=0;
return top;
}
int mid=(l+r)>>1,tmp=++top;
dat[tmp].l=bbuild(l,mid);
dat[tmp].r=bbuild(mid+1,r);
pushup(tmp);
return tmp;
}
public void pushdown(int mod,int l,int r){
if(dat[mod].lazy!=0){
int mid=(l+r)>>1;
dat[dat[mod].l].val+=dat[mod].lazy*(mid-l+1);
dat[dat[mod].r].val+=dat[mod].lazy*(r-mid);

dat[dat[mod].l].lazy+=dat[mod].lazy;
dat[dat[mod].r].lazy+=dat[mod].lazy;
dat[mod].lazy=0;
}
}
public void pushup(int mod){
dat[mod].val=dat[dat[mod].l].val+dat[dat[mod].r].val;
}
public long qquery(int mod,int l,int r,int tl,int tr){
if(tl<=l&&r<=tr){
return dat[mod].val;
}
pushdown(mod,l,r);
int mid=(l+r)>>1;
long res=0;
if(tl<=mid)res+=qquery(dat[mod].l,l,mid,tl,tr);
if(tr>mid)res+=qquery(dat[mod].r,mid+1,r,tl,tr);
return res;
}
public void aadd(int mod,int l,int r,int tl,int tr,long val){
if(tl<=l&&r<=tr){
dat[mod].lazy+=val;
dat[mod].val+=val*(r-l+1);
return;
}
pushdown(mod,l,r);
int mid=(l+r)>>1;
if(tl<=mid)aadd(dat[mod].l,l,mid,tl,tr,val);
if(tr>mid)aadd(dat[mod].r,mid+1,r,tl,tr,val);
pushup(mod);
}
}