簡體   English   中英

找到重復數字序列的索引中點的最有效算法是什么?

[英]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方法可能更好,更清潔。 盡管如此,這是一種使用mathstatistics的方法,它會查找每組數字的起始索引和終止索引的中值。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM