Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Посчитать, одинаковые элементы 
V
    Опции темы
antonkonikov
Дата 11.5.2010, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 56
Регистрация: 22.3.2009
Где: Украна, Донецк

Репутация: нет
Всего: нет



Как посчитать количество повторяющихся элементов в массиве? Пример (1,2,3,4,5,6,7,8,9,1,2,4,6,8,2,1)
1-3 раза
2-2 раза
3-1 раз
4-2 раза и т.д.
Только чтобы не повторялись числа массива на выходе.
PM MAIL WWW ICQ   Вверх
baldina
Дата 11.5.2010, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



если диапазон чисел невелик, например от 0 до 10, то быстрее всего будет работать массив счётчиков, i-й эелмент которого содержит число повторений числа i:

Код

int array[] = {1,2,3,4,5,6,7,8,9,1,2,4,6,8,2,1};
const int num = sizeof array / sizeof array[0];

int counters[10] = {0}; // изначально заполнен 0

for (int i=0; i < num; ++i)
  ++counters[ array[i] ];


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

Код

int array[] = {1,2,3,4,5,6,7,8,9,1,2,4,6,8,2,1};
const int num = sizeof array / sizeof array[0];

std::map <int,int> counters;

for (int i=0; i < num; ++i)
  ++counters[ array[i] ];


Это сообщение отредактировал(а) baldina - 11.5.2010, 19:14
PM MAIL   Вверх
azesmcar
Дата 11.5.2010, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



еще можно использовать битовый массив, для экономии памяти.
PM   Вверх
Abyx
Дата 11.5.2010, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 5
Всего: 10



Цитата(azesmcar @  11.5.2010,  20:06 Найти цитируемый пост)
битовый массив

что это?
PM MAIL   Вверх
azesmcar
Дата 11.5.2010, 20:34 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(Abyx @  11.5.2010,  20:32 Найти цитируемый пост)
что это? 

что-то вроде vector<bool> или bitset

Это сообщение отредактировал(а) azesmcar - 11.5.2010, 20:34
PM   Вверх
Abyx
Дата 11.5.2010, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 5
Всего: 10



azesmcar, а как это юзать в этой задаче?
PM MAIL   Вверх
azesmcar
Дата 11.5.2010, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



как-то так
Код

#include <iostream>
#include <vector>
#include <limits>

int main() 
{
    unsigned short data[] = {10, 30, 55, 771, 312, 21, 12, 30, 11, 5, 55, 31, 21};
    unsigned short size = sizeof(data) / sizeof(short);
    unsigned short count = 0;
    std::vector<bool> bits(USHRT_MAX);
    for (int i = 0; i < size; ++i)
    {
        if (!bits[data[i]])
            bits[data[i]] = true;
        else
            ++count;
    }
    std::cout << count << std::endl;
}

ну и уже результат записывать куда угодно, map наверно удобнее всего.

Это сообщение отредактировал(а) azesmcar - 11.5.2010, 21:06
PM   Вверх
Abyx
Дата 11.5.2010, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 5
Всего: 10



azesmcar, это сумма повторов элементов, ТСу надо не это

алсо ваш код мне чем-то напомнил примеры по C#, там где if(cond)return true; else return false;

Код

     for (int i = 0; i < size; ++i)
    {
        count += bits[data[i]] ? 1 : 0;
        bits[data[i]] = true;
    }

PM MAIL   Вверх
azesmcar
Дата 11.5.2010, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(Abyx @  11.5.2010,  21:42 Найти цитируемый пост)
azesmcar, это сумма повторов элементов, ТСу надо не это

во первых
Цитата

Как посчитать количество повторяющихся элементов в массиве?

во вторых это не сложно его переделать. Я показал метод нахождения повторов, остальное можно додумать.
если использовать для поиска повторов к примеру map - для каждого элемента будет произведен поиск, что замедлит программу, в случае с массивом (т.е. использования значения как индекс, см. пример 1 baldina) поиск будет константным, но и занимать будет немало памяти, это как бы альтернатива. А хранить повторы и их количества можно в map-е, повторов будет меньше чем элементов массива.

Цитата(Abyx @  11.5.2010,  21:42 Найти цитируемый пост)
алсо ваш код мне чем-то напомнил примеры по C#, там где if(cond)return true; else return false;

совершенно непохоже, это дело вкуса, мне так не нравиться.

