Wei Jiang


  • 首页

  • 分类

  • 归档

  • 标签

multi-factors-model(MFM)

发表于 2017-04-19

##多因子择股
量化交易中的要点,不外乎择股,择时以及风险控制。如果买卖时机的选择看的是你对市场波动的敏感度,股票的选择就是看你对证券价值的判断标准了。凭借什么样的条件来选择想要持有的股票,不同的投资者有不同的标准,可能是依据公司三大表数据的基本面和财务面分析;也可能是依赖于公司证券在市场中价格波动的市场面分析。孰优孰劣不做评价

#1. 策略背景
基本面和财务面都可以叫做基本面分析,都依赖于公司三大表的财务数据。
多因子图解
1 基本面分析

每股盈余---等于盈余/流通股树。每股盈余高代表公司每单位资本额的获利能力高,表示该公司能有效利用资源创造出高获利

营收增长率---反应公司的营运好坏,当营收持续成长表示公司规模处于扩张期,通常说明公司比较距离获利潜力(其实也有意外,比如胜华科技,已然破产)。因此营收创新高的公司,在股价会有所表现。

净值---等于公司总资产扣除总负债后的价值;净值是一家公司被复制的成本,所以当公司股价低于每股净值,该公司股价可能被低估,若股价净值比较低则在此情况下公司甚至因此而有机会被并购。

股本---衡量公司规模大小的指标。股本大小代表筹码多寡,筹码少的股票具有稳定的优点,而筹码多的股票则相对而言具有较好的流通性。

2 财务面分析

资产报酬率(ROA)---衡量公司是否充分利用资产以创造获利的指标,资产报酬率能够衡量公司的运营状况是否能使其资产运用效率达到最佳。

股东权益报酬率(ROE)---代表该年度股东权益的成长速度,而古董权益报酬率由企业保留盈余所获得,因此显示企业不依赖于对外举债也能促使企业成长的能力。

毛利率--反映了公司产品获利能力,具有高毛利率的公司往往是该产业领域的龙头厂商。通过观察毛利率将可找出公司获利变化的趋势当公司毛利率往上提升时期代表公司的新产品效益出现,或是规模经济量显现,都是公司体质好转的迹象。

资产负债率---负债总额与资产总额之比,是衡量一家公司的资本结构的重要指标。资本主要来源于股东出资或是负债,负债有发挥财务杠杆的功能,有助于提高投资报酬率,并且由于利息费用可以抵税,因此也有税务上的优点。缺点是负债过高时候,由于杠杆因素也将使风险提高,若同时发生营运不如预期甚至有倒闭的风险。

营业利益旅---为公司每创造一单位的营收所能产生的获利。营业利益考虑了在取得收入的过程中所耗用的一切成本。当营业利益率发生变化,冗长代表公司体质发生转变,比如新产品效益出现,规模经济量显现伙食管理能力的提升等等,这些公司体质转好的效益都会显示现在营业利益率中。

3 市场面分析(几个典型的)

涨幅---最基本的指标,其衍生出来的RS\RSP指标等都被广泛使用,追涨也是股票市场中的一种基本操作之一。如果股票在过去一段时间有较好的涨幅,根据惯性定力,其股价在未来一段时间也拥有较好的涨幅。

流通市值---反应证券规模的一个基本指标;一般流通市值过大的股票则难以操作,而小市值的股票存在更高的风险,流通市值适中的股票才有利于资金运作和散户追涨杀跌。

成交量---反映了证券过去一段时间的“受欢迎程度”,成交量大的股票,在市场中的“受欢迎程度”自然越高,通过成交量筛选,能够筛出有价无市的个股。

clustering

发表于 2017-03-28

聚类 clustering

  1. k-means;
  2. LVQ(learning vector quantization);
  3. Mixture-of-Gaussian
  4. 密度聚类; DBSCAN(neighborhood参数: epsilon, MinPts)
  5. 层次聚类 hierarchical clustering; AGNES[自低向上聚合策略,层次聚类算法]

design_pattern

