Russian Qt Forum
Ноябрь 26, 2024, 02:48 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Организация произвольного построчного чтения  (Прочитано 19190 раз)
Spark
Гость
« : Июль 19, 2013, 10:17 »

Создаю слайдшоу. Имена карточек берутся из списка по порядку, построчно - http://www.prog.org.ru/topic_25276_15.html

Необходимо организовать режим Random (случайное чтение), учитывая, что список может быть большим (тысяч сто). Т.е список надо перемешать и затем выдавать по порядку (что бы не было повторов).
Подскажите как это организовать?
Рад любой помощи.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Июль 19, 2013, 12:01 »

1) быстрый способ: засунуть строки в хэш или множество и извлекать оттуда, получится такой себе не очень рандомный рандом
2) нормальный способ: генерировать случайный индекс через qrand(), извлекать по нему строку, помещать индекс во множество для проверки уникальности
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Июль 19, 2013, 12:58 »

2) нормальный способ: генерировать случайный индекс через qrand(), извлекать по нему строку, помещать индекс во множество для проверки уникальности
Проще перемешать сами элементы контейнера напр
Код
C++ (Qt)
QStringList lst;
...
for (int i = 0; i < lst.size(); ++i)
lst.swap(qrand() % lst.size(), qrand() % lst.size());
 
А потом брать подряд
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #3 : Июль 19, 2013, 13:57 »

Код
C++ (Qt)
QStringList list;
...
std::random_shuffle(list.begin(), list.end());
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #4 : Июль 19, 2013, 13:59 »

да уж, надо изучить STL получше
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Июль 19, 2013, 14:12 »

Код
C++ (Qt)
QStringList list;
...
std::random_shuffle(list.begin(), list.end());
 
Это заметно хуже предыдущего варианта (см описание QList::swap)
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #6 : Июль 19, 2013, 14:35 »

Код
C++ (Qt)
QStringList list;
...
std::random_shuffle(list.begin(), list.end());
 
Это заметно хуже предыдущего варианта (см описание QList::swap)

Это Ваше очередное заблуждение..

Давайте посмотрим на тесты:

Код
C++ (Qt)
#include <iostream>
#include <list>
#include <algorithm>
#include <QStringList>
#include <ctime>
#include <chrono>
 
template <unsigned N>
void initList(QStringList & list) {
   for (unsigned i = 0; i < N; ++i) {
       list << QString::number(i);
   }
}
 
int main()
{
 
   using namespace std::chrono;
   const unsigned Num = 1000000;
 
   QStringList list;
 
   initList<Num>(list);
 
   high_resolution_clock::time_point t1 = high_resolution_clock::now();
   std::random_shuffle(list.begin(), list.end());
   high_resolution_clock::time_point t2 = high_resolution_clock::now();
 
   duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
   std::cout << "random_shuffle: " << time_span.count() << " seconds." << std::endl;
 
   t1 = high_resolution_clock::now();
   for (int i = 0; i < list.size(); ++i) {
       list.swap(qrand() % list.size(), qrand() % list.size());
   }
   t2 = high_resolution_clock::now();
 
   time_span = duration_cast<duration<double>>(t2 - t1);
   std::cout << "igors: " << time_span.count() << " seconds." << std::endl;
 
 
   return 0;
}
 

Результаты у меня такие (3 испытания)
Код
Bash
random_shuffle: 0.172468 seconds.
igors: 0.403365 seconds.
 
random_shuffle: 0.1679 seconds.
igors: 0.350107 seconds.
 
random_shuffle: 0.162135 seconds.
igors: 0.362432 seconds.
 

Результаты ясно говорят, что random_shuffle эффективнее более чем в два раза..
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Июль 19, 2013, 14:53 »

Результаты ясно говорят, что random_shuffle эффективнее более чем в два раза..
А время на изучение почему ваш тест не выводит, так сказать на поиск и рыскатню? Улыбающийся
« Последнее редактирование: Июль 19, 2013, 14:59 от Old » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #8 : Июль 19, 2013, 15:03 »

Результаты ясно говорят, что random_shuffle эффективнее более чем в два раза..
А время на изучение почему ваш тест не выводит, так сказать на поиск и рыскатню? Улыбающийся

 Смеющийся
Моё лицо упало на пол, потом я долго долго плакал)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Июль 19, 2013, 15:09 »

