粗粒度服务的执行时间统计算法实现及问题推广

3.1 算法一:逐一合并算法

3.1.1 算法描述

如图3.我们先将所有的时间片段按照起始时刻排序,后面的处理过程即依次判定相邻两个时间片段的三种关系,并将统计时间进行合并,合并的时间片段可以作为一个新的时间片段与后继的时间片段进行相关的计算。

图3.新的时间片段统计算法。

算法部分总共分两步,

一,将时间片段按开始时间进行排序,这里可以使用冒泡或快速排序算法。

二,1. 从第一个时间片段period 1开始,与后面的period 2 进行比较,取二者的并集,得到的新的period 2’。

2.重复上面的过程,直到最后一个时间片段并入最终的时间片段为止。

3.1.2 算法实现

为方便这里将时间都统一处理为long型,事实上,计算时间差也的确需要取date类型数据的long值再进行相关计算。

粗粒度服务的执行时间统计算法实现及问题推广粗粒度服务的执行时间统计算法实现及问题推广
package com.example.demo.mine.time_collect;

import java.util.*;import lombok.Data;import lombok.extern.slf4j.Slf4j;

/* * * @author lunyu * @since 2018-03-03 /@Slf4jpublic class StatisticTime {
</span><span>public</span> <span>static</span> <span>void</span><span> main(String[] args) {
    </span><span>//</span><span> 1.&#x4EA7;&#x751F;&#x968F;&#x673A;&#x6570;&#x636E;</span>
    <span>int</span> size = 10<span>;
    List</span><period> periods = <span>new</span> ArrayList<period><span>();

// long currentTime = System.currentTimeMillis();
//不失准确性,可以设当前时间是0
long currentTime = 0;
int range = 100;
int start;
int end;
int coi;
Random random
= new Random();
for (int i = 0; i < size; i++){
//区间膨胀系数
coi = random.nextInt(9)+1;
start
= random.nextInt(rangecoi);
end
= random.nextInt(range
coi) + start;
        Period period </span>= <span>new</span> Period(currentTime + start, currentTime +<span> end);
        log.info(</span>&quot;&#x65F6;&#x95F4;&#x7247;&#x6BB5;&#xFF1A;{}-{}&quot;<span>, period.getStartTime(), period.getEndTime());
        periods.add(period);

    }

    </span><span>//</span><span>2.&#x7B97;&#x6CD5;&#x6267;&#x884C;
    </span><span>//</span><span>2.1&#x5148;&#x5BF9;&#x5404;&#x4E2A;&#x65F6;&#x95F4;&#x6BB5;&#x6309;&#x5F00;&#x59CB;&#x65F6;&#x523B;&#x8FDB;&#x884C;&#x6392;&#x5E8F;</span>

sortPeriodsByStartTime(periods);

    </span><span>//</span><span>2.2&#x5BF9;&#x6570;&#x636E;&#x7EDF;&#x8BA1;</span>
    <span>long</span> totalSpendTime =<span> statisticTime(periods);
    log.info(</span>&quot;&#x603B;&#x7528;&#x65F6;&#xFF1A;{}&quot;<span>, totalSpendTime);
}

</span><span>/**</span><span>
 * &#x5BF9;&#x6392;&#x5E8F;&#x540E;&#x7684;&#x6570;&#x636E;&#x8FDB;&#x884C;&#x7EDF;&#x8BA1;
 * </span><span>@param</span><span> periods
 * </span><span>@return</span>
 <span>*/</span>
