самый быстрый способ (раз упорядоченный список):
nums = [1, 2, 2, 3, 4, 5, 5, 5]
count = 1
for i in range(1, len(nums)):
if nums[i - 1] != nums[i]:
count += 1
print(count)
или чуть сократив код:
count = 1
for i in range(1, len(nums)):
count += nums[i - 1] != nums[i]
правда стоит сделать проверку для ситуации, когда список пустой
из той же серии (если требуется не только подсчитать кол-во элементов, но и найти эти элементы)
count = len([nums[0]] + [nums[i] for i in range(1, len(nums)) if nums[i - 1] != nums[i]])
Это все требует одного прохода по списку
Можно написать очень короткий код, но по времени работы для такой задачи он будет неоптимальным
count = len(set(nums))
Самый неоптимальный по времени работы код
nums = [1, 2, 2, 3, 4, 5, 5, 5]
res = []
for elem in nums:
if elem not in res:
res.append(elem)
print(len(res))
Вобщем я сделал программу, но она немного не правильно работает, если одинаковые числа идут подряд, то она их не выводит. Подскажите в чём дело? Вот полное условие: В массиве M(k) много совпадающих элементов. Найти количество различных элементов в нем. Здесь я сделал немного иначе: массив различных элементов выводится на экран, но смысл остался прежним. Задача сделать это с использованием циклов массивов и условий.
#include <locale>
#include <iostream>
#include <conio.h>
void main()
{
setlocale(LC_ALL, "rus");
using namespace std;
int n, i, r=0, c=1;
int *a = new int[99999];
int *b = new int[99999];
int t, k=0;
cout << "Введите размер массива" << endl;
cin >> n;
cout << "Введите размерность" << endl;
cin >> t;
cout << endl;
srand((unsigned)time(NULL));
cout << "Цикл" << endl;
for (i = 0; i < n; i++) // Создаём рандомный массив
{
a[i] = rand() % t;
cout << a[i] << endl;
}
cout << endl;
for (i = 0; i < n; i++)
{
for (int h=0; h < n+1; h++) {
if (a[i] != a[h] && i!=h) {
k++;
if (k==i+1) {
cout << a[i] << endl;
break;
}
}
if (a[i] == a[h] && i != h) {
break;
}
}
k = 0;
}
_getch();
}
Задача. Найти количество различных чисел в массиве из N элементов.
Как будем решать задачу (2 способа)
для хранения уникальных значений исходного массива будем использовать:
- новый массив
- множество
Способ 1
Сформируем массив a случайных чисел из диапазона от 0 до 20.
Заведем массив b и заполним все его ячейки числами -1.
Переменной j присвоим значение 0.
В цикле для k от 1 до n:
- Присвоим флагу f значение true, это будет означать, что ячейка a[k] хранит уникальное значение, и его нет в массиве b.
- В цикле для s от 1 до j сравним значение a[k] со значениями массива b (a[k]=b[s]), если условие верно, флагу присвоим значение false.
- Если флаг не поменял значение true на false и хранит значение true, счетчик j увеличим на 1 и сохраним в ячейке b[j] значение a[k].
В итоге переменная j будет хранить количество измененных ячеек массива b — количество различных элементов исходного массива.
Программа решения задачи на языке Паскаль (способ 1)
const n = 10;
var a,b:array[1..n] of integer;
k,s,j:integer;
f:boolean;
begin
write(‘Исходный массив: ‘);
for k:=1 to n do
begin
a[k]:=random(21); write(a[k],’ ‘);
b[k]:=-1;
end;
j:=0;
for k:=1 to n do
begin
f:=true; //элемента a[k] нет в массиве b
for s:=1 to j do if a[k]=b[s] then f:=false;
if f then begin j+=1; b[j]:=a[k]; end;
end;
writeln;
write(‘Неповторяющиеся числа: ‘);
for k:=1 to j do write(b[k],’ ‘);
writeln;
writeln(‘Количество различных чисел: ‘,j);
end.
Способ 2
Заведем пустое множество m.
Сформируем массив a случайных чисел из диапазона от 0 до 20.
В цикле для k от 1 до n:
- если значение a[k] нет в множестве m, увеличим счетчик j на 1,
- добавим значение a[k] в множество m.
В итоге переменная j будет хранить длину сформированного множества, то есть количество различных значений исходного массива
В цикле foreach k in m do
(для каждого k, имеющегося в множестве m) выведем значения, сохраненные в множестве m.
Программа решения задачи на языке Паскаль (способ 2)
const n = 10;
var a:array[1..n] of integer;
k,j:integer;
m:set of integer;
begin
m:=[];
j:=0;
write(‘Исходный массив: ‘);
for k:=1 to n do
begin
a[k]:=random(21); write(a[k],’ ‘);
if not(a[k] in m) then j+=1;
m:=m+[a[k]];
end;
writeln;
write(‘Неповторяющиеся числа: ‘);
foreach k in m do write(k,’ ‘);
writeln;
writeln(‘Количество различных чисел: ‘,j);
end.
Результат запуска программы
Если значительно увеличить количество элементов массива a, какая программа будет искать различные числа более эффективно (быстро)?
0 / 0 / 0 Регистрация: 13.04.2020 Сообщений: 25 |
|
1 |
|
Найти количество различных элементов в массиве08.05.2020, 12:37. Показов 13686. Ответов 9
Дан массив из n чисел. Необходимо вывести количество различных элементов в массиве. Формат входных данных входные данные
0 |
Максим 1994 115 / 72 / 48 Регистрация: 16.11.2012 Сообщений: 257 |
||||
08.05.2020, 15:24 |
2 |
|||
Сообщение было отмечено f_ как решение Решение
1 |
0 / 0 / 0 Регистрация: 13.04.2020 Сообщений: 25 |
|
08.05.2020, 15:47 [ТС] |
3 |
Тут в некоторых тестах не верный ответ. Input Correct
0 |
Shut913 151 / 103 / 49 Регистрация: 21.11.2019 Сообщений: 285 |
||||||||
08.05.2020, 16:22 |
4 |
|||||||
Сообщение было отмечено f_ как решение Решениепопробуйте этот кусок кода предыдущего автора (25-31 строка}:
заменить таким:
0 |
0 / 0 / 0 Регистрация: 13.04.2020 Сообщений: 25 |
|
08.05.2020, 16:43 [ТС] |
5 |
Shut913, в for опечатка?
for(int j=>+1;j<n;++j) Может for(int j >=+1;j<n;++j) ? Добавлено через 12 минут А если заменить, то выдаёт: 000003.cpp: In function ‘int main()’:
0 |
151 / 103 / 49 Регистрация: 21.11.2019 Сообщений: 285 |
|
08.05.2020, 16:44 |
6 |
да, там была опечатка, уже подправил, и проверил, код компилируется
0 |
0 / 0 / 0 Регистрация: 13.04.2020 Сообщений: 25 |
|
08.05.2020, 16:47 [ТС] |
7 |
Теперь тест не проходит.
0 |
Shut913 151 / 103 / 49 Регистрация: 21.11.2019 Сообщений: 285 |
||||||||
08.05.2020, 17:12 |
8 |
|||||||
подправь 11 строку
на
0 |
0 / 0 / 0 Регистрация: 13.04.2020 Сообщений: 25 |
|
08.05.2020, 17:15 [ТС] |
9 |
Спасибо большое!
0 |
zss Модератор 13101 / 10373 / 6207 Регистрация: 18.12.2011 Сообщений: 27,749 |
||||
08.05.2020, 17:23 |
10 |
|||
Сообщение было отмечено f_ как решение Решение
1 |
Дан массив и целое число k
, найти количество различных элементов в каждом подмассиве размера k
.
Например,
Input:
arr[] = { 2, 1, 2, 3, 2, 1, 4, 5 };
k = 5;
Output:
The count of distinct elements in subarray { 2, 1, 2, 3, 2 } is 3
The count of distinct elements in subarray { 1, 2, 3, 2, 1 } is 3
The count of distinct elements in subarray { 2, 3, 2, 1, 4 } is 4
The count of distinct elements in subarray { 3, 2, 1, 4, 5 } is 5
Потренируйтесь в этой проблеме
Обратите внимание, что проблема конкретно нацелена подмассивы которые являются смежными (т. е. занимают последовательные позиции) и по своей сути поддерживают порядок элементов.
Наивным решением является рассмотрение каждого подмассива в заданном массиве и подсчет всех отдельных элементов в нем с помощью двух вложенных циклов, как показано ниже в C, Java и Python. Временная сложность этого подхода составляет O(n.k2), куда n
размер ввода и k
размер подмассива.
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include <stdio.h> // Функция для определения количества различных элементов в каждом подмассиве // размером `k` в массиве void findDistinctCount(int arr[], int n, int k) { // рассматриваем каждый подмассив размера `k` for (int x = 0; x <= n — k; x++) { // поддерживает счетчик различных элементов в текущем подмассиве int distinct = 0; // текущий подмассив формируется подмассивом `arr[x, x+k)` for (int i = x; i < x + k; i++) { // увеличить количество различных элементов для `arr[i]` в текущем подмассиве distinct++; // проверяем, присутствует ли `arr[i]` в подмассиве `arr[x, i-1]` или нет for (int j = x; j < i; j++) { // если в текущем подмассиве найден повторяющийся элемент if (arr[i] == arr[j]) { // снимите пометку с элемента `arr[i]` как отдельный – уменьшите количество distinct—; break; } } } printf(«The count of distinct elements in subarray [%d, %d] « «is %dn», x, x + k — 1, distinct); } } int main(void) { int arr[] = { 2, 1, 2, 3, 2, 1, 4, 5 }; int k = 5; int n = sizeof(arr) / sizeof(arr[0]); findDistinctCount(arr, n, k); return 0; } |
Скачать Выполнить код
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
class Main { // Функция для определения количества различных элементов в каждом подмассиве // размера `k` в массиве public static void findDistinctCount(int[] arr, int k) { // рассматриваем каждый подмассив размера `k` for (int x = 0; x <= arr.length — k; x++) { // поддерживает счетчик различных элементов в текущем подмассиве int distinct = 0; // текущий подмассив формируется подмассивом `arr[x, x+k)` for (int i = x; i < x + k; i++) { // увеличить количество различных элементов для `arr[i]` в текущем подмассиве distinct++; // проверяем, присутствует ли `arr[i]` в подмассиве `arr[x, i-1]` или нет for (int j = x; j < i; j++) { // если в текущем подмассиве найден повторяющийся элемент if (arr[i] == arr[j]) { // снимите пометку с элемента `arr[i]` как отдельный – уменьшите количество distinct—; break; } } } System.out.printf(«The count of distinct elements in subarray [%d, %d]» + » is %dn», x, x + k — 1, distinct); } } public static void main(String[] args) { int[] arr = { 2, 1, 2, 3, 2, 1, 4, 5 }; int k = 5; findDistinctCount(arr, k); } } |
Скачать Выполнить код
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# Функция для определения количества различных элементов в каждом подсписке # размера `k` в списке def findDistinctCount(A, k): # рассматривает каждый подсписок размера `k` for x in range(len(A) — k + 1): # поддерживает счетчик отдельных элементов в текущем подсписке. distinct = 0 # текущий подсписок формируется из подсписка `A[x, x+k)` for i in range(x, x + k): # увеличить количество различных для `A[i]` в текущем подсписке distinct = distinct + 1 # проверяет, присутствует ли `A[i]` в подсписке `A[x, i-1]` или нет for j in range(x, i): # Если в текущем подсписке найден повторяющийся элемент if A[i] == A[j]: # снять пометку с элемента `A[i]` как отдельный – уменьшить количество distinct = distinct — 1 break print(«The count of distinct elements in sublist», f«[{x}, {x + k — 1}] is {distinct}») if __name__ == ‘__main__’: A = [2, 1, 2, 3, 2, 1, 4, 5] k = 5 findDistinctCount(A, k) |
Скачать Выполнить код
Output:
The count of distinct elements in subarray [0, 4] is 3
The count of distinct elements in subarray [1, 5] is 3
The count of distinct elements in subarray [2, 6] is 4
The count of distinct elements in subarray [3, 7] is 5
Мы знаем, что множество не хранит повторяющихся элементов. Мы можем воспользоваться этим фактом и вставить все элементы текущего подмассива в набор. Тогда размер набора будет равен количеству отдельных элементов. Это снижает временную сложность до O(n.k) но использует O(k) дополнительное пространство.
Алгоритм может быть реализован следующим образом на C++, Java и Python. Мы можем даже расширить решение для печати содержимого набора, как показано здесь.
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include <iostream> #include <vector> #include <unordered_set> using namespace std; // Функция для поиска всех различных элементов, присутствующих в каждом подмассиве // размером `k` в массиве void findDistinctCount(vector<int> const &input, int k) { // цикл по вектору for (int i = 0; i < input.size() — (k — 1); i++) { unordered_set<int> distinct(input.begin() + i, input.begin() + i + k); cout << «The count of distinct elements in subarray [« << i << «, « << (i + k — 1) << «] is « << distinct.size() << endl; } } int main() { vector<int> input = { 2, 1, 2, 3, 2, 1, 4, 5 }; int k = 5; findDistinctCount(input, k); return 0; } |
Скачать Выполнить код
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; class Main { // Функция для поиска всех различных элементов, присутствующих в каждом подмассиве // размера `k` в массиве public static void findDistinctCount(List<Integer> input, int k) { // цикл по списку for (int i = 0; i < input.size() — (k — 1); i++) { Set<Integer> distinct = new HashSet<>(); distinct.addAll(input.subList(i, i + k)); System.out.println(«The count of distinct elements in « + «subarray [« + i + «, « + (i + k — 1) + «] is « + distinct.size()); } } public static void main(String[] args) { List<Integer> input = Arrays.asList( 2, 1, 2, 3, 2, 1, 4, 5 ); int k = 5; findDistinctCount(input, k); } } |
Скачать Выполнить код
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# Функция для поиска всех отдельных элементов, присутствующих в каждом подсписке. # размера `k` в списке def findDistinctCount(A, k): # цикл по списку for i in range(len(A) — (k — 1)): distinct = set(A[i:i+k]) print(f«The count of distinct elements in sublist [{i}, {(i + k — 1)}] is», len(distinct)) if __name__ == ‘__main__’: input = [2, 1, 2, 3, 2, 1, 4, 5] k = 5 findDistinctCount(input, k) |
Скачать Выполнить код
Output:
The count of distinct elements in subarray [0, 4] is 3
The count of distinct elements in subarray [1, 5] is 3
The count of distinct elements in subarray [2, 6] is 4
The count of distinct elements in subarray [3, 7] is 5
Мы можем дополнительно уменьшить временную сложность до O(n) с помощью раздвижное окно техника. Идея состоит в том, чтобы сохранить частоту элементов в текущем окне на карте и отслеживать количество отдельных элементов в текущем окне (размером k
). Код можно оптимизировать для получения количества элементов в любом окне, используя количество элементов в предыдущем окне, вставляя новый элемент в предыдущее окно справа и удаляя элемент слева.
Ниже приведена программа на C++, Java и Python, которая демонстрирует это:
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#include <iostream> #include <vector> #include <unordered_map> #include <unordered_set> using namespace std; // Функция для определения количества различных элементов в каждом подмассиве // размером `k` в массиве void findDistinctCount(vector<int> const &input, int k) { // карта для хранения частоты элементов в текущем окне размером `k` unordered_map<int, int> freq; // поддерживает количество различных элементов в каждом подмассиве размера `k` int distinct = 0; // цикл по массиву for (int i = 0; i < input.size(); i++) { // игнорируем первые `k` элементов if (i >= k) { // удалить первый элемент из подмассива, уменьшив его // частота на карте freq[input[i — k]]—; // уменьшаем количество различных, если осталось 0 if (freq[input[i — k]] == 0) { distinct—; } } // добавляем текущий элемент в подмассив, увеличивая его // количество на карте freq[input[i]]++; // увеличиваем счетчик уникальных элементов на 1, если элемент встречается первым // время в текущем окне if (freq[input[i]] == 1) { distinct++; } // вывести количество различных элементов в текущем подмассиве if (i >= k — 1) { cout << «The count of distinct elements in subarray [« << (i — k + 1) << «, « << i << «]» << » is « << distinct << endl; } } } int main() { vector<int> input = { 1, 1, 2, 1, 3 }; int k = 3; findDistinctCount(input, k); return 0; } |
Скачать Выполнить код
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
import java.util.HashMap; import java.util.Map; class Main { // Функция для определения количества различных элементов в каждом подмассиве // размера `k` в массиве public static void findDistinctCount(int[] A, int k) { // карта для хранения частоты элементов в текущем окне размером `k` Map<Integer, Integer> freq = new HashMap<>(); // поддерживает количество различных элементов в каждом подмассиве размера `k` int distinct = 0; // цикл по массиву for (int i = 0; i < A.length; i++) { // игнорируем первые `k` элементов if (i >= k) { // удалить первый элемент из подмассива, уменьшив его // частота на карте freq.put(A[i — k], freq.getOrDefault(A[i — k], 0) — 1); // уменьшаем количество различных, если осталось 0 if (freq.get(A[i — k]) == 0) { distinct—; } } // добавляем текущий элемент в подмассив, увеличивая его // количество на карте freq.put(A[i], freq.getOrDefault(A[i], 0) + 1); // увеличиваем счетчик уникальных элементов на 1, если элемент встречается первым // время в текущем окне if (freq.get(A[i]) == 1) { distinct++; } // вывести количество различных элементов в текущем подмассиве if (i >= k — 1) { System.out.println(«The count of distinct elements in subarray [« + (i — k + 1) + «, « + i + «]» + » is « + distinct); } } } public static void main(String[] args) { int[] input = { 1, 1, 2, 1, 3 }; int k = 3; findDistinctCount(input, k); } } |
Скачать Выполнить код
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# Функция для определения количества различных элементов в каждом подсписке # размера `k` в списке def findDistinctCount(A, k): # Словарь # для хранения частоты элементов в текущем окне размером `k` freq = {} # поддерживает количество отдельных элементов в каждом подсписке размера `k`. distinct = 0 # цикл по списку for i in range(len(A)): # игнорирует первые `k` элементов if i >= k: # удалить первый элемент из подсписка, уменьшив его # Частота # в словаре freq[A[i — k]] -= 1 # уменьшает количество различных, если у нас осталось 0 if freq.get(A[i — k]) == 0: distinct = distinct — 1 # добавить текущий элемент в подсписок, увеличив его # Количество # в словаре freq[A[i]] = freq.get(A[i], 0) + 1 # увеличивает количество уникальных элементов на 1, если элемент встречается в первый раз. # время в текущем окне if freq.get(A[i]) == 1: distinct = distinct + 1 # вывести количество различных элементов в текущем подсписке if i >= k — 1: print(«The count of distinct elements in sublist», f«[{(i — k + 1)}, {i}] is {distinct}») if __name__ == ‘__main__’: input = [1, 1, 2, 1, 3] k = 3 findDistinctCount(input, k) |
Скачать Выполнить код
Output:
The count of distinct elements in subarray [0, 2] is 2
The count of distinct elements in subarray [1, 3] is 2
The count of distinct elements in subarray [2, 4] is 3