2008-10-18 28 views
42

मुझे आदिम प्रकारों (डबल) की एक बड़ी श्रृंखला मिली है। मैं अवरोही क्रम में तत्वों को कैसे क्रमबद्ध करूं?अवरोही क्रम में आदिम प्रकारों के क्रमबद्ध क्रमबद्ध करें

दुर्भाग्यवश जावा एपीआई एक तुलनात्मक के साथ आदिम प्रकारों के क्रमबद्ध करने का समर्थन नहीं करता है।

एक वैकल्पिक हल को सॉर्ट और फिर उल्टा करने के लिए होगा:

double[] array = new double[1048576]; 
... 
Arrays.sort(array); 
// reverse the array 
for(int i=0;i<array.length/2;i++) { 
    // swap the elements 
    double temp = array[i]; 
    array[i] = array[array.length-(i+1)]; 
    array[array.length-(i+1)] = temp; 
} 

यह धीमी है - खासकर यदि सरणी पहले से ही काफी अच्छी तरह से हल कर रहा है।

बेहतर विकल्प क्या है?

उत्तर

12

Java Primitive में कस्टम तुलनित्र के आधार पर आदिम सरणी को सॉर्ट करने की कार्यक्षमता शामिल है। यह, और जावा 8 का उपयोग करना, अपने नमूना लिखा जा सकता है के रूप में:

double[] array = new double[1048576]; 
... 
Primitive.sort(array, (d1, d2) -> Double.compare(d2, d1), false); 

आप Maven का उपयोग कर रहे हैं, तो आप इसे शामिल साथ कर सकते हैं:

<dependency> 
    <groupId>net.mintern</groupId> 
    <artifactId>primitive</artifactId> 
    <version>1.2.1</version> 
</dependency> 

जब आप करने के लिए तीसरा तर्क के रूप में false पारित sort, यह एक अस्थिर प्रकार का उपयोग करता है, जावा के अंतर्निर्मित dual-pivot quicksort का एक सरल संपादन। इसका मतलब है कि गति अंतर्निहित सॉर्टिंग के करीब होना चाहिए।

पूर्ण प्रकटीकरण: मैंने जावा प्राथमिक पुस्तकालय लिखा था।

+1

यह गिटहब पर एक महान, सरल परियोजना है। बहुत अच्छा काम! पाठकों को यह भी ध्यान रखना चाहिए कि 'सच्चाई 'तीसरे तर्क के रूप में' सॉर्ट 'के रूप में जावा के अंतर्निहित टिमसोर्ट के एक साधारण संपादन का उपयोग करेगा, जो स्थिर है। – kevinarpe

1

आपका कार्यान्वयन (प्रश्न में से एक) उदा। toList() के साथ लपेटना और एक तुलनित्र-आधारित विधि का उपयोग करना। ऑटो-मुक्केबाजी और तुलनित्र विधियों या लपेटा संग्रह वस्तुओं के माध्यम से चलना बस उलटने से कहीं धीमा है।

बेशक आप अपना खुद का प्रकार लिख सकते हैं। हो सकता है कि वह उत्तर न हो जो आप खोज रहे हैं, लेकिन ध्यान दें कि यदि "अगर सरणी पहले से ही अच्छी तरह से हल हो चुकी है" के बारे में आपकी टिप्पणी अक्सर होती है, तो आप एक सॉर्टिंग एल्गोरिदम चुनने के लिए अच्छा कर सकते हैं जो उस मामले को अच्छी तरह से संभालता है (उदाहरण के लिए सम्मिलन) Arrays.sort() (जो विलय है, या सम्मिलन अगर तत्वों की संख्या छोटी है) का उपयोग करने के बजाय।

+1

आप Arrays.toList को डबल पर नहीं बुला सकते हैं [] और यह वही करें जो आप चाहते हैं; Arrays.toList को एक डबल [] और आदिम प्रकारों की एक सरणी पारित करने की जरूरत है। –