<span>private</span> <span>static</span> <span>long</span> statisticTime(List<period><span> periods) {
    </span><span>long</span> sum = periods.get(0).getEndTime() - periods.get(0<span>).getStartTime();
    </span><span>for</span>(<span>int</span> i = 0; i &lt; periods.size() - 1; i++<span>) {
        </span><span>//</span><span>1.&#x5982;&#x679C;(period i) &#x548C;(period i+1)&#x76F8;&#x4EA4;,&#x4F8B;&#xFF1A;
        </span><span>//</span><span> ------------
        </span><span>//</span><span>       ---------</span>
        <span>if</span> (periods.get(i).getEndTime() &gt; periods.get(i + 1<span>).getStartTime()
                </span>&amp;&amp; periods.get(i).getEndTime() &lt; periods.get(i + 1<span>).getEndTime()) {
            sum </span>+= periods.get(i + 1).getEndTime() -<span> periods.get(i).getEndTime();
            </span><span>//</span><span>2.&#x5982;&#x679C;(period i) &#x548C;(period i+1)&#x4E0D;&#x76F8;&#x4EA4;,&#x4F8B;&#xFF1A;
            </span><span>//</span><span>-----------
            </span><span>//</span><span>            ------</span>
        }<span>else</span> <span>if</span> (periods.get(i).getEndTime() <=>).getStartTime()) {
            sum += periods.get(i + 1).getEndTime() - periods.get(i + 1<span>).getStartTime();
            </span><span>//</span><span>3.&#x5982;&#x679C;(period i) &#x5305;&#x542B;(period i+1),&#x4F8B;&#xFF1A;
            </span><span>//</span><span>---------------
            </span><span>//</span><span> -----------</span>
        }<span>else</span> <span>if</span> (periods.get(i).getEndTime() &gt;= periods.get(i + 1<span>).getEndTime()) {
            </span><span>//</span><span>&#x8FD9;&#x65F6;&#x4EC0;&#x4E48;&#x90FD;&#x4E0D;&#x505A;&#xFF0C;&#x56E0;&#x4E3A;(period i) &#x6240;&#x5BF9;&#x5E94;&#x7684;&#x957F;&#x5EA6;&#x5373;&#x4E3A;(period i) &#x548C;(period i+1)&#x5E76;&#x96C6;&#x7684;&#x65F6;&#x95F4;&#x957F;&#x5EA6;&#x3002;
            </span><span>//</span><span>sum +=0;</span>

}
}
return sum;
}

</span><span>/**</span><span>
 * &#x5BF9;&#x65F6;&#x95F4;&#x6BB5;&#x6309;&#x5F00;&#x59CB;&#x65F6;&#x95F4;&#x8FDB;&#x884C;&#x987A;&#x5E8F;&#x6392;&#x5E8F;&#xFF0C;&#x7B80;&#x5355;&#x8D77;&#x89C1;&#xFF0C;&#x7528;&#x5192;&#x6CE1;&#x7B97;&#x6CD5;
 * </span><span>@param</span><span> periods
 </span><span>*/</span>
<span>private</span> <span>static</span> <span>void</span> sortPeriodsByStartTime(List<period><span> periods) {
    </span><span>//</span><span>&#x5192;&#x6CE1;&#x6CD5;&#xFF0C;&#x4ECE;&#x540E;&#x5411;&#x524D;&#x5192;&#x6CE1;</span>
    <span>for</span>(<span>int</span> i = periods.size() - 1; i &gt; 0; i--<span>) {
        </span><span>for</span>(<span>int</span> j = periods.size() - 2; j &gt;= 0; j--<span>) {

            </span><span>if</span> (periods.get(j).getStartTime() &gt; periods.get(j+1<span>).getStartTime()) {

                swap(periods, j, j</span>+1<span>);
            }
        }
    }
}

</span><span>/**</span><span>
 * &#x4EA4;&#x6362;&#x5BF9;&#x8C61;
 * </span><span>@param</span><span> periods
 * </span><span>@param</span><span> j
 * </span><span>@param</span><span> i
 * </span><span>@return</span>
 <span>*/</span>
<span>private</span> <span>static</span> <span>void</span> swap(List<period> periods, <span>int</span> j, <span>int</span><span> i) {
    Period tempPeriod </span>= <span>new</span> Period(0, 0<span>);
    tempPeriod </span>=<span> periods.get(j);
    periods.set(j, periods.get(i));
    periods.set(i, tempPeriod);
}