Это сообщение отредактировал(а) azesmcar - 11.5.2010, 22:32
PM   Вверх
Abyx
Дата 11.5.2010, 23:19 (ссылка)    | (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 5
Всего: 10



azesmcar, во первых читайте текст 1го поста полностью, ТС написал что на входе, а что на выходе.

Во-вторых, как я понял, у вас все повторы хранятся в одной переменной - count,
как туда прикрутить map, чтобы получить для каждого значения свой счетчик?
PM MAIL   Вверх
azesmcar
Дата 12.5.2010, 06:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(Abyx @  11.5.2010,  23:19 Найти цитируемый пост)

Во-вторых, как я понял, у вас все повторы хранятся в одной переменной - count,
как туда прикрутить map, чтобы получить для каждого значения свой счетчик?

Я и не решал задачу автора, я показывал как найти повторения. Это пример поиска ПОВТОРЕНИЙ, прикрутиь сюда map очень просто, хранить ИМЕННО ПОВТОРЕНИЯ и их количества в map, их можно хранить в чем угодно, хоть в файле, сложность задачи - найти повторения и задача решена, а как организовать хранения нужных ДЛЯ ВЫВОДА данных - это другой вопрос. Сделаем проще, напишите свой вариант решения задачи автора.

Это сообщение отредактировал(а) azesmcar - 12.5.2010, 08:34
PM   Вверх
baldina
Дата 12.5.2010, 18:23 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



azesmcar, на спичках экономите, а исходная задача ТС так Вами и не решена smile  (надо найти не вообще повторения, а повторения каждого элемента множества, из постановки это ясно).

Код

 if (!bits[data[i]])
            bits[data[i]] = true;


Согласен с Abyx, это масло масляное. Эквивалент
Код

bits[data[i]] = true;

PM MAIL   Вверх
azesmcar
Дата 12.5.2010, 19:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(baldina @  12.5.2010,  18:23 Найти цитируемый пост)
azesmcar, на спичках экономите

во первых я не предлагал экономить и не говорил что предложенный вами вариант ошибочен, я предложил еще один способ нахождения повторений, во вторых, это не спички а память, если в массиве не 10 элементов а несколько миллиардов - экономия получается достаточно серьезная, вместо 1-байта используется 1 бит а поиск остается константным, экономия в 8 раз не шутки. Вам никогда не приходилось писать задачи под слабые процессоры или машины с малым количеством памяти?

Цитата(baldina @  12.5.2010,  18:23 Найти цитируемый пост)
а исходная задача ТС так Вами и не решена

я и не собирался, это не центр помощи, я не решал исходную задачу а предложил еще один вариант решения, или вы считаете что так задачу решить невозможно?

Цитата(baldina @  12.5.2010,  18:23 Найти цитируемый пост)
bits[data[i]] = true;

это не эквивалент, эквивалент написал Abyx, тут в любом случае нужна проверка повторился ли элемент, если проверка есть - тогда какой смысл присваивать еще раз? есть ли смысл говорить о том, что vector<bool> работает через proxy класс, которые совершает битовую операцию при присваивании? в чем смысл? выйграть пару строку кода, сделав код менее читабельным?

теперь о решении
для вывода повторяющихся значений в том виде, в котором вы предоставили решение ТС надо пройтись по всем элементам массива/map-а, и проверять кажый на предмет повторения, это я так полагаю не вариант, вам надо хранить повторения раздельно, т.е. в отдельном map-е, получается используется map/vector для нахождения повторов и повторы заносяться в отдельный map, в чем же разница? это все я говорю с учетом того, что в масиве пара миллиардов значений. Повторений среди них наверняка на порядок меньше.

Это сообщение отредактировал(а) azesmcar - 12.5.2010, 19:18
PM   Вверх
Abyx
Дата 12.5.2010, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 5
Всего: 10



Цитата(azesmcar @  12.5.2010,  19:11 Найти цитируемый пост)
если проверка есть - тогда какой смысл присваивать еще раз?

если bits[data[i]] в любом случае должен быть true, то зачем чтото проверять?
так и пишите, bits[data[i]] = true;

(и это существенно эффективнее на уровне асма)
PM MAIL   Вверх
azesmcar
Дата 12.5.2010, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(Abyx @  12.5.2010,  19:54 Найти цитируемый пост)

если bits[data[i]] в любом случае должен быть true, то зачем чтото проверять?
так и пишите, bits[data[i]] = true;

(и это существенно эффективнее на уровне асма) 

затем, чтобы подсчитать сколько раз повторялось то или иное значение.

проведем небольшой эксперимент
через vector<bool>
Код

#include <iostream>
#include <vector>
#include <ctime>
#include <map>
#include <algorithm>

int main() 
{
    const int upto = 9999999;
    srand(time(0));
    std::vector<unsigned int> v(upto);
    std::map<unsigned int, unsigned int> r;
    std::vector<bool> bits(upto);

    std::generate(v.begin(), v.end(), rand);

    time_t start = time(0);
    for (auto it = v.begin(); it != v.end(); ++it)
    {
        if (!bits[*it])
            bits[*it] = true;
        else
            ++r.insert(std::map<unsigned int, unsigned int>::value_type(*it, 1)).first->second;
    }
    std::cout << time(0) - start << std::endl;
}

результат
Цитата

запуск #1 - 4
запуск #3 - 3
запуск #3 - 4
запуск #4 - 3
запуск #5 - 3
-----
среднее - 3,4


через set/map
Код

#include <iostream>
#include <vector>
#include <ctime>
#include <set>
#include <map>
#include <algorithm>

int main() 
{
    const int upto = 9999999;
    srand(time(0));
    std::vector<unsigned int> v(upto);
    std::map<unsigned int, unsigned int> r;
    std::set<unsigned int> bits;

    std::generate(v.begin(), v.end(), rand);

    time_t start = time(0);
    for (auto it = v.begin(); it != v.end(); ++it)
    {
        if (!bits.insert(*it).second)
            ++r.insert(std::map<unsigned int, unsigned int>::value_type(*it, 1)).first->second;
    }
    std::cout << time(0) - start << std::endl;
}

результат
Цитата

запуск #1 - 8
запуск #3 - 12
запуск #3 - 8
запуск #4 - 7
запуск #5 - 8
-----
среднее - 8,6

замена vector<bool> к примеру на vector<char> на скорость практически не влияет, зато на использование памяти влияет немало
9999999 байтов = 9.53Mb
9999999 битов = 1.19Mb
разница есть? экономия на спичках? а если в вашем распоряжении 64Mb оперативной памяти?

Это сообщение отредактировал(а) azesmcar - 12.5.2010, 20:12
PM   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0878 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.