[英]What is the most efficient algorithm to find the midpoint of the index of a repeated sequence of numbers?
a=[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 -1, -1, -1, -1,-1, 0, 0, 0, 0, 0]
我希望能夠獲得重復點索引的中點,即
output_vector = [2, 8, 13, 19]
即output_vector [0]是第一序列的中點的索引0, 0, 0, 0, 0
output_vector [1]是中點的第二重復序列的1, 1, 1, 1, 1, 1, 1
output_vector [2]是第二個重復序列-1, -1, -1, -1,-1
中點
一種方法是使用itertools.groupby
查找組並計算其中點:
from itertools import groupby
a = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1,-1, 0, 0, 0, 0, 0]
groups = [list(g) for _, g in groupby(a)]
output_vector = [sum(1 for x in groups[:i] for _ in x) + len(x) // 2 for i, x in enumerate(groups)]
# [2, 8, 14, 19]
itertools
方法可能更好,更清潔。 盡管如此,這是一種使用math
和statistics
的方法,它會查找每組數字的起始索引和終止索引的中值。
import math
import statistics as stat
a = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0]
lastNum = None
startIdx = 0
midpts = []
for idx, x in enumerate(a):
if lastNum is not None and lastNum != x or idx == len(a) - 1:
midpts.append(math.floor(stat.median([startIdx, idx])))
startIdx = idx
lastNum = x
print(midpts)
# [2, 8, 14, 19]
另一個基於itertools的解決方案,但效率更高。
from itertools import groupby
a = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1,-1, 0, 0, 0, 0, 0]
output = []
psum = 0
for glen in (sum(1 for i in g) for k, g in groupby(a)):
output.append(psum + glen // 2)
psum += glen
print(output)
@Matt M答案的基於C ++的實現
template<typename T>
std::vector<size_t> getPeaks(std::vector<T>& input_vector) {
std::vector<size_t> output;
T lastNum = 10000;
size_t startIdx = 0;
for (size_t i = 0; i < input_vector.size(); ++i) {
if ((lastNum != 10000 and lastNum != input_vector[i]) || (i == input_vector.size() - 1)) {
auto medianIdx = findMedian(startIdx, i);
output.emplace_back(medianIdx);
startIdx = i;
}
lastNum = input_vector[i];
}
return output;
}
size_t findMedian(size_t start, size_t end) {
return start + (end - start) / 2;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.