# coding=utf-8
import doctest
import collections
from timeit import timeit
from collections.abc import Iterable
# 操作一维数组中多余的数值(限制值为num)【适用短数组】
def array_limit_count_01(array, num): # 时间复杂度O(n ^ 2)
"""
根据限制值num ,对列表进行删除操作(每个值最多出现 num次)
>>> data =[1,2,3,1,2,1,2,3,4]
>>> array_limit_count_01(data, 2)
[1, 2, 3, 1, 2, 3, 4]
"""
ans = []
for i in array:
if ans.count(i) < num:
ans.append(i)
return ans
# 操作一维数组中多余的数值(限制值为num)【适用长数组】
def array_limit_count_02(array, num): # 使用哈希表的时间复杂度O(n)。
"""
根据限制值num ,对列表进行删除操作(每个值最多出现 num次)
>>> data =[1,2,3,1,2,1,2,3,4]
>>> array_limit_count_02(data, 2)
[1, 2, 3, 1, 2, 3, 4]
"""
result = []
counts = collections.defaultdict(int)
for i in array:
if counts[i] < num:
result.append(i)
counts[i] += 1
return result
# 把多维数组变成一维数组【适用短数组】
def array_flatten_01(input_arr, output_arr=None):
"""
把多维数组变成一维数组,返回一个列表
>>> data = [1, [1, ], 2, [5, ],[3, 4, [6, ], 6], 8, ]
>>> array_flatten_01(data)
[1, 1, 2, 5, 3, 4, 6, 6, 8]
"""
if output_arr is None:
output_arr = []
for ele in input_arr:
# 检查是否可迭代
if isinstance(ele, Iterable):
array_flatten_01(ele, output_arr)
else:
output_arr.append(ele)
return output_arr
# 把多维数组变成一维数组【适用长数组】
def array_flatten_02(iterable):
"""
把多维数组变成一维数组,返回一个迭代器
>>> data = [1, [1, ], 2, [5, ], [3, 4, [6, ], 6], 8, ]
>>> result = array_flatten_02(data)
>>> next(result)
1
>>> list(result)
[1, 2, 5, 3, 4, 6, 6, 8]
"""
for element in iterable:
# 检查是否可迭代
if isinstance(element, Iterable):
yield from array_flatten_02(element)
else:
yield element
# 类似打乱数组里的元素位置,再把打乱的数据恢复
def array_restore(initial_arr, final_arr):
"""
initial_arr:初始状态 final_arr:最终状态
把【initial_arr】变成【final_arr】
例子:车库的停车场(每个场地的编号)
把场地重新划分
>>> initial_arr = [1, 2, 3, 0, 4]
>>> final_arr = [0, 3, 2, 1, 4]
>>> array_restore(initial_arr, final_arr) # 结果为:恢复步骤次数和过程
(4, [[0, 3, 2, 1, 4], [0, 2, 3, 1, 4], [2, 0, 3, 1, 4], [2, 3, 0, 1, 4], [0, 3, 2, 1, 4]])
"""
initial = initial_arr[::] # 拷贝数据(id不一样)
seq = [] # 依次列出每个步骤
seq.append(initial)
steps = 0
while initial != final_arr:
zero = initial.index(0)
# 如果initial数组的0所在的下标 不等于 final数组的0所在的下标
if zero != final_arr.index(0): # 如果零不在应该的位置,
car_to_move = final_arr[zero]
pos = initial.index(car_to_move)
initial[zero], initial[pos] = initial[pos], initial[zero]
else:
for i in range(len(initial)):
# 如果值不相等就退出循环(根据下标对应的值)
if initial[i] != final_arr[i]:
initial[zero], initial[i] = initial[i], initial[zero]
break
seq.append(initial[::])
steps += 1
return steps, seq
# 对数组重新排序(改变值的位置)
def array_rearrange(int_arr, skip, index=0):
"""
根据skip 重组数组的位置
:param skip: 跳跃的步长
:param index: 存放索引的,不需要传入
>>> int_arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> result = array_rearrange(int_arr, 3)
>>> next(result)
3
>>> list(result)
[6, 9, 4, 8, 5, 2, 7, 1]
"""
skip = skip - 1 # 列表以0索引开头
len_list = (len(int_arr))
while len_list > 0:
index = (skip + index) % len_list
yield int_arr.pop(index)
len_list -= 1
# 在一维数组中找出限定值
def array_limit(arr, min_lim=None, max_lim=None):
"""
在一维数组中找出限定值
:param min_lim: 最小值
:param max_lim: 最大值
>>> array_limit([1,2,3,4,5], None, 3)
[1, 2, 3]
>>> array_limit([2, 5, 1, 2, 3, 4, 5], 2, 3)
[2, 2, 3]
"""
# 检验最小值的匿名函数
min_check = lambda val: True if min_lim is None else (min_lim <= val)
# 检验最大值的匿名函数
max_check = lambda val: True if max_lim is None else (val <= max_lim)
return [val for val in arr if min_check(val) and max_check(val)]
if __name__ == '__main__':
doctest.testmod( )
doctest.testfile("doc.txt")
"""
stmt = "array_limit([1,2,3,4,5], None, 3)"
setup = "from __main__ import array_limit"
cost_time = timeit(stmt, setup, number = 10000)
print(cost_time) # 0.020091733
stmt = "array_rearrange([1, 2, 3, 4, 5, 6, 7, 8, 9], 3)"
setup = "from __main__ import array_rearrange"
cost_time = timeit(stmt, setup, number = 10000)
print(cost_time) # 0.0033079469999999916
stmt = "array_restore([1, 2, 3, 0, 4], [0, 3, 2, 1, 4])"
setup = "from __main__ import array_restore"
cost_time = timeit(stmt, setup, number = 10000)
print(cost_time) # 0.041407573
stmt = "array_flatten_01([1, [1, ], 2, [5, ], [3, 4, [6, ], 6], 8, ])"
setup = "from __main__ import array_flatten_01"
cost_time = timeit(stmt, setup, number = 10000)
print(cost_time) # 0.07394432000000001
stmt = "array_flatten_02([1, [1, ], 2, [5, ], [3, 4, [6, ], 6], 8, ])"
setup = "from __main__ import array_flatten_02"
cost_time = timeit(stmt, setup, number = 10000)
print(cost_time) # 0.0046058670000000135
stmt = 'array_limit_count_01([1,2,3,1,2,1,2,3,4],2)'
setup = 'from __main__ import array_limit_count_01'
cost_time = timeit(stmt, setup, number = 10000)
print(cost_time) # 0.016674133999999993
stmt = 'array_limit_count_02([1,2,3,1,2,1,2,3,4],2)'
setup = 'from __main__ import array_limit_count_02'
cost_time = timeit(stmt, setup, number = 10000)
print(cost_time) # 0.027026773000000004【适用长数组】
"""
操作数组的基础算法
最新推荐文章于 2024-04-13 16:16:17 发布