+0

Arrays.asList (नया डबल [] {}); ठीक है संकलित करता है। – johnstok

+0

लेकिन परिणाम प्रकार सूची नहीं है ... – johnstok

1

अन्य उत्तरों में Arrays.asList के बारे में कुछ भ्रम हो रहा है। यदि आप

double[] arr = new double[]{6.0, 5.0, 11.0, 7.0}; 
List xs = Arrays.asList(arr); 
System.out.println(xs.size()); // prints 1 

तो आपके पास 1 तत्व के साथ एक सूची होगी। परिणामी सूची में डबल [] सरणी अपने तत्व के रूप में है। आप जो चाहते हैं वह List<Double> है जिसका तत्व double[] के तत्व हैं।

दुर्भाग्यवश, तुलना करने वाले कोई समाधान एक आदिम सरणी के लिए काम नहीं करेगा। Arrays.sortObject[] पारित होने पर केवल एक तुलनाकर्ता को स्वीकार करता है। और ऊपर वर्णित कारणों के लिए, Arrays.asList आपको अपनी सरणी के तत्वों से सूची बनाने नहीं देगा।

तो मेरे पिछले उत्तर के बावजूद नीचे दिए गए टिप्पणियों के बावजूद, क्रमबद्ध करने के बाद सरणी को मैन्युअल रूप से उलटने से बेहतर तरीका नहीं है। कोई अन्य दृष्टिकोण (जैसे Double[] में तत्वों की प्रतिलिपि बनाना और उन्हें पीछे हटाना और उन्हें कॉपी करना) अधिक कोड और धीमा होगा।

+1

मैं आपका कोड चुरा रहा हूं ... क्षमा करें – jjnguy

+0

कोई माफ़ी आवश्यक नहीं है। उन्हें बेहतर बनाने के लिए अपने उत्तरों को संपादित करना यह सब कुछ है। मैंने आपके जवाब को भी ऊपर उठाया क्योंकि यह वह है जो सबसे अधिक चर्चा प्राप्त कर रहा है। –

+0

मैं आपको वोट के साथ भी मार दूंगा। – jjnguy

0

मुझे जावा कोर एपीआई के भीतर किसी भी प्राचीन सॉर्टिंग सुविधाओं से अवगत नहीं है।

D programming language (एक स्टेरॉयड पर सी की तरह) के साथ अपने प्रयोगों से, मैं पाया है कि मर्ज तरह एल्गोरिथ्म यकीनन सबसे तेजी से सामान्य प्रयोजन के आसपास एल्गोरिथ्म छँटाई है (यह क्या डी भाषा ही अपने तरह लागू करने के लिए उपयोग करता है समारोह)।

12

मुझे लगता है कि यह सबसे अच्छा नहीं होगा पहिया फिर से आविष्कार और Arrays.sort उपयोग करने के लिए()।

हां, मैंने "अवरोही" भाग देखा। सॉर्टिंग कठिन हिस्सा है, और आप जावा के लाइब्रेरी कोड की सादगी और गति से लाभ उठाना चाहते हैं। एक बार ऐसा करने के बाद, आप बस सरणी को उलट दें, जो अपेक्षाकृत सस्ते ओ (एन) ऑपरेशन है। Here's some code मैं कम से कम 4 लाइनों में यह करने के लिए मिल गया:

for (int left=0, right=b.length-1; left<right; left++, right--) { 
    // exchange the first and last 
    int temp = b[left]; b[left] = b[right]; b[right] = temp; 
} 
+3

लिंक अब काम नहीं करता है। – nelaaro

+0