</span><span>/**</span><span>
 * &#x533A;&#x95F4;&#x5BF9;&#x8C61;
 * </span><span>@author</span><span> lunyu
 * </span><span>@since</span><span> 2018-03-03
 </span><span>*/</span><span>
@Data
</span><span>private</span> <span>static</span> <span>class</span><span> Period{

    </span><span>public</span> Period(<span>long</span> startTime, <span>long</span><span> endTime) {
        </span><span>super</span><span>();
        </span><span>this</span>.startTime =<span> startTime;
        </span><span>this</span>.endTime =<span> endTime;
    }

    </span><span>/**</span><span>
     * &#x5F00;&#x59CB;&#x65F6;&#x95F4;
     </span><span>*/</span>
    <span>private</span> <span>long</span><span> startTime;

    </span><span>/**</span><span>
     * &#x7ED3;&#x675F;&#x65F6;&#x95F4;
     </span><span>*/</span>
    <span>private</span> <span>long</span><span> endTime;

}

}

View Code

不难知道算法的空间复杂度为O(1),时间复杂度为O(n2) (排序冒泡算法复杂度:O(n2) + 时间片段并集计算复杂度:O(n))。

3.2 算法二:化整为零算法

3.2.1 算法描述

将每个时间片段的端点,都取出,并排序,我们就得到了n个细粒度服务分割的2n个时间点。

如图所示蓝色虚线与时间轴的交点表示每个时间端点,这些端点分割了时间从t1,t2一直持续到t2n。

将这些区间段分别与每个细粒度服务的时间片段进行比较,如果在某个细粒度服务的时间片段内,那么我们认为该时间段为执行时间。

粗粒度服务的执行时间统计算法实现及问题推广

图4.细粒度服务端点对时间的分割。

3.2.2 算法实现