发表于 2017-03-01   |   分类于 OOD

Singleton mode

独一无二,只有一个实例对象。比如:线程池(threadpool), cache, 对话框,注册表对象,日志对象,

  1. 构造器私有,因为私有的构造器的泪不能被实例化,又因为只有实例化后才能调用构造器。鸡生蛋,蛋生鸡的问题。如果有一个静态方法,可以这样调用:
    MyClass.getInstance();, 因为getInstance()是一个静态方法,是一个类方法,引用一个静态方法需要使用类名。
    单例模式的优点:

在内存中只有一个对象,节省内存空间。
避免频繁的创建销毁对象,可以提高性能。
避免对共享资源的多重占用。
可以全局访问。

适用场景:由于单例模式的以上优点,所以是编程中用的比较多的一种设计模式。我总结了一下我所知道的适合使用单例模式的场景:

需要频繁实例化然后销毁的对象。
创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
有状态的工具类对象。
频繁访问数据库或文件的对象。
以及其他我没用过的所有要求只有一个对象的场景。

python_tips

发表于 2017-02-04

Python 基础复习
不复习老忘

Character Format
d, Integer
u Unsigned integer
f Floating point as m.ddddd
e Floating point as m.ddddde+/-xx
E Floating point as m.dddddE+/-xx
g Use %e for exponents less than −4−4 or greater than +5+5, otherwise use %f
c Single character
s String, or any Python data object that can be converted to a string by using the str function.
% Insert a literal % character
Modifier Example Description
number %20d Put the value in a field width of 20
- %-20d Put the value in a field 20 characters wide, left-justified
+ %+20d Put the value in a field 20 characters wide, right-justified
0 %020d Put the value in a field 20 characters wide, fill in with leading zeros.

Built-in Collection Data Types¶

methods used to build data structures

list

Method Name Use Explanation
append alist.append(item) Adds a new item to the end of a list
insert alist.insert(i,item) Inserts an item at the ith position in a list
pop alist.pop() Removes and returns the last item in a list
pop alist.pop(i) Removes and returns the ith item in a list
sort alist.sort() Modifies a list to be sorted
reverse alist.reverse() Modifies a list to be in reverse order
del del alist[i] Deletes the item in the ith position
index alist.index(item) Returns the index of the first occurrence of item
count alist.count(item) Returns the number of occurrences of item
remove alist.remove(item) Removes the first occurrence of item

big O for list operation

Operation Big-O Efficiency
index [] O(1)
index assignment O(1)
append O(1)
pop() O(1)
pop(i) O(n)
insert(i,item) O(n)
del operator O(n)
iteration O(n)
contains (in) O(n)
get slice [x:y] O(k)
del slice O(n)
set slice O(n+k)
reverse O(n)
concatenate O(k)
sort O(n log n)
multiply O(nk)

string

Method Name Use Explanation
center astring.center(w) Returns a string centered in a field of size w
count astring.count(item) Returns the number of occurrences of item in the string
ljust astring.ljust(w) Returns a string left-justified in a field of size w
lower astring.lower() Returns a string in all lowercase
rjust astring.rjust(w) Returns a string right-justified in a field of size w
find astring.find(item) Returns the index of the first occurrence of item
split astring.split(schar) Splits a string into substrings at schar

set

Method Name Use Explanation
union aset.union(otherset) Returns a new set with all elements from both sets
intersection aset.intersection(otherset) Returns a new set with only those elements common to both sets
difference aset.difference(otherset) Returns a new set with all items from first set not in second
issubset aset.issubset(otherset) Asks whether all elements of one set are in the other
add aset.add(item) Adds item to the set
remove aset.remove(item) Removes item from the set
pop aset.pop() Removes an arbitrary element from the set
clear aset.clear() Removes all elements from the set

dictionary

