Discover long patterns

前端 未结 6 1820
逝去的感伤
逝去的感伤 2021-01-30 02:20

Given a sorted list of numbers, I would like to find the longest subsequence where the differences between successive elements are geometrically increasing. So if the list is <

6条回答
  •  太阳男子
    2021-01-30 03:11

    Just to start with something, here is a simple solution in JavaScript:

    var input = [0.7, 1, 2, 3, 4, 7, 15, 27, 30, 31, 81], 
        output = [], indexes, values, i, index, value, i_max_length,
        i1, i2, i3, j1, j2, j3, difference12a, difference23a, difference12b, difference23b,
        scale_factor, common_ratio_a, common_ratio_b, common_ratio_c,
        error, EPSILON = 1e-9, common_ratio_is_integer,
        resultDiv = $("#result");
    
    for (i1 = 0; i1 < input.length - 2; ++i1) {
        for (i2 = i1 + 1; i2 < input.length - 1; ++i2) {
            scale_factor = difference12a = input[i2] - input[i1];
            for (i3 = i2 + 1; i3 < input.length; ++i3) {
                difference23a = input[i3] - input[i2];
                common_ratio_1a = difference23a / difference12a;
                common_ratio_2a = Math.round(common_ratio_1a);
                error = Math.abs((common_ratio_2a - common_ratio_1a) / common_ratio_1a);
                common_ratio_is_integer = error < EPSILON;
                if (common_ratio_2a > 1 && common_ratio_is_integer) {
                    indexes = [i1, i2, i3];
                    j1 = i2;
                    j2 = i3
                    difference12b = difference23a;
                    for (j3 = j2 + 1; j3 < input.length; ++j3) {
                        difference23b = input[j3] - input[j2];
                        common_ratio_1b = difference23b / difference12b;
                        common_ratio_2b = Math.round(common_ratio_1b);
                        error = Math.abs((common_ratio_2b - common_ratio_1b) / common_ratio_1b);
                        common_ratio_is_integer = error < EPSILON;
                        if (common_ratio_is_integer && common_ratio_2a === common_ratio_2b) {
                            indexes.push(j3);
                            j1 = j2;
                            j2 = j3
                            difference12b = difference23b;
                        }
                    }
                    values = [];
                    for (i = 0; i < indexes.length; ++i) {
                        index = indexes[i];
                        value = input[index];
                        values.push(value);
                    }
                    output.push(values);
                }
            }
        }
    }
    if (output !== []) {
        i_max_length = 0;
        for (i = 1; i < output.length; ++i) {
            if (output[i_max_length].length < output[i].length)
                i_max_length = i;
        }
        for (i = 0; i < output.length; ++i) {
            if (output[i_max_length].length == output[i].length)
                resultDiv.append("

    [" + output[i] + "]

    "); } }

    Output:

    [1, 3, 7, 15, 31]
    

    I find the first three items of every subsequence candidate, calculate the scale factor and the common ratio from them, and if the common ratio is integer, then I iterate over the remaining elements after the third one, and add those to the subsequence, which fit into the geometric progression defined by the first three items. As a last step, I select the sebsequence/s which has/have the largest length.

提交回复
热议问题