粗粒度服务的执行时间统计算法实现及问题推广粗粒度服务的执行时间统计算法实现及问题推广
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/* * 化整为零的方式处理代码 * @author lunyu * @since 2018-03-03 /@Slf4jpublic class StatisticTimeByAll2Part {
</span><span>public</span> <span>static</span> <span>void</span><span> main(String[] args) {
    </span><span>//</span><span> 1.&#x4EA7;&#x751F;&#x968F;&#x673A;&#x6570;&#x636E;</span>
    <span>int</span> size = 10<span>;
    List</span><period> periods = <span>new</span> ArrayList<period><span>();

// long currentTime = System.currentTimeMillis();
//不失准确性,可以设当前时间是0
long currentTime = 0;
int range = 100;
int start;
int end;
int coi;
Random random
= new Random();
for (int i = 0; i < size; i++){
//区间膨胀系数
coi = random.nextInt(9)+1;
start
= random.nextInt(rangecoi);
end
= random.nextInt(range
coi) + start;
        Period period </span>= <span>new</span> Period(currentTime + start, currentTime +<span> end);
        log.info(</span>&quot;&#x65F6;&#x95F4;&#x7247;&#x6BB5;&#xFF1A;{}-{}&quot;<span>, period.getStartTime(), period.getEndTime());
        periods.add(period);

    }

    </span><span>//</span><span>2.&#x7B97;&#x6CD5;&#x6267;&#x884C;
    </span><span>//</span><span>2.1 &#x83B7;&#x53D6;&#x6240;&#x6709;&#x7684;&#x65F6;&#x95F4;&#x70B9;&#x96C6;&#x5408;</span>
    List<long> allTimePoints =<span> getAllTimePoints(periods);

    </span><span>//</span><span>2.2 &#x5BF9;&#x6240;&#x6709;&#x7684;&#x65F6;&#x95F4;&#x70B9;&#x96C6;&#x5408;&#x8FDB;&#x884C;&#x6392;&#x5E8F;</span>

sort(allTimePoints);

    </span><span>//</span><span>2.2&#x5BF9;&#x6570;&#x636E;&#x7EDF;&#x8BA1;</span>
    <span>long</span> totalSpendTime =<span> statisticTime(allTimePoints, periods);
    log.info(</span>&quot;&#x603B;&#x7528;&#x65F6;&#xFF1A;{}&quot;<span>, totalSpendTime);
}

</span><span>private</span> <span>static</span> <span>long</span> statisticTime(List<long> allTimePoints, List<period><span> periods) {
    </span><span>long</span> totolSpendTime = 0<span>;
    </span><span>for</span> (<span>int</span> i = 0; i &lt; allTimePoints.size() -1; i++<span>){
        </span><span>long</span> startTimePoint =<span> allTimePoints.get(i);
        </span><span>long</span> endTimePoint = allTimePoints.get(i + 1<span>);
        </span><span>//</span><span>&#x5BF9;&#x65F6;&#x95F4;&#x8FDB;&#x884C;&#x9A8C;&#x8BC1;</span>
        <span>for</span><span> (Period period : periods){
            </span><span>//</span><span>&#x5982;&#x679C;&#x67D0;&#x4E2A;&#xFF08;&#x7EC6;&#x7C92;&#x5EA6;&#xFF09;&#x65F6;&#x95F4;&#x7247;&#x6BB5;&#x5305;&#x542B;&#x8BE5;&#x5206;&#x5272;&#x7684;&#x65F6;&#x95F4;&#x7247;&#x6BB5;&#xFF0C;&#x5219;&#x8BA4;&#x4E3A;&#x5206;&#x5272;&#x7684;&#x65F6;&#x95F4;&#x7247;&#x6BB5;&#x6267;&#x884C;&#x65F6;&#x95F4;</span>
            <span>if</span> (startTimePoint &gt;=<span> period.getStartTime()
                    </span>&amp;&amp; endTimePoint <=<span> period.getEndTime()){
                totolSpendTime += (endTimePoint -<span> startTimePoint);
                </span><span>break</span><span>;
            }
        }
    }
    </span><span>return</span><span> totolSpendTime;
}

</span><span>/**</span><span>
 * &#x4E3A;&#x7B80;&#x5355;&#x8D77;&#x89C1;&#xFF0C;&#x7528;&#x5192;&#x6CE1;&#x6CD5;&#x5BF9;&#x65F6;&#x95F4;&#x70B9;&#x8FDB;&#x884C;&#x6392;&#x5E8F;
 </span><span>*/</span>
<span>private</span> <span>static</span> <span>void</span> sort(List<long><span> allTimePoints) {
    </span><span>//</span><span>&#x5192;&#x6CE1;&#x6CD5;&#xFF0C;&#x4ECE;&#x540E;&#x5411;&#x524D;&#x5192;&#x6CE1;</span>
    <span>for</span>(<span>int</span> i = allTimePoints.size() - 1; i &gt; 0; i--<span>) {
        </span><span>for</span>(<span>int</span> j = allTimePoints.size() - 2; j &gt;= 0; j--<span>) {

            </span><span>if</span> (allTimePoints.get(j) &gt; allTimePoints.get(j+1<span>)) {

                swap(allTimePoints, j, j</span>+1<span>);
            }
        }
    }
}

</span><span>/**</span><span>
 * &#x4EA4;&#x6362;&#x5BF9;&#x8C61;
 * </span><span>@param</span><span> allTimePoints
 * </span><span>@param</span><span> j
 * </span><span>@param</span><span> i
 * </span><span>@return</span>
 <span>*/</span>
<span>private</span> <span>static</span> <span>void</span> swap(List<long> allTimePoints, <span>int</span> j, <span>int</span><span> i) {

    </span><span>long</span> tempPeriod =<span> allTimePoints.get(j);
    allTimePoints.set(j, allTimePoints.get(i));
    allTimePoints.set(i, tempPeriod);
}

