#c #arrays #c
#c #массивы #c
Вопрос:
У меня возникают проблемы с этим, вы можете мне помочь?
Я успешно удаляю дубликат, но затем я использую пузырьковую сортировку для его сортировки, но это неэффективно.
Как я могу удалить дубликат, а затем отсортировать его? Использование 2 функций не может принести то, что я хочу.
#include <stdio.h>
#include <conio.h>
int arr[100];
int n;
void RemoveDuplicate(int arr[]);
void Print(int arr[]);
int main()
{
int i;
printf("Enter n:");
scanf("%d",amp;n);
for(i=0;i<n;i )
scanf("%d",amp;arr[i]);
RemoveDuplicate(arr);
Print(arr);
getch();
return 0;
}
void Print(int arr[])
{
int i;
for(i=0;i<n;i )
printf("%d ",arr[i]);
}
void RemoveDuplicate(int arr[])
{
int i,j,k;
for(i=0;i<n;i )
{
for(j=i 1;j<n;)
{
if(arr[i]==arr[j])
{
for(k=j;k<n;k )
{
arr[k]=arr[k 1];
}
n--;
}
else
j ;
}
}
}
Комментарии:
1. Переверните операции. Отсортируйте, затем удалите дубликаты. Делает это намного проще.
2. Подсказка: обычно это делается в противоположном направлении: сначала сортируется последовательность, а затем удаляются дубликаты. Удаление дубликатов в несортированной последовательности — это боль.
3. C или C ? Пожалуйста, выберите один.
4. Вы можете удалять дубликаты во время сортировки. Если вы выполняете, скажем, сортировку по куче, вы можете сравнить элемент, извлеченный из кучи, с предыдущим элементом в отсортированной части массива и добавить новое значение, если оно совпадает с предыдущим.
5. В C вы можете использовать
std::set
контейнер для хранения уникальных элементов
Ответ №1:
Все примеры не проверены и начинаются со следующего
if (n<1 || n > sizeof(arr))
return;
auto begin = std::begin(arr);
auto end = begin n;
Использование std::set
std::set<int> unique(begin, end);
std::copy(unique.begin(), unique.end(), std::begin(arr));
int size = unique.size();
Использование кучи
std::make_heap(begin, end);
std::sort_heap(begin, end);
auto last = std::unique(begin, end);
auto size = std::distance(begin, last);
Просто используя std::sort вместо sort_heap
std::sort(begin, end);
auto last = std::unique(begin, end);
auto size = std::distance(begin, last);
Использование кучи с ручным pop
std::make_heap(std::begin(arr), std::end(arr));
auto first = begin;
auto last = end;
auto sorted = std::prev(last);
std::pop_heap(first, last--); // initial value
while (first != last)
std::pop_heap(first, last--);
if (*last != *sorted amp;amp; last != sorted)
*--sorted = *last;
}
auto size = std::distance(sorted, end);
std::copy(sorted, end, begin); // move values to start of array
Условие
last != sorted
будет иметь значение false до первого дубликата и true после этого, поэтому цикл можно разделить на две части для возможного повышения производительности, но предсказатель ветвления должен устранить большинство проблем с производительностью из-за этого.
Если количество уникальных значений невелико и имеет небольшой разброс, а ‘n’ велико, используйте подсчетный массив.
Пример подсчета символов для std::векторный текст;
std::array<int,256> count;
std::vector<char> resu<
for (auto ch : text)
count[ch] ;
for (auto idx = 0; idx < count.size(); idx)
if (count[idx])
result.emplace_back(idx);
Если количество дубликатов больше, но значения разбросаны, рассмотрите возможность использования std::unordered_set вместо этого и сортировки в конце.
std::unordered:set<int> unique(begin, end);
std::copy(unique.begin(), unique.end(), std::begin(arr));
int size = unique.size();
std::sort(begin, begin size);