Результаты ясно говорят, что random_shuffle эффективнее более чем в два раза..
У меня др результаты (gcc/icc практически одинаковы)
Цитировать
random_shuffle: 298 ms.
igors: 126 ms.
Немного изменил Ваш пример т.к. не имею С++ 11. На всякий случай вот полный текст
Код
C++ (Qt)
#include <iostream>
#include <algorithm>
#include <QtGUI>
 
template <unsigned N>
void initList(QStringList & list) {
   for (unsigned i = 0; i < N; ++i) {
       list << QString::number(i);
   }
}
 
int main()
{
   const unsigned Num = 1000000;
   QStringList list;
   initList<Num>(list);
 
   QTime t1 = QTime::currentTime();
   std::random_shuffle(list.begin(), list.end());
   std::cout << "random_shuffle: " << t1.elapsed() << " ms." << std::endl;
 
   t1 = QTime::currentTime();
   for (int i = 0; i < list.size(); ++i)
list.swap(i, qrand() % list.size());
   std::cout << "igors: " << t1.elapsed() << " ms." << std::endl;
 
   return 0;
}
 
Перемещать данные не есть хорошо/грамотно - нужно перемещать указатели. И здесь еще так-сяк с имплисит шарой
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #10 : Июль 19, 2013, 15:16 »

С Вашим модифицированным вариантом результаты у меня:

Код
Bash
random_shuffle: 163 ms.
igors: 229 ms.
 
random_shuffle: 159 ms.
igors: 229 ms.
 
random_shuffle: 192 ms.
igors: 233 ms.
 

gcc 4.6.3

Architecture:               x86_64
CPU(s):                      1
On-line CPU(s) list:     0
Thread(s) per core:      1
Vendor ID:                  AuthenticAMD
CPU MHz:                  1808.327




« Последнее редактирование: Июль 19, 2013, 15:33 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Июль 19, 2013, 15:33 »

С Вашим модифицированным вариантом результаты у меня:
Непонимающий Не знаю. Я уже и тесты поменял местами, добавил srand и qsrand - все то же самое gcc/icc 32/64. debug/release. Вот последний вариант (хотя принципиальной разницы никакой)
Код
C++ (Qt)
#include <iostream>
#include <algorithm>
#include <QtGUI>
 
template <unsigned N>
void initList(QStringList & list) {
   for (unsigned i = 0; i < N; ++i) {
       list << QString::number(i);
   }
}
 
int main()
{
   const unsigned Num = 1000000;
   QStringList list;
   initList<Num>(list);
   qsrand(0);
 
   QTime t2 = QTime::currentTime();
   for (int i = 0; i < list.size(); ++i)
list.swap(i, qrand() % list.size());
   std::cout << "igors: " << t2.elapsed() << " ms." << std::endl;
 
   srand(0);
   QTime t1 = QTime::currentTime();
   std::random_shuffle(list.begin(), list.end());
   std::cout << "random_shuffle: " << t1.elapsed() << " ms." << std::endl;
 
   return 0;
}
 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #12 : Июль 19, 2013, 15:35 »

А версии и разработчики stl думаю отличаются существенно. У вас даже стандарты разные.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Июль 19, 2013, 16:41 »

Проверил у себя, последний тест:
Код:
igors: 83 ms.
random_shuffle: 59 ms.

g++ (GCC) 4.8.1

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    1
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             AuthenticAMD
CPU family:            16
Model:                 4
Model name:            AMD Phenom(tm) II X4 945 Processor
Stepping:              2
CPU MHz:               800.000
BogoMIPS:              6030.87
Virtualization:        AMD-V
L1d cache:             64K
L1i cache:             64K
L2 cache:              512K
L3 cache:              6144K
NUMA node0 CPU(s):     0-3
Записан
Spark
Гость
« Ответ #14 : Июль 19, 2013, 17:18 »

Спасибо за помощь.
Понял пока только  в каком направлении двигаться, остальное не понял Улыбающийся. Но наверное на изучение вопроса придется потратить ночь.
Из того, что понял.
- Надо создать:
Код
C++ (Qt)
QStringList lst;
- Далее каким то образом перетащить в него все пункты с текстового файла.
- Затем перемешать:
Код
C++ (Qt)
for (int i = 0; i < lst.size(); ++i)
lst.swap(qrand() % lst.size(), qrand() % lst.size());

В списке (колонке) 100.000 пунктов. Тормозить не будет?
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.225 секунд. Запросов: 22.