Method Name Use Explanation
keys adict.keys() Returns the keys of the dictionary in a dict_keys object
values adict.values() Returns the values of the dictionary in a dict_values object
items adict.items() Returns the key-value pairs in a dict_items object
get adict.get(k) Returns the value associated with k, None otherwise
get adict.get(k,alt) Returns the value associated with k, alt otherwise
Operator Use Explanation
[] myDict[k] Returns the value associated with k, otherwise its an error
in key in adict Returns True if key is in the dictionary, False otherwise
del del adict[key] Removes the entry from the dictionary

ubuntu config

发表于 2017-01-01

自带的vi太难用,先装vim,terminal中输入vi,然后tab键,可以看到系统只安装了vi和vim.tiny

1
$ vi tab

输入命令

1
$ sudo apt-get install vim-gtk

安装好之后再输入vi + tab可以看到已经安装了vim,
再输入

1
$ sudo vim /etc/vim/vimrc

会打开vim配置文件,默认syntax on,说明语法高亮。就可以了

supervisor这个坑终于能填上了

不知道写这个包的人怎么想的,不同版本之间bug这么多,踩过的坑一定要记下来
1 不要用apt-get安装supervisor,apt-get版本是3.0b2版本,可能有bug,官方安装(easy_install和pip),按照官方说明配置
解决方法: 删除老版本,用easy_install安装,现在是3.3.1版本

1
2
$ sudo apt-get remove --auto-remove supervisord
$ sudo easy_install supervisor

2 安装好之后run echo_supervisord_conf,可以打印一份配置文件sample。
修改配置文件,不同安装方法配置文件也在不同的地方!!,官方文档说下面几个路径都会去搜索

1
2
3
4
5
6
1: $CWD/supervisord.conf
2: $CWD/etc/supervisord.conf
3: /etc/supervisord.conf
4: /etc/supervisor/supervisord.conf (since Supervisor 3.3.0)
5: ../etc/supervisord.conf (Relative to the executable)
6: ../supervisord.conf (Relative to the executable)

我们采用3的路径方法,先把sample配置文件导入/etc/supervisord.conf(需要super user权限)

1
2
# 把官方配置文件例子导入到/etc/supervisord.conf的文件中
$ sudo echo_supervisord_conf > /etc/supervisord.conf

如果出现permission denied,说明需要super user

1
$ su -c "echo_supervisord_conf > /etc/supervisord.conf"

然后用vim编辑配置文件,在最后一行添加webapp的设置保存退出

1
2
3
4
5
6
7
8
9
10
11
12
13
$ sudo vim supervisord.conf
[program:awesome]
command = python3 /home/wei/srv/awesome/www/app.py
directory = /home/wei/srv/awesome/www
user = www-data
startsecs = 3
redirect_stderr = true
stdout_logfile_maxbytes = 50MB
stdout_logfile_backups = 10
stdout_logfile = /home/wei/srv/awesome/log/app.log

这里有几个坑需要注意

<1> stdout_logfile 路径需要指定绝对路径,command也是一样,否则会出现log file does not exist的报错。

<2> 因为supervisor只支持python2.7而不是python3(坑爹啊!!!),所以在app前面指定python3,如果还不行就指定python3的绝对路径。应该是用python2启动supervisor,然后再守护python3的进程? 这个还不确定,有待后续研究

<3> 在conf文件没法加载的情况下是没办法reload,或者restart的,所以可以用

1
sudo supervisorctl -c /etc/supervisord.conf reload

来reload,这时候会输出

1
Restarted supervisord

然后查看supervisor运行状态

1
2
3
sudo supervisorctl -c /etc/supervisord.conf status
output:
awesome RUNNING pid 20010, update 0:00:04

就说明运行了。oh yeah!~,这时候打开浏览器输入”http://127.0.0.1:9000",可以看到看到我们的网站啦。

