Java 連續數 二分法 分組

2021-06-17 01:06:47 字數 3396 閱讀 4123

要求:將連續數的數分成一組,不連續的分成另一組。如1、2、3、5、7、8,輸出1-3、5-5、7-8。

方法一、不推薦

bean物件儲存分組的最大值和最小值。並提供將某數增加到該分組的方法。**如下:

public class bean

if (value == minvalue - 1)

if (value == maxvalue + 1)

// 其他情況都增加該區間失敗

return false;

} public int getminvalue()

public void setminvalue(int minvalue)

public int getmaxvalue()

public void setmaxvalue(int maxvalue)

}

beanlist類為list集合的簡單封裝。對外也提供將數字加入到某分組的方法,由於加入某個數字,可能會將兩個分組合併成乙個分組,如原來1-3和5-6組,加入4後,必須合併為1-6組,如下方法實現邏輯:如果某乙個數字加入兩個分組成功,則這兩個分組可以合併。

public class beanlist

existbean = bean;

}} if (existbean == null)

}private void addifnotexist(int value)

private void merge(bean existbean, bean deletebean)

else if (existbean.getminvalue() == deletebean.getmaxvalue())

}public void print() }

}

測試類。beanlist只是簡單將結果列印出來。

public class test

beanlist.print();

}}

效能測試:

public static void main(string args)

long endtime = system.currenttimemillis();

system.out.println("count time [" + (endtime - starttime) + "] ms");

system.out.println("bean list size [" + beanlist.getbeanlist().size() + "]");

結果:

count time [73203] ms 

beanlist size [23094]

十萬條資料,在十萬內產生隨機數,從結果來看引數了2.3w個區間,但是耗時為73秒。這個是相當慢的。

方法二:二分法

同樣bean

public class bean implements comparable

if (other.start > this.end + 1)

return 0;

}public void merge(bean other)

public long getstart()

public void setstart(long start)

public long getend()

public void setend(long end)

@override

public string tostring()

}

邏輯處理類beansearch。beansearch類同樣也是list集合的簡單封裝。但是對外提供二個方法,乙個是將區間增加到集合中,第二個方式用於將已經加入的集合的區間合併。因為加入乙個資料到區間後馬上合併是乙個相當耗時的操作,很有必要提取出來。

public class beansearch

public void add(long value)

public void add(bean bean)

else

}public void merge()}}

public listgetbeanlist()

private void binsearch(bean bean)

int lower = 0;

while (true)

current = (lower + upper) / 2;

searchedbean = beanlist.get(current);

int result = searchedbean.compareto(bean);

if (result == 0)

else if (result < 0)

else if (result > 0)}}

private void addifnoexist(bean bean)

while (true)

else if (beanlist.get(current + 1).compareto(bean) > 0)

}else if (result > 0)

// 當前索引bean比引數bean大,則左移動乙個進行比較

current--;

}else}}

}

效能測試:

@test

public void testadd()

search.merge();

long endtime = system.currenttimemillis();

system.out.println("coust time [" + (endtime - starttime) + "] ms");

system.out.println("beanlist size[" + search.getbeanlist().size() + "]");

}

結果:

coust time [29094] ms

beanlistsize[232698]

100w資料,在100w內產生隨機數,共有23.2w個區間,但是耗時29秒。

在這兩個方法中,都用相同的處理步驟,那就是根據當前區間查詢可以融合的區間。在方法一種,依次對集合迴圈,那麼10w條資料最壞的情況需要比較10w次,而其中很多都是多餘的比較。這就是二分法的優點。

舉個例子:1-100之間你猜乙個數字,你猜中正確數字的次數。方法一是從1開始,依次猜,那麼最差的情況需要猜100次,這是笨拙的。而方法二是第一次猜50,如果猜小了,那下次猜75,再次猜小了,那下次就猜83,最多7次可以猜到答案。這就是二分法的精髓所在,當然二分法要求資料是有序的,無序是沒有意義的。在方法二中,將不存在的區間新增(addifnotexist)就是有序新增。

Java 二分法查詢

這學期學了資料結構這門課,這會都期末了才想起來更新部落格,所以我就來了,話不多說。如下 package com.vgbh public class binarysearch 二分法查詢必須是已經排序好的數列,且必須為正序,才可進行查詢 首先,假設表中元素是按公升序排列,將表中間位置記錄的關鍵字與查詢...

Java二分法查詢

前提 必須是有序的資料。基本思想 把乙個有序的資料乙份為二。然後判斷是比目標資料大了還是小了,如果小了往左邊的部分找 如果大了往右邊的資料找。確定了找的方向後再次把資料一分為二,繼續上面的步驟直到找到為止。涉及到了遞迴的思想。通俗的講 每次減少一半,然後確定方向,再次減少一半,直到找到為止。1 傳入...

二分法查詢 Java

原理 基本思想 假設資料是按公升序排序的,對於給定值x,從序列的中間位置開始比較,如果當前位置值等於x,則查詢成功 若x小於當前位置值,則在數列的前半段中查詢 若x大於當前位置值則在數列的後半段中繼續查詢,直到找到為止。演算法 假如有一組數為3,12,24,36,55,68,75,88要查給定的值2...