</span><span>/**</span><span>
 * &#x83B7;&#x5F97;&#x6240;&#x6709;&#x7684;&#x65F6;&#x95F4;&#x70B9;
 * </span><span>@param</span><span> periods
 * </span><span>@return</span>
 <span>*/</span>
<span>private</span> <span>static</span> List<long> getAllTimePoints(List<period><span> periods) {
    List</span><long> allTimePoints =<span> Lists.newArrayList();
    </span><span>for</span><span> (Period period : periods){
            allTimePoints.add(period.getStartTime());
            allTimePoints.add(period.getEndTime());
    }
    </span><span>return</span><span> allTimePoints;
}

</span><span>/**</span><span>
 * &#x533A;&#x95F4;&#x5BF9;&#x8C61;
 * </span><span>@author</span><span> lunyu
 * </span><span>@since</span><span> 2018-03-03
 </span><span>*/</span><span>
@Data
</span><span>private</span> <span>static</span> <span>class</span><span> Period{

    </span><span>public</span> Period(<span>long</span> startTime, <span>long</span><span> endTime) {
        </span><span>super</span><span>();
        </span><span>this</span>.startTime =<span> startTime;
        </span><span>this</span>.endTime =<span> endTime;
    }

    </span><span>/**</span><span>
     * &#x5F00;&#x59CB;&#x65F6;&#x95F4;
     </span><span>*/</span>
    <span>private</span> <span>long</span><span> startTime;

    </span><span>/**</span><span>
     * &#x7ED3;&#x675F;&#x65F6;&#x95F4;
     </span><span>*/</span>
    <span>private</span> <span>long</span><span> endTime;

}

}

View Code

不难知道,需要一个list用以保存2n各时间端点,因此,该算法的空间复杂度为2O(n)。对2n个时间端点进行排序,其时间复杂度为4O(n2),每个分割的时间段与细粒度服务的时间段比较,最多比较2n*n次,其时间复杂度为O(2n2),因此总的时间复杂度为4O(n2)。

四、问题的推广

4.1 二维覆盖的情况

4.1.1 问题分析

为简单起见,这里只考虑矩形覆盖的问题。

粗粒度服务的执行时间统计算法实现及问题推广

图4. 随机分布的矩形及其覆盖。

如图,左侧是一系列随机的矩形,这些矩形可能相交,也可能不相交,我们的目的是求这些矩形覆盖的面积(右侧)。

说说问题的复杂性,这个问题本来我想用一维时间段的方式拓展到二维来处理。发现,实际上行不通。因为,二维矩形图形之间的关系不能简单划归为两个矩形之间的关系。首先图形间的关系是一种偏序关系,即按照x轴的顺序是acb但是按照y轴的顺序是abc,如图5。

粗粒度服务的执行时间统计算法实现及问题推广

图5.三个矩形的某种分布。

这样就会造成如下问题:

  1. 当进行面积计算的时候,随着矩形块的增加,数据的计算会越来越复杂,也就是不能像之前一样排序之后,数据可以化归到更简单的二元形式。比如上图,把a和b矩形合并后,再与c进行面积运算的时候,必须要同时计算a-c,b-c的关系。
  2. 矩形不能随意的移动,比如a-c间的关系,两者的关系是固定的,不能随意移动。

由于上述问题的存在,目前能想到的解决方案即通过3.2算法二(化整为零算法)的方式来解决。

4.1.2 算法描述

算法如下:

  1. 统计所有的矩形组成的A集合中矩形的横坐标和纵坐标,并将横坐标和纵坐标进行排序。
  2. 依次取相邻的横坐标,相邻的纵坐标,相邻的横坐标和相邻的纵坐标这样可以组成一个个小的矩形集合B。
  3. 依次对矩形B集合中元素b与矩形A集合中a进行比较,如果矩形b包含于矩形a,则加上矩形b的面积,否则,跳过。