再补充几个有用的:
Supervisor 有两个主要的组成部分:

  1. supervisord,运行 Supervisor 时会启动一个进程 supervisord,它负责启动所管理的进程,并将所管理的进程作为自己的子进程来启动,而且可以在所管理的进程出现崩溃时自动重启。
  2. supervisorctl,是命令行管理工具,可以用来执行 stop、start、restart 等命令,来对这些子进程进行管理。
    有的时候提示: 启动supervisord失败,提示error: , [Errno 2] No such file or directory: file: /usr/lib/python2.7/socket.py line: 228 找不到socket文件
    解决方法:重启supervisord的进程,再reload supervisorctl
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ sudo ps ax | grep supervisor # 查询supervisord进程,
    2516 ? Ss 1:35 /usr/bin/python /usr/local/bin/supervisord #记住第一个进程pid
    19342 pts/1 S+ 0:00 grep --color=auto supervisord #这是grep命令的进程,不用管
    # 如果没有supervisord这个进程,说明并没有启动,继续检查配置文件
    $ sudo kill 2516 # 杀死这supervisord该死的进程
    $ sudo supervisord # 启动supervisord
    $ sudo supervisorctl reload # reload supervisordctl
    $ sudo supervisorctl start awesome # 启动程序
    $ sudo supervisorctl status # 查看状态

C++中的comparator

发表于 2016-12-18

自定义了对象,如何按照自定对象中某一或多个元素对其进行排序呢?以下分别从C++和Java对其进行实现。

一:C++

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
/*
实现对自定义的对象类型进行排序(按照其中的元素),首先将对象存放在vector中,然后利用algorithm库函数中的sort对其进行排序,需要重写排序函数以函数名
作为函数指针作为sort的第三个参数
*/
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
struct students{
int age;
string name;
};
void addStudents(vector<students> &vec, int age, string name){
students stu;
stu.age = age;
stu.name = name;
vec.push_back(stu);
}
// 按照年龄进行排序 升序
bool sortByAge(const students &s1, const students &s2){
return s1.age < s2.age;
}
// 先按照年龄进行排序 年纪一样 按照姓名排序
bool sortByAll(const students &s1, const students &s2){
if(s1.age < s2.age) return true;
else if(s1.age > s2.age) return false;
else return s1.name < s2.name;
}
int main(){
vector<students> vec;
addStudents(vec, 20, "zhangming");
addStudents(vec, 20, "xiaoming");
addStudents(vec, 20, "xiaoming2");
addStudents(vec, 23, "xiaohong");
addStudents(vec, 22, "xiaofei");
addStudents(vec, 27, "xiaogang");
cout << "排序前:" << endl;
for(vector<students>::iterator iter = vec.begin(); iter != vec.end(); ++iter){
cout << (*iter).age << " " << (*iter).name << endl;
}
sort(vec.begin(), vec.end(), sortByAll);
cout << "排序后:" << endl;
for(vector<students>::iterator iter = vec.begin(); iter != vec.end(); ++iter){
cout << (*iter).age << " " << (*iter).name << endl;
}
}

服务器配置经验.md

发表于 2016-12-13   |   分类于 Linux

#Linux server配置经验
因为要部署webapp到服务器,准备用自己的linux验证一下再上传到aws上,写这篇文章记录一下。
首先需要安装openssh-server,系统是ubuntu,至于是不是服务器版本或者桌面版都无所谓

1
$ sudo apt-get install openssh-server

一般来说安装好之后服务器可以连接,为了验证下可以这样:

1
$ ps -e | grep ssh

如果输出

1
2
8367 ? 00:00:00 sshd
16277 ? 00:00:00 ssh-agent

ssh-agent表示ssh-client启动,sshd表示ssh-server启动了。
ssh服务默认的端口是22,可以更改端口,使用如下命令打开ssh配置文件:

1
$ sudo gedit /etc/ssh/sshd_config

修改端口号(Port)后,重启ssh服务即可生效,命令如下:

1
$ sudo /etc/init.d/ssh restart

ssh服务启动后,即可登陆,登陆命令格式为:ssh 帐号@IP地址
不知道ip就ifconfig查看一下
比如我的是 ssh wei@192.168.1.6
输入用户名密码就可以把程序传上去喽!

dynamic programming note_jiuzhang

发表于 2016-11-06

什么情况下使用动态规划

满足下面三个条件之一,则极有可能使用动态规划 90% - 95%:

求最大值,最小值
判断是否可行
统计方案个数
极不可能使用动态规划的情况:

求出所有具体的方案而非方案的个数
输入数据是一个集合而不是序列
暴力的算法已经是多项式级别
动态规划的 4 点要素

状态 State
灵感,创造⼒,存储小规模问题的结果
最优解 / Maximum / Minimum
Yes / No
Count(*)
方程 Function
状态之间的联系,怎么通过⼩的状态,来求得⼤的状态
初始化 Intialization
最极限的小状态是什么,起点
答案 Answer
最⼤的那个状态是什么,终点
总结

什么情况下可能使用/不用动态规划?

最大值最小值/是否可行/方案总数
求所有方案/集合而不是序列/指数级到多项式
三种面试常见的动态规划类别及状态特点

坐标,单序列,双序列
两招独孤九剑

二维DP需要初始化第0行和第0列
n个字符的字符串要开n+1个位置的数组
坐标型

state:
f[x] 表示我从起点走到坐标x……
f[x][y] 表示我从起点走到坐标x,y……
function: 研究走到x,y这个点之前的一步
initialize: 起点
answer: 终点
单序列

以字符串居多

state: f[i]表示前i个位置/数字/字符,第i个…
function: f[i] = f[j] … j 是i之前的一个位置
initialize: f[0]..
answer: f[n]..
一般answer是f(n)而不是f(n-1), 因为对于n个字符,包含前0个字符(空串),前1个字符……前n个字符。
双序列

一般给两个字符串

state: f[i][j]代表了第一个sequence的前i个数字/字符,配上第二个sequence的前j个…
function: f[i][j] = 研究第i个和第j个的匹配关系
initialize: f[i][0] 和 f[0][i]
answer: f[n][m]
n = s1.length()
m = s2.length()
划分型

题目:给一个序列,求一次划分区间,求区间中的最大值

state: f[i] 表⽰示前 个元素的最⼤大值
function: f[i] = 前 i 个元素里⾯选一个区间的最⼤值
initialize: f[0]..
answer: f[n-1]..
优化

state:
gobal[i] 表示前 i 个元素的最大值
local[i] 表⽰示包含第 i 个元素前 i 个元素的最大值
function:
global[i] = 通过 local[i] 更新
local[i] = 通过原序列或者 global[i] 更新
initialize: global[0].. Local[i]
answer: global[n-1]..
背包型

特点:

用值作为DP维度
DP过程就是填写矩阵
可以滚动数组优化
Backpack

State:
f[i][S] “前i”个物品,取出一些能否组成和为S
Function:
f[i][S] = f[i-1][S - a[i]] or f[i-1][S]
Intialize:
f[i][0] = true; f[0][1..target] = false
Answer:
检查所有的f[n][j]
时间复杂度 O(n*S) , 滚动数组优化

区间型

特点:

求一段区间的解max/min/count
转移方程通过区间更新
从大到小的更新
这种题目共性就是区间最后求[0,n-1] 这样一个区间
逆向思维分析 从大到小就能迎刃而解
逆向 =》 分治类似

博弈型

博弈有先后手

State:
定义一个人的状态
Function:
考虑两个人的状态做状态更新
Initialize:
Answer:
先思考最小状态
然后思考大的状态-> 往小的递推,那么非常适合记忆化搜索
记忆化搜索

本质上:动态规划
动态规划就是解决了重复计算的搜索
大部分DP都可以用记忆化搜索做

动态规划的实现方式:

循环(从小到大递推)
记忆化搜索(从大到小搜索)
画搜索树
万金油
什么时候用记忆化搜索?

状态转移特别麻烦,不是顺序性。
初始化状态不是很容易找到
题目类型

博弈类问题
区间类问题
适合解决题目
状态特别复杂
初始化不好初始化。

tips

发表于 2016-10-23

#2d vector resize 可以用 dp.resize(matrix.size() + 1, vector(matrix.size() + 1, 0));

#统计是否包含某个字符(字母)可以统计字母出现的次数,比如字母就设定一个26元素的数组数组,统计字符在字母表中出现的字数即可

