Top.Mail.Ru
Ответы

Помогите на C++

Уникальные элементы

Дан массив. Распечатайте только те значения элементов массива, которые встречаются в нём ровно один раз. Элементы следует распечатывать в том порядке, в котором они встречаются в массиве. Создавать новые массивы нельзя.

Обратите внимание, что разобранная в лекции задача отличается от данной.

Входные данные

В первой строке входных данных содержится натуральное число n
(n⩽100) — количество элементов массива. В следующей строке содержатся n натуральных чисел, не превосходящих 30000

, элементы массива.

Выходные данные

Выведите ответ к задаче.

По дате
По рейтингу
Аватар пользователя
Мастер
1234567891011
 #include <iostream> 
using namespace std; 
int main(){ 
    int n,a[101];cin>>n; 
    for(int i=0;i<n;i++)cin>>a[i]; 
    for(int i=0;i<n;i++){ 
        int c=0; 
        for(int j=0;j<n;j++) c+=a[i]==a[j]; 
        if(c==1) cout<<a[i]<<" "; 
    } 
} 
Аватар пользователя
Ученик

#include <iostream>
#include <unordered_set>
#include <vector>

using namespace std;

// Функция для печати уникальных элементов из вектора
void printUniqueElements(const vector<int>& arr) {
unordered_set<int> seen; // Множество для отслеживания встреченных элементов
unordered_set<int> duplicates; // Множество для отслеживания дубликатов

// Проходим по всем элементам массива
for (int num : arr) {
// Если элемент уже встречался, добавляем его в множество дубликатов
if (seen.find(num) != seen.end()) {
duplicates.insert(num);
} else {
// Если элемент встречается впервые, добавляем его во множество встреченных
seen.insert(num);
}
}

// Печатаем только те элементы, которые не находятся в множестве дубликатов
for (int num : arr) {
if (duplicates.find(num) == duplicates.end()) {
cout << num << " ";
}
}
}

int main() {
int n;
cout << "Enter number of elements: ";

// Проверка корректности ввода размера массива
while (!(cin >> n) || n <= 0) {
cout << "Please enter a valid positive integer: ";
cin.clear(); // Сбрасываем состояние ошибки потока
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Игнорируем некорректный ввод
}

vector<int> arr(n); // Создаем вектор для хранения элементов
cout << "Enter the elements: ";

// Считываем элементы массива с проверкой корректности ввода
for (int i = 0; i < n; ++i) {
while (!(cin >> arr[i])) {
cout << "Please enter a valid integer: ";
cin.clear(); // Сбрасываем состояние ошибки потока
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Игнорируем некорректный ввод
}
}

// Вызываем функцию для печати уникальных элементов
printUniqueElements(arr);

return 0;
}



Пример:
Enter number of elements: 7
Enter the elements: 3 3 7 5 5 2 8
7 2 8
[Program finished]

Аватар пользователя
Мудрец

Контейнеры изучали? Так вот можно:

123456789101112131415
 #include <vector> 
#include <iostream> 
 
int main() 
{ 
  int k, l, m, n; std::cin >> n; 
  std::vector<int> A(n); 
  for (l = 0; l < n; ++l) std::cin >> A[l]; 
  for (auto a: A) 
  { 
    k = 0; 
    for (auto b: A) if (a == b) ++k; 
    if (k == 1) std::cout << a << ' '; 
  } 
} 

Временная сложность получается O(n²). Можно также исключать неуникальные элементы из массива (обходя его, например, с конца) инструкцией erase; при этом количество операций вроде бы должно уменьшиться (да и то не таким образом чтобы уменьшить временну́ю сложность алгоритма!), но так как массив, элементы которого вводятся с клавиатуры вручную, скорее всего небольшой, то и никакие оптимизации тут ровным счётом ни к чему!
Без контейнеров:

123456789101112131415
 #include <iostream> 
int main() 
{ 
    int k, l, n; std::cin >> n; 
    int *A = new int [n]; 
    for (l = 0; l < n; ++l) std::cin >> A[l]; 
    for (l = 0; l < n; ++l) 
    { 
      k = 0; 
      for (m = 0; m < n; ++m) if (A[l] == A[m]) ++k;
      if (k == 1) std::cout << A[l] << ' ';
  } 
  delete [] A; 
  return 0; 
} 
Аватар пользователя
Ученик

#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

int main() {
int n;
cin >> n;

vector<int> arr(n);
for (int i = 0; i < n; ++i) {
cin >> arr[i];
}

unordered_map<int, int> counts;
for (int x : arr) {
counts[x]++;
}

for (int x : arr) {
if (counts[x] == 1) {
cout << x << " ";
}
}
cout << endl;

return 0;
}

cpp
Как работает код:

Ввод данных:

Считывает количество элементов n.
Создает вектор arr для хранения элементов массива и считывает элементы.
Подсчет частоты:

Создает unordered_map counts. В unordered_map ключами будут значения элементов массива, а значениями - количество их вхождений.
Проходит по массиву arr. Для каждого элемента x:
counts[x]++; Увеличивает счетчик для этого элемента в counts. Если элемента нет в counts, он автоматически создается с начальным значением 0, и затем увеличивается до 1.
Вывод уникальных элементов:

Проходит по массиву arr снова.
Для каждого элемента x:
if (counts[x] == 1): Проверяет, встречается ли элемент ровно один раз (его счетчик равен 1).
cout << x << " ";: Если да, выводит элемент в выходной поток.
cout << endl;: Выводит перевод строки в конце.
Почему используется unordered_map:

Эффективный поиск: unordered_map (хэш-таблица) обеспечивает быстрый доступ к элементам по ключу (в данном случае, по значению элемента массива). Поиск, добавление и обновление элементов в unordered_map в среднем занимает O(1) времени (константное время).
Простота использования: Легко хранить пары “элемент - количество вхождений” с помощью unordered_map.
Преимущества решения:

Эффективность: Использует unordered_map для эффективного подсчета частоты. Общее время работы алгоритма составляет O(n) - линейное, где n - количество элементов в массиве.
Простота: Код понятный и легко читаемый.
Требования соблюдены: Не используются новые массивы, элементы выводятся в порядке их появления.



Видео по теме