要求:將連續數的數分成一組,不連續的分成另一組。如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...