#BST的inorder遍历相当于生序排列,要熟悉用栈来实现

#删除bst节点,分三种情况: 1. 如果删除节点为叶子节点,直接删除,指向null。2. 如果其结点只包含左子树,或者右子树的话,此时直接删除该结点,并将其左子树,或者右子树设置为其父结点的左子树或者右子树即可,此操作不会破坏树结构。

  1. 当结点的左右子树都不空的时候,一般的删除策略是用其右子树的最小数据(容易找到)代替要删除的结点数据并递归删除该结点(此时为null),因为右子树的最小结点不可能有左孩子,所以第二次删除较为容易。z的左子树和右子树均不空。找到z的后继y,因为y一定没有左子树,所以可以删除y并让y的父亲节点成为y的右子树的父亲节点,并用y的值代替z的值.如图:

容易犯错的概念

c++ list是双向链表,iterator是双向迭代器,但是只支持++, –, != ==操作,不能比较也不能向前跨越,如果需要前进多步,则需要用advance函数,前提是要检查是否到达.end()。

list的insert(iterator position, const value_type& val),返回值是一个iterator,所以如果要在最末位插入元素并且返回一个iterator指向最后一个元素,可以用insert,而不用push_back.

list的erase,的参数是iterator(iterator erase(iterator position),或者iterator erase (iterator first, iterator last)),范围[first, last);,不支持用index,返回值也是一个iterator;但是unordered_map支持key和iterator的删除,因为元素是一个pair嘛,也好理解

list的swap是交换两个containor,而不是两个元素

以上为LRUCache踩过的坑,算法明白了,老有bug,记录下来不能再犯错了

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
class LRUCache {
int m_capacity;
list<pair<int, int>> cache;
unordered_map<int, list<pair<int, int>>::iterator> hs;
public:
LRUCache(int capacity) {
m_capacity = capacity;
}
int get(int key) {
if (hs.find(key) == hs.end()) return -1;
// erase的参数为iterator
pair<int, int> p = *hs[key];
cache.erase(hs[key]);
hs[key] = cache.insert(cache.end(), p);
return (*hs[key]).second;
}
void put(int key, int value) {
// 如果key有重叠,一定要把以前的擦掉,不然会残留在containor内,超过容量会把需要的元素弹出的
if (hs.find(key) != hs.end()) {
cache.erase(hs[key]);
hs[key] = cache.insert(cache.end(), make_pair(key, value));
}
else {
if (cache.size() == m_capacity) {
hs.erase(cache.front().first);
cache.pop_front();
// hashtable erase可以是iterator也可以是key
hs[key] = cache.insert(cache.end(), make_pair(key, value));
}
else {
hs[key] = cache.insert(cache.end(), make_pair(key, value));
}
}
}
};

##继续iterator,数组型和节点型iterator的区别
链接:https://www.nowcoder.com/test/question/done?tid=6738151&qid=55374
来源:牛客网

当使用一个容器的insert或者erase函数通过迭代器插入或删除元素”可能”会导致迭代器失效
iterator失效主要有两种情况:
1、iterator变量已经变成了“野指针”,对它进行*,++,–都会引起程序内存操作异常;
2、iterator所指向的变量已经不是你所以为的那个变量了。
不同的容器,他们erase()的返回值的内容是不同的,有的会返回被删除元素的下一个的iterator,有的则会返回删除元素的个数。
对于非结点类,如数组类的容器 vector,string,deque 容器标准写法是这样:

1
2
3
4
5
6
7
8
9
10
//vector<int> m_vector;
for(vector<int>::iterator iter = m_vector.begin(); iter != m_vector.end();)
{
if(需要删除)
{
iter=m_vector.erase(iter);
}
else
++iter;
}

数组型数据结构:该数据结构的元素是分配在连续的内存中,insert和erase操作,都会使得删除点和插入点之后的元素挪位置,所以,插入点和删除掉之后的迭代器全部失效,也就是说insert(iter)(或erase(iter)),然后在iter++,是没有意义的。解决方法:erase(*iter)的返回值是下一个有效迭代器的值。 iter =cont.erase(iter);

