Skip to content

Commit 812741c

Browse files
committed
update stack & add row
1 parent 216cd17 commit 812741c

36 files changed

+2361
-5
lines changed

Recursion/readme.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
- 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成`栈溢出`等,所以一般不提倡用递归算法设计程序。
2828

2929
表现在 `Python` 语言中,即为报错信息`RecursionError: maximum recursion depth exceeded in comparison.`
30-
默认递归深度为 1000 ,我们可以通过修改下面的代码设置调节,但是通常不建议这样操作。(效率太低)
30+
默认递归深度为 1000 ,我们可以通过修改下面的代码设置调节,但是**通常不建议这样操作**。(效率太低)
3131
```python
3232
import sys
3333
sys.setrecursionlimit(100000)
@@ -62,7 +62,7 @@ def look_for_key_with_recursion(big_box):
6262

6363
# **尾递归**
6464

65-
在函数返回的时候,调用自身本身,并且,return语句不能包含表达式
65+
在函数返回的时候,调用自身本身,并且,`return`语句不能包含表达式
6666

6767
```python
6868
def bar():
@@ -73,7 +73,8 @@ def foo():
7373
```
7474
上面代码中,函数`foo()`的最后一步是调用函数`bar()`,这就叫尾调用。
7575
具体实现见[代码](./recursion.py)中的`tail_recursion_fact()`函数。
76-
`Python`解释器也没有做优化,所以,即使把上面的`factorial(n)`函数改成尾递归方式的`tail_recursion_fact()`,也会导致栈溢出。
76+
77+
`Python`解释器没有做优化,所以,即使把上面的`factorial(n)`函数改成尾递归方式的`tail_recursion_fact()`,也会导致栈溢出。
7778

7879
通过特殊的装饰器,我们也可以实现[Python开启尾递归优化](https://segmentfault.com/a/1190000007641519),详见代码中的`tail_call_optimized()`函数。
7980

Stack/linked_stack.py

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
# Created by imoyao at 2019/9/17 15:58
4+
5+
"""
6+
基于链表实现的栈
7+
"""
8+
9+
10+
class Node:
11+
12+
def __init__(self, data, next=None):
13+
self.data = data
14+
self._next = next
15+
16+
17+
class LinkedStack:
18+
"""A stack based upon singly-linked list.
19+
"""
20+
21+
def __init__(self):
22+
self._top = None
23+
self._size = 0
24+
25+
def __repr__(self):
26+
current = self._top
27+
nums = []
28+
while current:
29+
nums.append(current.data)
30+
current = current._next
31+
ret = ','.join([str(num) for num in nums])
32+
return f'[{ret}]'
33+
34+
def is_empty(self):
35+
return self._size == 0
36+
37+
def size(self):
38+
return self._size
39+
40+
def push(self, item):
41+
new_top = Node(item)
42+
new_top._next = self._top
43+
self._top = new_top
44+
self._size += 1
45+
46+
def pop(self):
47+
if not self._size:
48+
print('Stack Overflow')
49+
else:
50+
item = self._top.data
51+
self._top = self._top._next
52+
return item
53+
54+
def top(self):
55+
if not self._size:
56+
print('Stack Overflow.')
57+
else:
58+
return self._top.data
59+
60+
61+
s = LinkedStack()
62+
print(s.is_empty())
63+
s.push(4)
64+
print(s)
65+
s.push('dog')
66+
print(s)
67+
# print(s.peek())
68+
s.push(True)
69+
print(s)
70+
print(s.size())
71+
print(s.is_empty())
72+
print(s)
73+
74+
# class LinkedStack:
75+
# """
76+
# 基于单链表的栈实现
77+
# """
78+
#
79+
# def __init__(self):
80+
# self._top = None
81+
# self._num = 0
82+
#
83+
# def is_empty(self):
84+
# return self._num == 0
85+
#
86+
# def size(self):
87+
# return self._num
88+
#
89+
# # def __repr__(self):
90+
# # current = self._top
91+
# # nums = []
92+
# # while current:
93+
# # nums.append(current._data)
94+
# # current = current._next
95+
# # return ' '.join(f'{num}' for num in nums)
96+
#
97+
# def push(self, value):
98+
# new_top = Node(value)
99+
# new_top._next = self._top
100+
# self._top = new_top
101+
# self._num += 1
102+
#
103+
# def pop(self):
104+
# if not self._num:
105+
# print('The length of stack is 0.')
106+
# else:
107+
# item = self._top._data
108+
# self._top = self._top.next
109+
# return item
110+
#
111+
#
112+
# if __name__ == '__main__':
113+
# s = LinkedStack()
114+
# print(s.is_empty())
115+
# s.push(4)
116+
# print(s)
117+
# s.push('dog')
118+
# print(s)
119+
# # print(s.peek())
120+
# s.push(True)
121+
# print(s)
122+
# print(s.size())
123+
# print(s.is_empty())
124+
# print(s)
File renamed without changes.

Stack/readme.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
- 弹夹(先压入的最后射出)
88
- 摞在一起的餐碟
99

10-
![羽毛球杯](./img/stack-example.jpg)
10+
![羽毛球杯](./img/stack-example.jpg)
11+
1112
(我们假设杯子只有顶端可以放入和取出)
1213

1314
## 操作
@@ -31,7 +32,7 @@
3132
| s.size() | [4,'dog'] | 2 | |
3233

3334
## 代码实现
34-
[stack](stack.py)
35+
[基于list实现stack](list_stack.py)
3536

3637
## 其他
3738
常与另一种有序的线性数据`队列`相提并论。

raw/datastructre/__init__.py

Whitespace-only changes.
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
class Bag(object):
2+
def __init__(self,n,capacity,weights,values):
3+
self.capacity = capacity
4+
self.weights = weights
5+
self.values = values
6+
self.n = n
7+
8+
9+
10+
def get_max_value(self):
11+
sum_v = [[0 for i in range(self.capacity+1)] for j in range(self.n+1)]
12+
13+
for i in range(1,self.n+1):
14+
for j in range(1,self.capacity+1):
15+
# sum_v[i][0]=0
16+
# sum_v[0][j]=0
17+
sum_v[i][j] = sum_v[i - 1][j]
18+
if j-self.weights[i-1]>=0 : ##这里是i-1,因为weights数组是从0开始的
19+
# 这个判断是背包总容量够放当前物体
20+
sum_v[i][j] = max(sum_v[i-1][j-self.weights[i-1]]+self.values[i-1], sum_v[i-1][j])
21+
self.print_matrix(sum_v)
22+
return sum_v[self.n-1][self.n-1]
23+
24+
def print_matrix(self,matrix):
25+
for i in range(len(matrix)):
26+
for j in range(len(matrix[0])):
27+
print(matrix[i][j],end=" ")
28+
print()
29+
30+
def bag(n, c, w, v):
31+
"""
32+
测试数据:
33+
n = 6 物品的数量,
34+
c = 10 书包能承受的重量,
35+
w = [2, 2, 3, 1, 5, 2] 每个物品的重量,
36+
v = [2, 3, 1, 5, 4, 3] 每个物品的价值
37+
"""
38+
# 置零,表示初始状态
39+
value = [[0 for j in range(c + 1)] for i in range(n + 1)]
40+
for i in range(1, n + 1):
41+
for j in range(1, c + 1):
42+
value[i][j] = value[i - 1][j]
43+
# 背包总容量够放当前物体,遍历前一个状态考虑是否置换
44+
if j >= w[i - 1] and value[i][j] < value[i - 1][j - w[i - 1]] + v[i - 1]:
45+
value[i][j] = value[i - 1][j - w[i - 1]] + v[i - 1]
46+
for x in value:
47+
print(x)
48+
return value
49+
50+
51+
if __name__ == '__main__':
52+
num = 5
53+
capacity = 10
54+
weight_list = [2, 2, 6, 5, 4]
55+
value_list = [6, 3, 5, 4, 6]
56+
q = Bag(num, capacity, weight_list, value_list)
57+
q.get_max_value()
58+
bag(num,capacity,weight_list,value_list)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
bestV = 0
2+
ans = []
3+
wi = []
4+
vi = []
5+
w = 0
6+
n = 0
7+
8+
9+
def bag(n_, w_, vi_, wi_):
10+
global bestV, wi, vi, w, n
11+
wi = wi_
12+
vi = vi_
13+
w = w_
14+
n = n_
15+
backtrace(0, 0, 0,[])
16+
17+
18+
19+
def backtrace(i, sum_v, sum_w, result):
20+
global bestV,ans
21+
if i >= n:
22+
if bestV<sum_v:
23+
bestV = sum_v
24+
print(result)
25+
ans = result
26+
return
27+
if wi[i] + sum_w > w:
28+
backtrace(i+1,sum_v,sum_w,result)
29+
else:
30+
result.append(i)
31+
backtrace(i + 1, sum_v+vi[i], sum_w+wi[i], result.copy())
32+
result.pop()
33+
backtrace(i+1,sum_v,sum_w,result)
34+
35+
if __name__ == '__main__':
36+
num = 5
37+
capacity = 10
38+
weight_list = [2, 2, 6, 5, 4]
39+
value_list = [6, 3, 5, 4, 6]
40+
bag(num, capacity, value_list,weight_list)
41+
print(ans)
42+
print(bestV)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
def gen_power_set(L):
2+
power_set = []
3+
for i in range(2**len(L)):
4+
bin_str = get_binary_rep(i, len(L))
5+
6+
sub_set = []
7+
for j in range(len(L)):
8+
if bin_str[j] == '1':
9+
sub_set.append(L[j])
10+
power_set.append(sub_set)
11+
12+
return power_set
13+
14+
# 物品转化为二进制表示
15+
16+
## 我们可以把输入集合当做一个元素的列表,任意一个子集合看成是一个只包含了0,1的字符串,0表示不包含指定元素,1表示包含指定元素,那么全0就表示空集,全1就表示包括所有元素的集合(输入集合)。因此0–2727所有的数的2进制就代表了输入集合的所有子集,也就是找到了问题的全部子空间。
17+
def get_binary_rep(n, num_digital):
18+
result = ''
19+
while n > 0:
20+
result = str(n % 2) + result
21+
n = n // 2
22+
23+
if len(result) > num_digital:
24+
raise ValueError("not enough digits")
25+
26+
for i in range(num_digital - len(result)):
27+
result = '0' + result
28+
29+
return result
30+
31+
if __name__ == '__main__':
32+
print( gen_power_set(['a','b','c']))

raw/datastructre/algorithm_method/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#
2+
# void backtrack(int t) //t表示递归深度,即当前扩展节点在解空间树的深度
3+
# {
4+
# if ( t > n ) output(x); //n控制递归深度,如果算法已经搜索到叶节点,记录输出可行解X
5+
# else
6+
# {
7+
# for(int i = f(n,t) ; i <= g(n,t) ; i++) //在深度t,i从未搜索过得起始编号到终止编号
8+
# {
9+
# x[t] = h(i); //查看i这个点的值是否满足题目的要求
10+
# if( constraint(t) && bound(t))
11+
# backtrack(t+1)
12+
# //constraint(t)为true表示在当前扩展节点处x[1:t]的取值满足问题的约束条件;
13+
# //bound(t)为true表示当前扩展节点取值没有使目标函数越界;
14+
# //为true表示还需要进一步的搜索子树,否则减去子树。
15+
# }
16+
# }
17+
# }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
3+
#
4+
# count = 1
5+
#
6+
# def queen(A, cur=0):
7+
# global count
8+
# if cur == len(A):
9+
# print("-----------",count,"---------")
10+
#
11+
# print(A)
12+
# print()
13+
# count +=1
14+
# return
15+
# for col in range(len(A)):
16+
# A[cur], flag = col, True
17+
# for row in range(cur):
18+
# if A[row] == col or abs(col - A[row]) == cur - row:
19+
# flag = False
20+
# break
21+
# if flag:
22+
# queen(A, cur+1)
23+
24+
def check(board,row,col):
25+
i = 0
26+
while i < row:
27+
if abs(col-board[i]) in (0,abs(row-i)):
28+
return False
29+
i += 1
30+
return True
31+
32+
def EightQueen(board,row):
33+
blen = len(board)
34+
if row == blen: # 来到不存在的第九行了
35+
printBoard(board)
36+
return True
37+
col = 0
38+
while col < blen:
39+
if check(board,row,col):
40+
board[row] = col
41+
if EightQueen(board,row+1):
42+
return True
43+
col += 1
44+
return False
45+
46+
def printBoard(board):
47+
'''为了更友好地展示结果 方便观察'''
48+
import sys
49+
for i,col in enumerate(board):
50+
sys.stdout.write('□ ' * col + '■ ' + '□ ' * (len(board) - 1 - col))
51+
print()
52+
53+
if __name__ == '__main__':
54+
55+
# queen([None]*8)
56+
EightQueen([-1]*8,8)

0 commit comments

Comments
 (0)