How to organize an array in decreasing order of frequency of each number?

Input: {5, 13, 6, 5, 13, 7, 8, 6, 5}

Output: {5, 5, 5, 13, 13, 6, 6, 7, 8}

The question is to arrange the numbers in the array in descending order of their frequency, while maintaining the order in which they appear.

If there is a connection, as in this example between 13 and 6, then the number that first appears in the input array will be the first in the output array.

+5
source share
7 answers

I think I would do it like this:

Use the key-value data structure, in which the number itself is the key, and the value of the number of matches and the first occurrence index is the value.

. ( ), , , 1 . .

() () ( , ).

<= N, , , , O (N log N)

+6

:

,

, (O (N)) O (N log N).

- , "" - ( ),

, . - O (N) , O (N log N) . , .

+3

Python2.7 Python3.1

>>> from collections import Counter
>>> L=[5, 13, 6, 5, 13, 7, 8, 6, 5]
>>> c=Counter(L)
>>> def keyfunc(x):
...     return (-c.get(x),L.index(x))
... 
>>> sorted(L,key=keyfunc)
[5, 5, 5, 13, 13, 6, 6, 7, 8]

Python2.6

>>> from collections import defaultdict
>>> L=[5, 13, 6, 5, 13, 7, 8, 6, 5]
>>> c=defaultdict(int)
>>> for x in L:
...     c[x]+=1
... 
>>> def keyfunc(x):
...     return (-c.get(x),L.index(x))
... 
>>> sorted(L,key=keyfunc)
[5, 5, 5, 13, 13, 6, 6, 7, 8]

, ( )

>>> L=[5, 13, 6, 5, 13, 7, 8, 6, 5]
>>> c={}
>>> for x in L:
...     c[x]=c.setdefault(x,0)+1
... 
>>> def keyfunc(x):
...     return (-c.get(x),L.index(x))
... 
>>> sorted(L,key=keyfunc)
[5, 5, 5, 13, 13, 6, 6, 7, 8]

keyfunc

keyfunc(5) returns (-3,0)
keyfunc(6) returns (-2,2)
keyfunc(7) returns (-1,5)
keyfunc(8) returns (-1,6)
keyfunc(13) returns (-2,1)

keyfunc

+2

, , , .

- , std:: map/pair, , , .

+1

#. : .

: 5 5 5 13 13 6 6 7 8. : O (n). : O (n log n).

class Program
{
    class FreqAndOrdinal
    {
        public int Frequency;
        public int Ordinal;
        public FreqAndOrdinal(int freq, int ord)
        {
            this.Frequency = freq;
            this.Ordinal = ord;
        }
    }

    static int Compare(FreqAndOrdinal x, FreqAndOrdinal y)
    {
        int result = y.Frequency.CompareTo(x.Frequency);
        return result == 0 ? x.Ordinal.CompareTo(y.Ordinal) : result;
    }

    static void Main(string[] args)
    {
        int[] nums = new int[] { 5, 13, 6, 5, 13, 7, 8, 6, 5 };
        var freqLookup = new Dictionary<int, FreqAndOrdinal>(nums.Length);
        for (int i = 0; i < nums.Length; i++)
        {
            FreqAndOrdinal tmp;
            if (freqLookup.TryGetValue(nums[i], out tmp))
                ++tmp.Frequency;
            else
                freqLookup[nums[i]] = new FreqAndOrdinal(1, i);
        }

        Array.Sort(nums, (x,y) => Compare(freqLookup[x], freqLookup[y]));

        for (int i = 0; i < nums.Length; i++)
        {
            Console.Write(" {0}", nums[i]);
        }
        Console.ReadKey();
    }
}
+1

x, y: (x) count (y). , (x) (y)

python:

input = [5, 13, 6, 5, 13, 7, 8, 6, 5]
orig = list(input)

def cmp(x, y):
    if (orig.count(y) - orig.count(x) != 0):
        return orig.count(y) - orig.count(x)
    return orig.index(x) - orig.index(y)   

input.sort(cmp) 
print input

, .

0
private static void sortByFrequency(int[] a)
{
    Map<Integer, Element> map = new HashMap<Integer, Element>();
    for(int i=0; i<a.length; i++)
    {
        if(map.get(a[i]) == null)
        {
            map.put(a[i], new Element(i));
        }
        else
        {
            Element e = map.get(a[i]);
            e.frequency++;
        }
    }

    Set<Integer> set = map.keySet();
    TreeSet<Element> treeSet = new TreeSet<Element>();
    for(int i : set)
    {
        treeSet.add(map.get(i));
    }

    for(Element e : treeSet)
    {
        for(int i=0; i<e.frequency;i++)
        {
            System.out.println(a[e.index]);
        }
    }
}

private static class Element implements Comparable<Element>
{
    private final int index;
    private int frequency;

    Element(int index)
    {
        this.index = index;
        this.frequency = 1;
    }

    @Override
    public int compareTo(Element o)
    {
        int k = o.frequency - this.frequency;
        if(k != 0) return k;
        else
        {
            return this.index - o.index;
        }
    }
}

public static void main(String[] args)
{
    int[] a = {5, 13, 6, 5, 13, 7, 8, 6, 5};
    sortByFrequency(a);
}
0

All Articles