粗粒度服务的执行时间统计算法实现及问题推广

图6. 横坐标纵坐标对图形区域的分割和覆盖。

如图6,蓝色的线将矩形块,分割成一块块更小的矩形区块,求覆盖的区块所占的面积就可以对这些小区块分别判定求和。

4.1.3 算法实现

粗粒度服务的执行时间统计算法实现及问题推广粗粒度服务的执行时间统计算法实现及问题推广
import com.google.common.collect.Lists;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

/* * 面积统计 /@Slf4jpublic class AreaStatisticByAll2Part {
</span><span>public</span> <span>static</span> <span>void</span><span> main(String[] args) {
    </span><span>//</span><span> 1.&#x4EA7;&#x751F;&#x968F;&#x673A;&#x6570;&#x636E;</span>
    <span>int</span> size = 2<span>;

    </span><span>int</span> range = 100<span>;
    </span><span>int</span><span> xLeft;
    </span><span>int</span><span> xRight;
    </span><span>int</span><span> yLower;
    </span><span>int</span><span> yUpper;
    </span><span>int</span><span> coi;
    Random random </span>= <span>new</span><span> Random();
    List</span><rectangle> rectangleList =<span> Lists.newArrayList();
    </span><span>for</span> (<span>int</span> i = 0; i &lt; size; i++<span>){
        </span><span>//</span><span>&#x533A;&#x95F4;&#x81A8;&#x80C0;&#x7CFB;&#x6570;</span>
        coi = random.nextInt(9) + 1<span>;
        xLeft </span>= random.nextInt(range*<span>coi);
        xRight </span>= random.nextInt(range*coi) +<span> xLeft;

        coi </span>= random.nextInt(9) + 1<span>;
        yLower </span>= random.nextInt(range*<span>coi);
        yUpper </span>= random.nextInt(range*coi) +<span> yLower;

        Rectangle rectangle </span>= <span>new</span><span> Rectangle(xLeft, xRight, yLower, yUpper);
        log.info(rectangle.toString());
        rectangleList.add(rectangle);
    }

    </span><span>//</span><span>1.&#x5C06;&#x6A2A;&#x5750;&#x6807;&#x548C;&#x7EB5;&#x5750;&#x6807;&#x7684;&#x6570;&#x636E;&#x5206;&#x522B;&#x88C5;&#x8F7D;&#x5E76;&#x8FDB;&#x884C;&#x6392;&#x5E8F;</span>
    List<integer> xAxes =<span> getXAxes(rectangleList);
    List</span><integer> yAxes =<span> getYAxes(rectangleList);

    Collections.sort(xAxes);
    Collections.sort(yAxes);

    </span><span>//</span><span>2.&#x5BF9;&#x6570;&#x636E;&#x8FDB;&#x884C;&#x6BD4;&#x8F83;</span>
    BigDecimal areaSum =<span> compareAndGetAreaSum(xAxes, yAxes, rectangleList);

    log.info(</span>&quot;&#x603B;&#x9762;&#x79EF;:{}&quot;<span>, areaSum.toString());
}

</span><span>/**</span><span>
 * &#x6BD4;&#x8F83;&#x5E76;&#x83B7;&#x5F97;&#x9762;&#x79EF;
 </span><span>*/</span>
<span>private</span> <span>static</span> BigDecimal compareAndGetAreaSum(List<integer> xAxes, List<integer> yAxes, List<rectangle><span> rectangleList) {
    BigDecimal areaSum </span>=<span> BigDecimal.ZERO;
    </span><span>for</span> (<span>int</span> i = 0; i &lt; xAxes.size() -1; i++<span>){
        </span><span>int</span> xLeft =<span> xAxes.get(i);
        </span><span>int</span> xRight = xAxes.get(i + 1<span>);
        </span><span>for</span> (<span>int</span> j = 0; j &lt; yAxes.size() -1; j++<span>){
            </span><span>int</span> yLower =<span> yAxes.get(j);
            </span><span>int</span> yUpper = yAxes.get(j  + 1<span>);

            </span><span>for</span><span> (Rectangle rectangle : rectangleList){
                </span><span>if</span> (xLeft &gt;= rectangle.getXLeft() &amp;&amp; xRight <=<span> rectangle.getXRight()
                        &amp;&amp; yLower&gt;= rectangle.getYLower() &amp;&amp; yUpper <=<span> rectangle.getYUpper()){

                    areaSum = areaSum.add(BigDecimal.valueOf((xRight - xLeft) * (yUpper -<span> yLower)));
                    </span><span>break</span><span>;
                }
            }
        }
    }

    </span><span>return</span><span> areaSum;
}

</span><span>/**</span><span>
 * &#x83B7;&#x5F97;&#x6240;&#x6709;&#x7684;Y&#x8F74;&#x5750;&#x6807;&#x6570;&#x636E;
 </span><span>*/</span>
<span>private</span> <span>static</span> List<integer> getYAxes(List<rectangle><span> rectangleList) {
    List</span><integer> yAxes =<span> Lists.newArrayList();
    </span><span>for</span><span> (Rectangle rectangle : rectangleList){
        yAxes.add(rectangle.getYLower());
        yAxes.add(rectangle.getYUpper());
    }
    </span><span>return</span><span> yAxes;
}

</span><span>/**</span><span>
 * &#x83B7;&#x5F97;&#x6240;&#x6709;&#x7684;X&#x8F74;&#x5750;&#x6807;&#x6570;&#x636E;
 </span><span>*/</span>
<span>private</span> <span>static</span> List<integer> getXAxes(List<rectangle><span> rectangleList) {
    List</span><integer> xAxes =<span> Lists.newArrayList();
    </span><span>for</span><span> (Rectangle rectangle : rectangleList){
        xAxes.add(rectangle.getXLeft());
        xAxes.add(rectangle.getXRight());
    }
    </span><span>return</span><span> xAxes;
}

</span><span>/**</span><span>
 * &#x77E9;&#x5F62;&#x5B9E;&#x4F53;
 </span><span>*/</span><span>
@Data
@AllArgsConstructor
@Accessors(chain </span>= <span>true</span><span>)
</span><span>public</span> <span>static</span> <span>class</span><span> Rectangle {

    </span><span>private</span><span> Integer xLeft;

    </span><span>private</span><span> Integer xRight;

    </span><span>private</span><span> Integer yLower;

    </span><span>private</span><span> Integer yUpper;

}

}

View Code

不难知道,算法的空间复杂度是 4O(n)(用以存储横坐标和纵坐标的空间是2n+2n=4n个),时间复杂度是4O(n3)(排序的时间复杂度O(n2)(以冒泡算法为例) ,循环比较的次数为2n2nn=4n3次)。

4.2 三维及以上的情形

可以以此类推,将三维或更高纬度的空间分割成一个个小的空间,将这些空间一一与随机分布的立方体(或超体)进行比较,比较的结果并统计最终结果。不难知道,k维的情形,算法的空间复杂度是O(2kn),算法的时间复杂度是O(2(k-1)nk)。

Original: https://www.cnblogs.com/lunyu/p/10561220.html
Author: 论语
Title: 粗粒度服务的执行时间统计算法实现及问题推广

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/612568/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Redis进阶(一)

    通过简单的KV数据库理解Redis 分为访问模块,操作模块,索引模块,存储模块 底层数据结构 除了String类型,其他类型都是一个键对应一个集合,键值对的存储结构采用哈希表 哈希…

    数据库 2023年6月16日
    074
  • Linux巡检脚本

    #!/bin/bash sys:centos6.x/7.x [ $(id -u) -ne 0 ] && echo "&#x8BF7;&#x…

    数据库 2023年6月14日
    0101
  • 数据结构入门之单链表代码实现(java)

    1:单链表是: 单链表是一种链式存取的 数据结构 用一组地址任意的 存储单元 存放线性表中的数据元素。 链表中的数据是以结点来表示的,每个结点的构成:元素 ( 数据元素 的映象) …

    数据库 2023年6月6日
    091
  • SQL语句实战学习

    参考:https://zhuanlan.zhihu.com/p/38354000再次感谢作者的整理!! 1.数据已提前准备好了,已知有如下4张表:学生表:student 成绩表:s…

    数据库 2023年5月24日
    075
  • Git的常见命令

    Git 一、git环境安装 1.初始化本地仓库: git init 2.将本地仓库跟远程仓库建立连接:git remote add name path ​ git clone pa…

    数据库 2023年6月16日
    077
  • sarama Kafka客户端生产者与消费者梳理

    生产者 sarama 库提供了同步生产者和异步生产者。 SyncProducer 是在 AsyncProducer 基础上加以条件限制实现的。 type SyncProducer …

    数据库 2023年6月16日
    063
  • 注解

    注解概述 从 JDK5 开始,Java 增加对 &#x5143;&#x6570;&#x636E;的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解…

    数据库 2023年6月15日
    086
  • Fork/Join框架

    我们要使用ForkJoin框架,必须首先创建一个ForkJoin任务。它提供在任务中执行 fork()和 join() 操作的机制,通常情况下我们不需要直接继承ForkJoinTa…

    数据库 2023年6月14日
    070
  • 基础算法知识

    一、冒泡排序 冒泡排序其实跟握手定理差不多(即A,B,C三人需每两个都都要握手一次 AB,AC,BC) 时间复杂度比较差的O(n²) int[] arrays = {2, 1, 5…

    数据库 2023年6月6日
    0109
  • PDF转换OFD(Java实用版)

    前言: 在项目中用到了,就写一下哈 OFD简介 百度百科:https://baike.baidu.com/item/OFD/56227163?fr=aladdin OFD(Open…

    数据库 2023年6月16日
    0117
  • MySQL变量、流程控制和游标

    变量、流程控制和游标 变量 在MySQL数据库的存储过程和函数中,可以使用变量来存储查询或计算的中间结果数据,或者输出最终的结果的数据 系统变量 变量由系统定义,属于服务器级别 […

    数据库 2023年5月24日
    060
  • MySQL 回表

    MySQL 回表 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。 一、简述 回表,顾名思义就是回到表中,也就是先通过普通索引扫描出数据所在的行,再通过行主键ID 取出索引中未包含…

    数据库 2023年5月24日
    079
  • Redis缓存雪崩、缓存穿透、缓存击穿

    缓存雪崩 Redis中的缓存数据是有过期时间的,当在同一时间大量的缓存同时失效时就会造成缓存雪崩。解决方案1、设置Redis中的key永不过期,缺点是会占用很多内存2、使用Redi…

    数据库 2023年6月14日
    080
  • Asp.NET core/net 5接口返回实体含有long/int64的属性序列后最后几位变为0的解决

    Asp.NET core /net 5接口返回实体含有long/int64的属性时,序列后最后几位变为0的。 不得不吐槽一下MS,这种事还有问题,NND。 解决方案在startup…

    数据库 2023年6月14日
    072
  • Java学习-第一部分-第三阶段-第二节:反射

    反射 笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 一个需求引出反射 请看下面的问题 根据配置文件 re.pr…

    数据库 2023年6月11日
    060
  • 02-MySQL关键字、Select语句执行顺序

    SQL关键字 1、分页 MySQL的分页关键词是 limit SELECT * FROM student LIMIT 2,6:查询学生表中的数据,从第三条开始,显示6条数据 2、分…

    数据库 2023年6月16日
    092
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球