kotlin - Finding the most common interval in a list of doubles - Stack Overflow

I am currently stuck on evaluating a list of some Doubles representing time intervals. Let's say I

I am currently stuck on evaluating a list of some Doubles representing time intervals. Let's say I have an unordered list of up to 100 values fluctuating around 1: [0.897, 0.912, ... 1.214, 0.981]

I am now trying to find the interval of 0.05s that includes the most values in my list (say 20 of a list with 100 values).
Below is what I came up on my own and although it seems to work on my dummy data, this approach (looping the entire list for every interval) appears really redundant to me, especially if I were to evaluate much larger lists.

I am interested if someone could advice a more elegant way, perhaps using plotting of some sort? ´´´

    var lowerEnd = 0.5
    var higherEnd = 1.5
    var numberOfElements = 0
    var currentMost = 0
    var mostCommonRange = 0.0

    while(lowerEnd < higherEnd) {
        records.forEach { entry ->
            if(lowerEnd <= entry && entry < (lowerEnd + 0.05)) {
                numberOfElements += 1
            }              
        }
        if(numberOfElements > currentMost) {
            currentMost = numberOfElements
            mostCommonRange = lowerEnd
        }
        numberOfElements = 0
        lowerEnd += .05
    }

´´´

I am currently stuck on evaluating a list of some Doubles representing time intervals. Let's say I have an unordered list of up to 100 values fluctuating around 1: [0.897, 0.912, ... 1.214, 0.981]

I am now trying to find the interval of 0.05s that includes the most values in my list (say 20 of a list with 100 values).
Below is what I came up on my own and although it seems to work on my dummy data, this approach (looping the entire list for every interval) appears really redundant to me, especially if I were to evaluate much larger lists.

I am interested if someone could advice a more elegant way, perhaps using plotting of some sort? ´´´

    var lowerEnd = 0.5
    var higherEnd = 1.5
    var numberOfElements = 0
    var currentMost = 0
    var mostCommonRange = 0.0

    while(lowerEnd < higherEnd) {
        records.forEach { entry ->
            if(lowerEnd <= entry && entry < (lowerEnd + 0.05)) {
                numberOfElements += 1
            }              
        }
        if(numberOfElements > currentMost) {
            currentMost = numberOfElements
            mostCommonRange = lowerEnd
        }
        numberOfElements = 0
        lowerEnd += .05
    }

´´´

Share Improve this question asked Mar 27 at 1:57 AlexAlex 711 silver badge9 bronze badges 2
  • 2 Are you only trying to chose between intervals that start every 0.05 then? Ie [0.5, 0.55], [0.55, 0.6],... Presumably [0.56, 0.61] is not a valid answer? – Simon Jacobs Commented Mar 27 at 2:22
  • Yes you're right. I wasn't specific in my question. – Alex Commented Mar 27 at 12:20
Add a comment  | 

1 Answer 1

Reset to default 3

Since you only consider ranges that start and end at multiples of 0.05 (and not e.g. 0.01 ~ 0.06), just doing (x / 0.05).toInt() will tell you which range a number x is in.

So you just group by (x / 0.05).toInt(), and count how many items are in each group, then find the biggest group.

fun rangeLowerBound(list: List<Double>) =
    list.groupingBy { (it / 0.05).toInt() }.eachCount().maxBy { it.value }.key * 0.05

rangeLowerBound(listOf(-0.1, -0.11, -0.13, 0.1, 0.11, 0.12, 0.13)) will return 0.1, meaning that the range 0.1 ~ 0.15 contains the most numbers out of all the other ranges.

Note that this assumes the list is non-empty. If the list can be empty, you can use .maxByOrNull { it.value }?.key?.times(0.05) and return that (which would be null if the list is empty), or provide a default value with ?:.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744116852a4559215.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信