Пожалуйста, исправьте все предупреждения в вашем коде - вы можете включить флаги Wall
и Wextra
в GCC, например.
Тогда одна логическая ошибка, которую я вижу здесь:
array[j] == array[i]
где вы хотите назначить, а не сравнивать, поэтому измените его на:
array[j] = array[i]
Более того, когда вы печатаете массив с удаленными дублирующимися значениями, вы выполняете итерацию до end
, но эта переменнаяне объявлено.
Я думаю, что вам нужно сделать шаг назад и выполнить операцию с использованием дополнительного массива, который будет старым массивом с удаленными дублирующими элементами. В этом случае вы можете изменить свой код следующим образом:
#include <stdio.h>
#include <stdlib.h>
void removeDups(int *array, int length)
{
int array_no_dups[length];
int unique_n = 0;
for(int i = 0; i < length; ++i)
{
int found = 0; // flag
//check if element already in the array without duplicates
for(int j = 0; j < unique_n; j++)
{
if(array[i] == array_no_dups[j])
found = 1;
}
// If not found
if(!found)
// then append it to the array without duplicates
array_no_dups[unique_n++] = array[i];
}
printf("Number of new elements: %d,", unique_n);
printf(" new elements: ");
for(int i = 0; i < unique_n; i++)
{
printf("%d ", array_no_dups[i]);
}
}
void print_array(int *array, int length)
{
printf("Number of elements: %d,", length);
printf(" Orginal elements: ");
for(int i = 0; i < length; i++)
{
printf("%d " , array[i]);
}
}
int main()
{
int array[10];
int size = 10;
for(int i = 0; i < size; i++)
array[i] = rand() % 10 + 1;
print_array(array, size);
printf("\n");
removeDups(array, size);
return 0;
}
Вывод:
Number of elements: 10, Orginal elements: 4 7 8 6 4 6 7 3 10 2
Number of new elements: 7, new elements: 4 7 8 6 3 10 2
Теперь, если вы действительно хотите удалить дубликаты на месте, тогдакаждый раз, когда вы находите повторяющееся значение, вам нужно будет поменять 2-е вхождение этого значения на последний элемент вашего массива (который будет проиндексирован счетчиком, который вы будете поддерживать). Конечно, теперь вам нужно быть осторожным с вашими индексами.
Например, вы можете на месте вот так (вызвать метод так: removeDups(array, &size);
):
void removeDups(int *array, int *length)
{
int original_len = *length;
for(int i = 0; i < original_len - 1; ++i)
{
for(int j = i + 1; j < *length; ++j)
{
if(array[i] == array[j])
{
array[j] = array[*length - 1];
(*length)--;
j--; // since the new `array[j]` element might be also a duplicate of `array[i]`
}
}
}
printf("Number of new elements: %d,", *length);
printf(" new elements: ");
for(int i = 0; i < *length; i++)
{
printf("%d ", array[i]);
}
}
Теперь вывод будет:
Количество новых элементов: 7, новых элементов: 4 7 8 6 2 3 10
где оригиналпорядок элементов не сохраняется.
Если вы хотите сделать это на месте и сохранить исходный порядок, то вместо замены каждый раз, когда вы найдете дубликат, вы должны сдвинуть весь подмассив из (j+1) -ый элемент на одну позицию слева.
Это намного более дорогая операция с точки зрения сложности времени, но это компромисс, вы медленнее, но сохраняете порядок. Вы должны делать то, что требует ваше приложение, то есть, если порядок имеет значение, используйте сдвиговый подход, если порядок не имеет значения, используйте своп-подход.