2013-03-24 25 views
7

Sıralanmış bir nesne listesi var ve bir nesnenin ilk oluşumunu ve son oluşumunu bulmak istiyorum. C++ 'da, std :: equal_range (veya sadece bir lower_bound ve bir upper_bound) dosyasını kolayca kullanabilirim. ÖrneğinJava eşdeğeri C++ equal_range (veya lower_bound & upper_bound)

: Java'da

bool mygreater (int i,int j) { return (i>j); } 

int main() { 
    int myints[] = {10,20,30,30,20,10,10,20}; 
    std::vector<int> v(myints,myints+8);       // 10 20 30 30 20 10 10 20 
    std::pair<std::vector<int>::iterator,std::vector<int>::iterator> bounds; 

    // using default comparison: 
    std::sort (v.begin(), v.end());        // 10 10 10 20 20 20 30 30 
    bounds=std::equal_range (v.begin(), v.end(), 20);   //  ^ ^

    // using "mygreater" as comp: 
    std::sort (v.begin(), v.end(), mygreater);     // 30 30 20 20 20 10 10 10 
    bounds=std::equal_range (v.begin(), v.end(), 20, mygreater); //  ^ ^

    std::cout << "bounds at positions " << (bounds.first - v.begin()); 
    std::cout << " and " << (bounds.second - v.begin()) << '\n'; 

    return 0; 
} 

, basit denklik var gibi görünüyor? Nasıl, bir standart ithalat java.util.List kullanıyorum arada

List<MyClass> myList; 

eşit aralığı ile yapmalıdır;

+0

"C" bilmeyenler için, İngilizce'de ne istediğinizi örneklerle tarif edebilir misiniz? – Bohemian

cevap

3

Java'da, sıralı listenin eşit aralığının alt sınırını bulmak için Collections.binarySearch'u kullanırsınız (Arrays.binarySearch diziler için benzer bir özellik sağlar). Ardından, eşit aralığın sonuna gelene kadar doğrusal olarak yinelemeye devam edersiniz.

Bu yöntemler, Comparable arabirimini uygulayan yöntemler için çalışır. Comparable uygulamamayan sınıflar için, özel türünüzün öğelerini karşılaştırmak üzere özelComparator örneğini sağlayabilirsiniz.

+0

Teşekkürler ama Listem bununla uyumlu değil mi? Koleksiyonlar türündeki ikili Arama (argümanları için geçerli değil) (argümanları için geçerli değildir. (Liste , Tarih, Karşılaştırıcı ) – Gob00st

+0

Karşılaştırıcıyı Türetilmiş sınıf MyDerivedData'ya taşımaya çalıştım ancak hala bu problemi yaşıyorum. Listem sadece Listem listesi olarak tanımlanmıştır; Burada bir problem mi var? çok teşekkürler. – Gob00st

+0

@ Gob00st Cevabın güncellemesine bir göz atın. – dasblinkenlight

0

Böyle bir şey deneyebilirsiniz: ilk geçtiği ve bulmak için o zaman sırayla sol onun ikili arama yaparak tutabilir

public class TestSOF { 

     private ArrayList <Integer> testList = new ArrayList <Integer>(); 
     private Integer first, last; 

     public void fillArray(){ 

      testList.add(10); 
      testList.add(20); 
      testList.add(30); 
      testList.add(30); 
      testList.add(20); 
      testList.add(10); 
      testList.add(10); 
      testList.add(20); 
     } 

     public ArrayList getArray(){ 

      return this.testList; 
     } 

     public void sortArray(){ 

      Collections.sort(testList); 
     } 

     public void checkPosition(int element){ 

      if (testList.contains(element)){ 

       first = testList.indexOf(element); 
       last = testList.lastIndexOf(element); 

       System.out.println("The element " + element + "has it's first appeareance on position " 
      + first + "and it's last on position " + last); 
      } 

      else{ 

       System.out.println("Your element " + element + " is not into the arraylist!"); 
      } 
     } 

     public static void main (String [] args){ 

      TestSOF testSOF = new TestSOF(); 

      testSOF.fillArray(); 
      testSOF.sortArray(); 
      testSOF.checkPosition(20); 
     } 

} ikili aramada

+0

Özelleştirilmiş karşılaştırıcıyı kullanmam gerekiyor ... – Gob00st

0

, sen elemanı bulmak son elemanı bulmak için sağa.

/* 
B: element to find first or last occurrence of 
searchFirst: true to find first occurrence, false to find last 
*/ 
Integer bound(final List<Integer> A,int B,boolean searchFirst){ 
    int n = A.size(); 
    int low = 0; 
    int high = n-1; 
    int res = -1; //if element not found 
    int mid ; 
    while(low<=high){ 
     mid = low+(high-low)/2; 
     if(A.get(mid)==B){ 
      res=mid; 
      if(searchFirst){high=mid-1;} //to find first , go left 
      else{low=mid+1;}    // to find last, go right 
     } 
     else if(B>A.get(mid)){low=mid+1;} 
     else{high=mid-1;} 
    } 
    return res; 
} 
+0

= (düşük + yüksek)/2 'satırı. Aşırı taşabilir: http://googleresearch.blogspot.mx/2006/06/extra-extra-read-all-about-it-nearly.html – frozenkoi

0
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.util.Collections; 
import java.util.Vector; 

public class Bounds { 

    public static void main(String[] args) throws IOException { 
     Vector<Float> data = new Vector<>(); 
     for (int i = 29; i >= 0; i -= 2) { 
      data.add(Float.valueOf(i)); 
     } 
     Collections.sort(data); 
     float element = 14; 
     BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); 
     BufferedWriter log = new BufferedWriter(new OutputStreamWriter(System.out)); 
     String string = bf.readLine(); 
     while (!string.equals("q")) { 
      element=Float.parseFloat(string); 
      int first = 0; 
      int last = data.size(); 
      int mid; 
      while (first < last) { 
       mid = first + ((last - first) >> 1); 
       if (data.get(mid) < element) //lower bound. for upper use <= 
        first = mid + 1; 
       else 
        last = mid; 
      } 
      log.write("data is: "+data+"\n"); 
      if(first==data.size()) 
       first=data.size()-1; 
      log.write("element is : " + first+ "\n"); 
      log.flush(); 
      string= bf.readLine(); 
     } 
     bf.close(); 
    } 

} 

Bu LOWER_BOUND için uygulamasıdır ve C++ benzer UPPER_BOUND: fikri koduyla açık olmalıdır. Aradığın öğenin vektörde veya listede bulunmasına gerek olmadığını unutmayın. Bu uygulama sadece elemanın üst ve alt sınırlarını verir.