1

Тема: Заповнити чергу рандомними числами

Попередня назва: функція rand

Загалом, суть завдання полягає у тому, щоб заповнити чергу рандомними числами (велике число, 10 000+), використовуючи STL, виконати функції занесення елемента у чергу, вилучення елемента з черги, виведення кожного 1000 елемента екран. Проте функція заповнює лиш одним і тим самим числом, хоча в прикладах з інтернету все так само, як у цьому коді. В чому помилка?

#include <iostream>
#include <queue>
#define N 10000
using namespace std;

int main(void)
{
    setlocale(LC_ALL, "ukr");
    queue < int > ourQueue;
    cout << "Місце у пам'яті = " << ourQueue.size() << endl;
  
    for (int i = 0; i < N; i++) {
        ourQueue.push(rand());
    }

    cout << "Місце у пам'яті = " << ourQueue.size() << endl;
    cout << "І у байтах =" << ourQueue.size() * sizeof(int) << endl;

    for (int i = 0; i < 10; i++) {
        cout << ourQueue.front() << "\t";
    }

    while (!ourQueue.empty())
    {
        ourQueue.pop();
    }
    system("pause");
    
}

2

Re: Заповнити чергу рандомними числами

GROUND07 написав:

функція заповнює лиш одним і тим самим числом,

А як ви це перевіряєте? Якщо

for (int i = 0; i < 10; i++) {
        cout << ourQueue.front() << "\t";
    }

То тут ви 10 разів виводите перший елемент.

3 Востаннє редагувалося wander (26.05.2019 18:04:29)

Re: Заповнити чергу рандомними числами

GROUND07 написав:

Проте функція заповнює лиш одним і тим самим числом

Для того, щоб кожного разу видавало інші значення
потрібно обновляти значення seed для генератора
псевдовипадкових чисел, робится це функцією srand().

GROUND07 написав:

В чому помилка?

Основні ваші помилки в тому, що ви не задаєте
діапазон в якому мають генеруватися числа, а також
Ви вибрали не підходящий контейнер для "виведення"
елементів.
Ну, якось так це робиться:

Прихований текст
#include <iostream>
#include <cstdlib>
#include <queue>
#include <ctime>

std::size_t constexpr N = 5000;

int zrand() noexcept {
    [[maybe_unused]] static bool const seed 
        = (std::srand(std::time(nullptr)), true);
    return rand();
}

template <typename T>
void print_queue(std::queue<T> const& q) noexcept {
    struct hack : std::queue<T> {
        static int element(std::queue<T> const& q, std::size_t const i) {
            return (q.*&hack::c)[i];
        }
    };
    
    for (std::size_t i = 1000; i <= q.size(); i += 1000) {
            std::cout << hack::element(q, i) << '\n';
    }
}

int main() {
    std::queue<int> q;
    
    for (std::size_t i = 0; i <= N; ++i) {
        q.push(10'000 + zrand() % 10'001);
    }
    print_queue(q);
}

Перевірити можна тут https://wandbox.org/permlink/81Ck02PtUWFe2dHf

Подякували: leofun011

4

Re: Заповнити чергу рандомними числами

adziri написав:

Для того, щоб кожного разу видавало інші значення
потрібно обновляти значення seed для генератора
псевдовипадкових чисел, робится це функцією srand().

Навпаки. Значення seed треба виставляти один раз:
https://wandbox.org/permlink/Oqu2IZzOYgoeGKhz
якщо, звісно, вам не треба отримувати одну й ту саму послідовність псевдовипадкових чисел (це дозволяє, наприклад, зберігати одне число замість купи деталей у випадково створеному всесвіті).

adziri написав:

Основні ваші помилки в тому, що ви не задаєте діапазон в якому мають генеруватися числа

це не робить числа менш випадковими

adziri написав:

а також
Ви вибрали не підходящий контейнер для "виведення"
елементів.

Це не він обирав, в умові сказано "черга". Але в умові нічого не сказано про виведення перших 10 елементів, там треба, вочевидь, вилучити з черги всі числа і при цьому кожне 1000-е вивести.

Подякували: leofun011

5 Востаннє редагувалося wander (26.05.2019 21:20:18)

Re: Заповнити чергу рандомними числами

koala написав:

Навпаки. Значення seed треба виставляти один раз:

Не бачу, щоб я казав, що його потрібно виставляти
НЕ один раз?..

koala написав:

це не робить числа менш випадковими

Не робить, але умова - є умова.

GROUND07 написав:

заповнити чергу рандомними числами (велике число, 10 000+)

koala написав:

Це не він обирав, в умові сказано "черга".

Ем.. А умова не його? Чи скажете, що умову таку
задав викладач? Та, навіть у такому випадку це нічого не
змінює, а лише показує, некомпетентність останнього.