लिंक टूटा हुआ। :( –

+0

[2016/01 के रूप में लिंक] (http://www.leepoint.net/data/arrays/arrays-ex-reverse.html) – greybeard

1

आप आदिम सरणियों छँटाई के लिए कॉम्पैरेटर उपयोग नहीं कर सकते।

आपकी सबसे अच्छी शर्त एक सॉर्टिंग एल्गोरिदम के कार्यान्वयन (या कार्यान्वयन को उधार लेना) है जो appropriate आपके उपयोग के मामले में सरणी को सॉर्ट करने के लिए है (आपके मामले में रिवर्स ऑर्डर में)।

0

आपका एल्गोरिदम सही है। लेकिन हम निम्नानुसार अनुकूलन कर सकते हैं: रिवर्सिंग करते समय, आप array.Cength- (i + 1) की कंप्यूटिंग के बाद पिछड़े काउंटर को कम करने के लिए एक और चर रखने की कोशिश कर सकते हैं। (I + 1) समय ले सकता है! और यह भी अस्थायी की घोषणा के लिए कदम है कि हर यह

double temp; 

for(int i=0,j=array.length-1; i < (array.length/2); i++, j--) { 

    // swap the elements 
    temp = array[i]; 
    array[i] = array[j]; 
    array[j] = temp; 
} 
+0

सरणी लंबाई (और आधा सरणी लंबाई) को बाहर करने के बाहर चर लूप सार्थक है। लूप के बाहर 'अस्थायी' घोषित करने से कोई फर्क नहीं पड़ता - इसमें कोई "आवंटन" शामिल नहीं है। – Alnitak

3
double[] array = new double[1048576]; 

आवंटित किया जाना नहीं की जरूरत है ताकि बाहर ...

डिफ़ॉल्ट आदेश तक

आरोही क्रम

उल्टा करने के लिए
Arrays.sort(array,Collections.reverseOrder()); 
+63

'Arrays.sort (सरणी, संग्रह। रिवर्सऑर्डर()); 'एक अच्छा समाधान है लेकिन यह ** नहीं * * प्राइमेटिव्स पर काम करें। यह केवल 'कक्षा' पर काम करेगा। – Omnipresent

+3

आदिम प्रकार – siddhusingh

+0

के लिए कोई समाधान नहीं है यह आदिम प्रकारों पर काम नहीं करता है। – CyprUS

0

यदि प्रदर्शन महत्वपूर्ण है, और आमतौर पर सूची पहले से ही है काफी अच्छी तरह से हल किया गया है।

बबल सॉर्ट सॉर्टिंग के सबसे धीमे तरीकों में से एक होना चाहिए, लेकिन मैंने ऐसे मामलों को देखा है जहां सबसे अच्छा प्रदर्शन एक साधारण द्वि-दिशात्मक बबल प्रकार था।

तो यह उन कुछ मामलों में से एक हो सकता है जहां आप इसे स्वयं कोडिंग से लाभ उठा सकते हैं। लेकिन आपको वास्तव में इसे सही करने की ज़रूरत है (सुनिश्चित करें कि कम से कम कोई अन्य आपके कोड की पुष्टि करता है, यह सबूत बनाता है कि यह काम करता है आदि)

जैसा कि किसी और ने इंगित किया है, यह एक क्रमबद्ध सरणी से शुरू करना बेहतर हो सकता है, और जब आप सामग्री बदलते हैं तो इसे क्रमबद्ध रखें। यह भी बेहतर प्रदर्शन कर सकता है।

7

Guava में प्राचीन प्रकार के सरणी को रैपर प्रकारों की सूची में परिवर्तित करने के तरीके हैं। अच्छा हिस्सा यह है कि ये सूचियां लाइव दृश्य हैं, इसलिए उन पर संचालन अंतर्निहित सरणी पर भी काम करता है (Arrays.asList() के समान, लेकिन प्राइमेटिव के लिए)।

वैसे भी, इन सूचियों में से प्रत्येक Collections.reverse() के लिए पारित किया जा सकता है:

int[] intArr = { 1, 2, 3, 4, 5 }; 
float[] floatArr = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; 
double[] doubleArr = { 1.0d, 2.0d, 3.0d, 4.0d, 5.0d }; 
byte[] byteArr = { 1, 2, 3, 4, 5 }; 
short[] shortArr = { 1, 2, 3, 4, 5 }; 
Collections.reverse(Ints.asList(intArr)); 
Collections.reverse(Floats.asList(floatArr)); 
Collections.reverse(Doubles.asList(doubleArr)); 
Collections.reverse(Bytes.asList(byteArr)); 
Collections.reverse(Shorts.asList(shortArr)); 
System.out.println(Arrays.toString(intArr)); 
System.out.println(Arrays.toString(floatArr)); 
System.out.println(Arrays.toString(doubleArr)); 
System.out.println(Arrays.toString(byteArr)); 
System.out.println(Arrays.toString(shortArr)); 

आउटपुट:

[5, 4, 3, 2, 1]
[5.0, 4.0, 3.0 , 2.0, 1.0]
[5.0, 4.0, 3.0, 2.0, 1.0]
[5, 4, 3, 2, 1]
[5, 4, 3, 2, 1]

+0

'Ints.asList (intArr) .sort()' अंतर्निहित की एक प्रति बनाता है सरणी और प्रतिलिपि टाइप करता है। – ZhekaKozlov

-1
Double[] d = {5.5, 1.3, 8.8}; 
Arrays.sort(d, Collections.reverseOrder()); 
System.out.println(Arrays.toString(d)); 

संग्रह। रिवर्सऑर्डर() प्राइमेटिव पर काम नहीं करता है, लेकिन डबल, इंटीजर आदि संग्रह के साथ काम करता है।रिवर्सऑर्डर()

1

संख्यात्मक प्रकारों के साथ, पहले और बाद में तत्वों को अस्वीकार करना एक विकल्प लगता है। प्रकार के बाद एक रिवर्स के सापेक्ष गति कैश पर निर्भर करती है, और अगर रिवर्स तेज नहीं होता है, तो शोर में कोई अंतर भी खो सकता है।

+0

टिप्पणी के रूप में टिप्पणी पोस्ट करने के बजाय टिप्पणी जोड़ें। –

+1

अब मुझे टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा मिली है, मुझे अभी भी लगता है कि यह एक उत्तर है: यह वर्णन करता है कि कैसे तत्वों को अवरोही क्रम में क्रमबद्ध करें ', और 'सॉर्ट' के साथ और फिर रिवर्स [...] धीमा है, मुझे लगता है कि यह गति को मापने का एक विकल्प है। आपकी आंखों में एक जवाब के बजाय यह एक टिप्पणी क्या बनाता है? – greybeard

2

मुझे लगता है कि सबसे आसान समाधान अभी भी है:

  1. कि क्रमबद्ध सरणी जो तब अंतिम आइटम
  2. का उपयोग करना है के भीतर अधिकतम ढूँढना सरणी
  3. की प्राकृतिक व्यवस्था हो रही है एक साथ पाश के लिए कमी ऑपरेटर

जैसा कि पहले दूसरों ने कहा था: toList का उपयोग अतिरिक्त प्रयास है, Arrays.sort (सरणी, संग्रह .reverseOrder()) primitives के साथ काम नहीं करता है और एक अतिरिक्त फ्रेम का उपयोग नहीं करता है ework जटिल लगता है जब आप सभी की जरूरत पहले से ही inbuild है और इसलिए शायद तेजी के साथ-साथ ...

नमूना कोड:

import java.util.Arrays; 

public class SimpleDescending { 

    public static void main(String[] args) { 

     // unsorted array 
     int[] integerList = {55, 44, 33, 88, 99}; 

     // Getting the natural (ascending) order of the array 
     Arrays.sort(integerList); 

     // Getting the last item of the now sorted array (which represents the maximum, in other words: highest number) 
     int max = integerList.length-1; 

     // reversing the order with a simple for-loop 
     System.out.println("Array in descending order:"); 
     for(int i=max; i>=0; i--) { 
      System.out.println(integerList[i]); 
     } 

     // You could make the code even shorter skipping the variable max and use 
     // "int i=integerList.length-1" instead of int "i=max" in the parentheses of the for-loop 
    } 
} 
0
छोटे सरणियों इस काम कर सकते हैं के लिए

int getOrder (double num, double[] array){ 
    double[] b = new double[array.length]; 
    for (int i = 0; i < array.length; i++){ 
     b[i] = array[i]; 
    } 
    Arrays.sort(b); 
    for (int i = 0; i < b.length; i++){ 
     if (num < b[i]) return i; 
    } 
    return b.length; 
} 

मैं हैरान था कि सरणी ख की प्रारंभिक लोड हो रहा है आवश्यक

double[] b = array; // makes b point to array. so beware! 
0
Before sorting the given array multiply each element by -1 

तो Arrays.sort (आगमन) का उपयोग तब फिर -1

for(int i=0;i<arr.length;i++) 
    arr[i]=-arr[i]; 
Arrays.sort(arr); 
for(int i=0;i<arr.length;i++) 
    arr[i]=-arr[i]; 
द्वारा प्रत्येक तत्व गुणा था
0

यदि जावा 8 का उपयोग कर रहा है, तो सरणी को स्ट्रीम में बदलें, क्रमबद्ध करें और वापस कन्वर्ट करें। सभी कार्यों को केवल एक पंक्ति में किया जा सकता है, इसलिए मुझे लगता है कि इस तरह से बहुत बुरा नहीं है।

double[] nums = Arrays.stream(nums).boxed(). 
     .sorted((i1, i2) -> Double.compare(i2, i1)) 
     .mapToDouble(Double::doubleValue) 
     .toArray(); 
+0

बॉक्सिंग बहुत महंगा है। –

0

नीचे मेरा समाधान है, आप इसे अपनी आवश्यकताओं के अनुसार अनुकूलित कर सकते हैं।

यह कैसे काम करता है? यह तर्क के रूप में पूर्णांक की एक सरणी लेता है। इसके बाद यह एक नई सरणी तैयार करेगा जिसमें तर्कों से सरणी के समान मान होंगे। ऐसा करने का कारण मूल सरणी को बरकरार रखना है।

एक बार नई सरणी की नकल की डेटा शामिल हैं, हम इसे हालत जब तक मान गमागमन अगर (newArr [i] < newArr [i + 1]) गलत का आकलन के आधार पर सॉर्ट। इसका मतलब है कि सरणी अवरोही क्रम में क्रमबद्ध है।

पूरी तरह से स्पष्टीकरण के लिए मेरे ब्लॉग पोस्ट here देखें।

public static int[] sortDescending(int[] array) 
{ 
    int[] newArr = new int[array.length]; 

    for(int i = 0; i < array.length; i++) 
    { 
     newArr[i] = array[i]; 
    } 

    boolean flag = true; 
    int tempValue; 

    while(flag) 
    { 
     flag = false; 

     for(int i = 0; i < newArr.length - 1; i++) 
     { 
      if(newArr[i] < newArr[i+1]) 
      { 
       tempValue = newArr[i]; 
       newArr[i] = newArr[i+1]; 
       newArr[i+1] = tempValue; 
       flag = true; 
      } 
     } 
    } 

    return newArr; 
} 
0

एक बेहतर और अधिक संक्षिप्त दृष्टिकोण हो सकता है:

Arrays.sort(array); 
List<Integer> list=Arrays.asList(array); 
Collections.reverse(list); 
System.out.println(list); 

इसे वापस सरणी देने के लिए और अधिक आकर्षक है जाएगा। इनपुट: 4 2 9 5 3 आउटपुट: [9, 5, 4, 3, 2]

संबंधित मुद्दे