对于结点类容器(如:list,map,set)是这样:

1
2
3
4
5
6
7
8
9
10
//map<int,int> m_map;
for(map<int,int>::iterator iter = m_map.begin(); iter != m_map.end(); )
{
if(需要删除)
{
m_map.erase(iter++);
}
else
++iter;
}

链表型数据结构:对于list型的数据结构,使用了不连续分配的内存,删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.解决办法两种,erase(*iter)会返回下一个有效迭代器的值,或者erase(iter++).

树形数据结构: 使用红黑树来存储数据,插入不会使得任何迭代器失效;删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以采用erase(iter++)。

##友元
静态成员函数属于整个类所拥有,没有this指针
友员函数不是这个类的成员,没有this
类的非静态成员函数 有this

##复习static关键字

02/23/2017 指针的引用

http://www.cppblog.com/doing5552/archive/2010/09/28/127994.html
or
http://www.cnblogs.com/li-peng/p/4116349.html

// 例如: MYCLASS* p = new MYCLASS;
func1(p);
上面这段代码的这种处理方法想必谁都用过,创建一个MYCLASS对象,然后将它传入func1函数。现在假设此函数要修改pMyClass: void

1
2
3
4
func1(MYCLASS *pMyClass){
DoSomething(pMyClass);
pMyClass = // 其它对象的指针
}

第二条语句在函数过程中只修改了pMyClass的值。并没有修改调用者的变量p的值。如果p指向某个位于地址0x008a00的对象,当func1返回时,它仍然指向这个特定的对象。(除非func1有bug将堆弄乱了,完全有这种可能。)

现在假设你想要在func1中修改p的值。这是你的权利。调用者传入一个指针,然后函数给这个指针赋值。以往一般都是传双指针,即指针的指针,例如,CMyClass**。

1
2
3
4
5
6
7
MYCLASS* p = NULL;
func1(&p);
void func1(MYCLASS** pMyClass);{
*pMyClass = new MYCLASS;
……
}

调用func1之后,p指向新的对象。
如果你理解指针的指针,那么你肯定就理解指针引用,因为它们完全是一回事。如果你象下面这样声明函数:

1
2
3
4
void func1(MYCLASS *& pMyClass){
pMyClass = new MYCLASS;
……
}

其实,它和前面所讲得指针的指针例子是一码事,只是语法有所不同。传递的时候不用传p的地址&p,

02/25/2017
对于数组,如果要求一段的和,可以另外一个数组,然后累积求和

02/26/2017
c++的priority_queue只能用数组指针初始化?如果好像没办法像vector一样vector {1, 2}这样初始化。并且priority_queue不支持迭代器,只能用!pq.empty()来判断

x&(x-1)统计1的个数,x|(x+1)统计0的个数

02/27/2017
如果返回是int型,别直接开根号比较

刷题备注

发表于 2016-10-20

10/20/2016
tag: DP 95. Unique Binary Search Trees II; Unique Binary Search Trees I; 300. Longest Increasing Subsequence; Guess Number Higher or Lower II; Longest Increasing Subsequence; Ugly Number II

10/22/2016
tag: DP 264. Ugly Number II; 221. Maximal Square, House Robber II

10/23/2016
tag: DP 152. Maximum Product Subarray; 53. Maximum Subarray; 304. Range Sum Query 2D - Immutable

10/26/2016
tag: backtracking 93. Restore IP Addresses; Longest Palindromic Substring; 89. Gray Code; 79. Word Search(记得重做)

02/21/2017
163; *159; 158; 244; 245; 246; 247; 248; 249;

02/22/2017
250; 251; 254(错了); 255; 256; 265;270(错了);

02/23/2017
LintCode: binary search + copybook(hard)

12
Wei

Wei

update some solutions of Leetcode

16 日志
4 分类
10 标签
© 2017 Wei
由 Hexo 强力驱动
主题 - NexT.Mist