koala написав:

там треба, вочевидь, вилучити з черги всі числа і при цьому кожне 1000-е вивести.

Не бачу такої умови, тикнете пальцем де?
Вивести можна і не вилучаючи числа,
ви мій код дивились?

Подякували: leofun011

6

Re: Заповнити чергу рандомними числами

adziri написав:
koala написав:
adziri написав:

щоб кожного разу видавало інші значення
потрібно обновляти значення seed для генератора

Навпаки

Не бачу, щоб я казав, що його потрібно виставляти
НЕ один раз?..

Кожен раз ≠ один раз.
Ви, швидше за все, мали на увазі "кожен раз при початку роботи програми", але це можна прочитати і як "кожен раз перед викликом rand".

adziri написав:
koala написав:
adziri написав:

ви не задаєте діапазон

це не робить числа менш випадковими

Не робить, але умова - є умова.

В умові нічого не сказано про діапазон. Так, зручніше працювати з числами з відомого діапазону, але це не є помилкою чи невідповідністю умові.

adziri написав:

лише показує, некомпетентність останнього.

Не зрозумів, у чому саме некомпетентність?

adziri написав:
koala написав:

там треба, вочевидь, вилучити з черги всі числа і при цьому кожне 1000-е вивести.

Не бачу такої умови, тикнете пальцем де?

Це єдиний варіант, як можна зрозуміти ось це:

GROUND07 написав:

вилучення елемента з черги, виведення кожного 1000 елемента екран

adziri написав:

Вивести можна і не вилучаючи числа,

Але для цього знадобиться не черга, а якась інша структура даних. Ви користуєтеся тим, що стандартний queue використовує deque для зберігання даних; але ж ніхто не забороняє використати, наприклад, list: https://wandbox.org/permlink/82HWsN4iELPIX59x
Після чого ваш брудний хак тупо валить нормальний робочий код.
Черга - це структура, що допускає лише дві операції: зберегти і дістати. Якщо ви можете залізти всередину - це не черга.

Подякували: ReAl1

7

Re: Заповнити чергу рандомними числами

Ну і взагалі якщо вже використовувати C++11 і вище, то треба не std::rand брати, а <random>.

Подякували: leofun011

8

Re: Заповнити чергу рандомними числами

rand() Considered Harmful

9

Re: Заповнити чергу рандомними числами

koala написав:

Черга - це структура, що допускає лише дві операції: зберегти і дістати. Якщо ви можете залізти всередину - це не черга.

Саме так.
І навчальне завдання, як я розумію, було не тему черги як такої, а не прихованих можливостей конкретного втілення.

10

Re: Заповнити чергу рандомними числами

koala написав:

Ви, швидше за все, мали на увазі "кожен раз при початку роботи програми", але це можна прочитати і як "кожен раз перед викликом rand".

Гм, так, перечитав своє повідомлення і тут
погоджуся, що, здається, я не дуже ясно висловився.

koala написав:

В умові нічого не сказано про діапазон. Так, зручніше працювати з числами з відомого діапазону, але це не є помилкою чи невідповідністю умові.

В умові сказано, що випадкові числа мають бути
великими від 10.000 і більше чи я чогось не зрозумів?

koala написав:

Не зрозумів, у чому саме некомпетентність?

koala написав:

Але для цього знадобиться не черга, а якась інша структура даних.

Ось про це і казав. Якщо ТС новачок, то дане
завадання ніяким чином не дає зрозуміти для чого
потрібна черга і коли її потрібно використовувати.

koala написав:

Ви користуєтеся тим, що стандартний queue використовує deque для зберігання даних; але ж ніхто не забороняє використати, наприклад, list: https://wandbox.org/permlink/82HWsN4iELPIX59x
Після чого ваш брудний хак тупо валить нормальний робочий код.

Абсолютна нісенітниця. Що ви намались цим довести?
Що якщо змінити внутрішній контейнер, то мій код поламається?
То я про це і без вас знаю.. У мому випадку нічого не ламається
і буде працювати всюди і завжди, звісно, допоки хтось не пхне
свої 5 копійок. А ви можете дати гарантію, що при будь-якому
використанні, ваш коде буде працювати, як ви очікували?
От ви будете робити так:

koala написав:

там треба, вочевидь, вилучити з черги всі числа і при цьому кожне 1000-е вивести.

але ніхто не забороняє мені такий код наприклад винести
у функцію і потім десь так може статися, що цю ф-ї викличуть
двічі і що ми отримаємо?..
Я веду до того, що не потрібно показувати і так очевидні речі,
чи намагати відтворити коня у вакуумі.

koala написав:

Ну і взагалі якщо вже використовувати C++11 і вище, то треба не std::rand брати, а <random>.

Для такого тривіального випадку, не смішіть..

ReAl написав:

І навчальне завдання, як я розумію, було не тему черги як такої, а не прихованих можливостей конкретного втілення.

Ось це ви називаєте навчальним завданням?
І чому ж воно навчає? Заганяти і видаляти елементи
з черги? Ммм..
І чим це відрізняється від того, щоб одразу вивести
випадкові числа?..

Подякували: leofun011

11

Re: Заповнити чергу рандомними числами

adziri написав:

В умові сказано, що випадкові числа мають бути великими від 10.000 і більше чи я чогось не зрозумів?

Я так зрозумів, що має бути велике число (10000+) випадкових чисел. Хоча погоджуюся, що можна було це чіткіше сказати.

adziri написав:

Якщо ТС новачок, то дане
завадання ніяким чином не дає зрозуміти для чого
потрібна черга і коли її потрібно використовувати.

Хочете сказати, що ваш приклад дає краще розуміння цього?

adziri написав:

Що ви намались цим довести?

Що ваш код не працює, коли виконується решта умов завдання. Якщо це черга за умовою — то це має бути черга.

adziri написав:

ніхто не забороняє мені такий код наприклад винести
у функцію і потім десь так може статися, що цю ф-ї викличуть
двічі і що ми отримаємо?..

При другому виклику не буде виведено нічого. Це очікувана від черги поведінка.

adziri написав:

Для такого тривіального випадку, не смішіть..

Це точно пише людина, яка написала оце?

    [[maybe_unused]] static bool const seed 
        = (std::srand(std::time(nullptr)), true);
adziri написав:

І чому ж воно навчає? Заганяти і видаляти елементи
з черги? Ммм..

Саме так.

adziri написав:

І чим це відрізняється від того, щоб одразу вивести
випадкові числа?..

Тим, що при цьому виникає купа додаткових питань, які ми тут розбираємо.

GROUND07, ви якось відпишіться - ви щось тут зрозуміли взагалі?

12 Востаннє редагувалося wander (27.05.2019 10:30:57)

Re: Заповнити чергу рандомними числами

koala написав:

Хочете сказати, що ваш приклад дає краще розуміння цього?

Ясно, що ні. Я і не намагався його дати.

koala написав:

Хочете сказати, що ваш приклад дає краще розуміння цього?

koala написав:

Це точно пише людина, яка написала оце?

Де я таке сказав? Чи ви шукаєте скритий підтекст
читаючи між рядків? =.=
Я навпаки сказав, що для цього випадку
черга не найкраща структура, з чим ви і почали
сперечатись.
Проте я показав, як можна це зробити, так,
деяким хаком, але ж можна. І ще раз я не
претендував на якусь правильність, просто показав
приклад. Зрештою, незнаю як вам, а мені
тим і подобається С++, що тут є такі хаки :)

koala написав:

Це точно пише людина, яка написала оце?

І якщо б автор спитав, що це і навіщо, я
б із задоволенням дав відповідь, я написав таку
складнішу штуку, щоб навпаки вивести ТСа на
діалог.

koala написав:

Саме так.

Ну дійсно, навіщо щось пояснювати, про струтури
даних, для чого вони і які проблеми покликані
вирішувати, звісно, краще, просто додавати і видаляти
елементи, при цьому навіть не показуючи як це відбувається
і чому це відбувається не так, як, наприклад, у векторі...
Типове навчання.

koala написав:

Тим, що при цьому виникає купа додаткових питань, які ми тут розбираємо.

Здається розбираємо лише ми з вами )

13 Востаннє редагувалося GROUND07 (28.05.2019 01:37:28)

Re: Заповнити чергу рандомними числами

Перепрошую за нечітке формулювання умови. Таки малось на увазі, що буде створено велику чергу з 10 000+ елементів та виводити кожен 1000 елемент на екран. Тому діапазон, в якому вибирати випадкові числа, не потрібен у даній задачі, проте дякую за додаткове пояснення

14

Re: Заповнити чергу рандомними числами

Але ви ж мали б вже зрозуміти, що виводити
елементи вам не вдастся (принаймні так, як
ви, напевне того очікували), адже черга не
надає можливості доступу напряму до довільного
елементу, інакше це б ламало сам сенс цієї
структури.

15

Re: Заповнити чергу рандомними числами

може вже тема зайшла далеко, але http://cppstudio.com/uk/post/339/
на С написав такий код

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
  int i;

  for(i=0; i<10; i++)
    printf("%d ", rand() % 10 + 1);

  return 0;
}

там уже вказаний діапазон, а обчислення йде з нуля, тому додається +1, там все написано