2009-11-28 6 views
1

Вам задан массив целых чисел, и вы можете отсортировать эти целые числа на основе частоты
их возникновения. Разработать алгоритм и проанализировать его временную сложность. В случае связей меньший номер
должен отображаться первым в отсортированном списке.Сортировка по частоте

Пример ввода: 3,4,3,2,3,5,4,2,2,1,2
Пример вывода: 1 5 4 3 2

+2

Это звучит как домашняя проблема ... Разве это? – jheddings

+0

Это, безусловно, вопрос о домашнем задании. –

+0

Это не проблема домашней работы. Эта проблема имеет множество практических приложений, например, вы можете отсортировать список слов о том, сколько раз они происходят (скажем, исходя из их популярности) – Tanuj

ответ

3

Если дополнительное пространство разрешено: перейти вход и провести частотный анализ. Запишите его в некоторой хеш-таблице. Это означает, что, грубо говоря:

for each x in input: 
    if x in table: 
    ++table[x] 
    else 
    table.insert(x) 

Тогда простой Quicksort на уникальных значений, с функцией сравнения с учетом частоты вместо самого значения.

То есть:

function freq_compare (x, y): 
    return compare(table[x], table[y]) 

compare Где числовой для частот.

+0

Я подумал об этом, но тогда мы должны заботиться о столкновениях при использовании хеш-таблицы , Также как вы будете делать QuickSort только по уникальным значениям? Когда вы делаете частотный анализ, вам нужно хранить уникальные значения. – Tanuj

+0

Если у вас есть обычная реализация хеш-таблицы, нет проблем с столкновением. Если таблица не слишком мала, время выполнения всей вставки будет равно O (N). Что касается уникальных значений, их можно получить, просто линейно пройдя все ключи в хеш-таблице. –

+0

если это действительно не домашнее задание, скачайте GLib. у него есть хорошая реализация хеш-таблицы, вы можете использовать –

1

Сортируйте массив, а затем мы можем легко получить частоту чисел, потому что дублирующиеся числа будут помещены рядом друг с другом. Когда вы получаете частоту чисел, вставьте ее в карту с ключом как частоту и значение как число. Так как карта хранит ключи в отсортированном порядке, мы можем перебирать карту, чтобы получить результат.

+0

Этот метод терпит неудачу, если несколько номеров имеют одинаковую частоту, потому что более старое число той же частоты будет заменено более новым на карте. ** Что касается одного и того же ключа (частоты), то будет несколько значений (Number). ** –

+0

@Abhinavkumar true, в этом случае это не удастся. Мы можем исправить это, имея значение карты как вектор int вместо int. – San

0

Сначала сделайте HashMap, поместив элемент массива в качестве ключа и их частоту в качестве значений. Сортируйте их с помощью компаратора на основе ключей и значений.

import java.io.*; 
import java.util.*; 
import java.lang.*; 
public class Sum_of 
{ 
public static HashMap<Integer, Integer> sortHashMapByValues(
    HashMap<Integer, Integer> passedMap) { 
List<Integer> mapKeys = new ArrayList<>(passedMap.keySet()); 
List<Integer> mapValues = new ArrayList<>(passedMap.values()); 
Collections.sort(mapValues); 
Collections.sort(mapKeys); 

LinkedHashMap<Integer, Integer> sortedMap = 
    new LinkedHashMap<>(); 

Iterator<Integer> valueIt = mapValues.iterator(); 
while (valueIt.hasNext()) { 
    Integer val = valueIt.next(); 
    Iterator<Integer> keyIt = mapKeys.iterator(); 

    while (keyIt.hasNext()) { 
     Integer key = keyIt.next(); 
     Integer comp1 = passedMap.get(key); 
     Integer comp2 = val; 

     if (comp1.equals(comp2)) { 
      keyIt.remove(); 
      sortedMap.put(key, val); 
      break; 
     } 
    } 
} 
return sortedMap; 
} 
    public static void main(String args[]) 
    { 
     HashMap<Integer,Integer> hs = new HashMap<Integer,Integer>(); 
     int a[]={3,4,3,2,3,5,4,2,2,1,2}; 
     int n= a.length; 
     int c=0; 
     for(int i=0;i<n;i++) 
     { 
     if(hs.containsKey(a[i])) 
     { 
      c=hs.get(a[i]); 
      hs.put(a[i],c+1); 
     } 
     else 
     hs.put(a[i],1); 
    } 
    hs=Sum_of.sortHashMapByValues(hs); 
    System.out.println(hs.keySet()); 
     } 
} 
Смежные вопросы