Подскажите, как наиболее красиво рандомизировать вызов функций

Тема в разделе "LANGS.C", создана пользователем dyn, 16 ноя 2009.

  1. dyn

    dyn New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2009
    Сообщения:
    566
    Привет
    Задача такая
    есть 10 функций.

    Нужно рандомизировать последовательность их вызовов.

    т.е. нужна функция, которая сперва составит список, в какой последовательности их будет вызывать, а потом вызовет их.

    Пока что ничего кроме ифов в голову не приходит. Но тогда размер кода какой-то большой, а сам код похож на быдлокод.

    Сейчас вот хочу это как-то с помощью таблиц организовать. Но не знаю как. Чтобы например было 10 указателей. И чтобы можно было вызвать функцию, чтобы работала подсветка при этом и т.д. и т.п.

    Подскажите, как подобное реализовать наиболее красиво с наименьшими затратами
     
  2. o14189

    o14189 New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    320
    а в чем проблема то? что-то ты совсем расслабился
     
  3. dyn

    dyn New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2009
    Сообщения:
    566
    o14189
    ну на данном этапе реализовал вот так

    struct
    {
    PVOID pfunc;
    int func_type;
    } function_data;

    и далее массив типов.

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

    Может можно как-то красивее реализовать?
     
  4. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    ну во-первых ты уточни - у тебя к каждой из функций входные данные идут, и разные ли они, если таки идут;
    во-вторых - очень неожиданно, конечно, прозвучало и окончательно запутало "чтобы работала подсветка".

    насколько я понял, у тебя в коде будет примерно(простите мою помесь синтаксисов)
    Код (Text):
    1. .AAAAA:   procedure1(param1,param2);
    2. .AAAAX:   jmp _next;
    3. .BBBBB:   procedure2(pararam1);
    4. .BBBBX:   jmp _next;
    5. .CCCCC:   procedure3();
    6. .CCCCX:   jmp _next;
    7. .DDDDD:   procedure4(param,pam,pam);
    8. .DDDDX:   jmp _next;
    и в список ты хочешь заталкивать вразброс примерно так вот
    Код (Text):
    1. list[0] ¦ .CCCCC
    2. list[1] ¦ .BBBBB
    3. list[2] ¦ .DDDDD
    4. list[3] ¦ .AAAAA
    а потом его вызывать примерно так
    Код (Text):
    1. for(i=0;i<4;i++) {
    2.   jmp list[i];
    3.   _next:
    4. }
    /да, изложено всё весьма коряво, так что если где-то накосячил - спишите на состояние/

    ну если я правильно тебя понял, и ты хотел сделать что то такое, то я не знаю чего ты тормозишь, ты ведь уже всё сам продумал .)
     
  5. dyn

    dyn New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2009
    Сообщения:
    566
    Торможу :) сенкс
    так и сделаю ... сонный уже. 22 часа за монитором
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    switch/case?
     
  7. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    да вариантов море. от простого заталкивания в стек в случайном порядке параметров и адресов ваших тасуемых функций. а потом ret (в начале надо затолкнуть адрес куда вернуться должно). до сложных автоматов и виртуальных машин
     
  8. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    typedef boost::function<интерфейс> function;
    typedef std::vector<function> container;

    container cnt;

    ...заполняем...

    std::random_shuffle(cnt.begin(), cnt.end());

    вызываем.
     
  9. maksim_

    maksim_ New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2009
    Сообщения:
    263
    я бы сделал таблицку, а потом искал бы индекс, типа rand() % table_size - ни одного ифа.
     
  10. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    rand() % table_size не гарантирует что будет вызвана каждая функция и по одному разу. "перемешивание" таблицы рулит.
     
  11. iamlamer

    iamlamer New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2005
    Сообщения:
    273
    Адрес:
    Russia
    Рулит не перемешивание функций, а линейно-конгруэнтный датчик псевдослучайных чисел: r(i+1)=(r(i)*A+B) mod M. При правильных A, B, M метод гарантирует каждое число в интервале до M по одному разу.
     
  12. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Остаётся сравнить сложность реализации, включая доказательство правильности A, B, M :)
     
  13. iamlamer

    iamlamer New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2005
    Сообщения:
    273
    Адрес:
    Russia
    Нечего доказывать, Кнут все уже 40 лет назад доказал. А реализация, например, для a=1, b=7, m=10 вот:

    r = ( r + 7 )%10;

    Проверяем:
    r = 5; /* Затравка */
    for (i=0; i<10;i++) {
    r = ( r + 7 )%10;
    printf("%u ", r);
    }

    2 9 6 3 0 7 4 1 8 5

    Нужна другая последовательность?
    Меняем затравку r=6, имеем: 3 0 7 4 1 8 5 2 9 6
    Или меняем параметры датчика b = 3, получаем: 8 1 4 7 0 3 6 9 2 5

    Чего уж проще? Фактически, одна строка! :)
     
  14. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Одна строка это random_shuffle. В твоем случае надо добавить комментарий со ссылкой на Кнута, и тесты, которые проверят, что ничего не сломается если кто-то инициативный исправит меджики или формулу.
     
  15. iamlamer

    iamlamer New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2005
    Сообщения:
    273
    Адрес:
    Russia
    Ссылку на Кнута? Увольте.
    Если не знаете, кто это такой, то есть <a href="http://ru.wikipedia.org/wiki/%D0%9A%D0%BD%D1%83%D1%82_%D0%94.">Википедия</a>.
    Если не знаете, откуда скачать, есть <a href="http://www.google.ru/search?q=Кнут+Скачать">Гугль</a>.
    Формула стандартная. Правила выбора меджиков как раз Кнут и обосновал.
     
  16. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Мне ссылку на Кнута не надо, ее нужно поместить в исходник. Посмотри сколько ответов, и сколько знает про такой генератор. Посмотри на совет с rand(). Подумай, что может произойти через год, когда код будут поддерживать другие люди, не такие хорошие алгоритмисты, как ты. Только не пользуйся при этом той "логикой", по которой из моих слов следует, что этот генератор выдает повторы :)
     
  17. iamlamer

    iamlamer New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2005
    Сообщения:
    273
    Адрес:
    Russia
    Вообще-то, про то, как генерируются случайные числа, любой кодер должен просто знать. Это матчасть. И про то, что rand() в языке Си устроен именно по Кнуту, тоже иметь в виду не мешало бы. См. в Википедии "Линейный конгруэнтный метод" и требования "ANSI X3.159-1989".

    Ну, а если матчасть по боку, а забивание гвоздей микроскопами рулит, тогда я просто развожу руками и удаляюсь из топика. :dntknw:

    Удачи.
     
  18. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Если пытаешься тыкать носом в стандарт, будь добр сам с ним предварительно ознакомиться.

    ISO/IEC 9899:1999

    7.20.2.1 The rand function
    Synopsis
    1 #include <stdlib.h>
    int rand(void);
    Description
    2 The rand function computes a sequence of pseudo-random integers in the range 0 to RAND_MAX.
    3 The implementation shall behave as if no library function calls the rand function.
    Returns
    4 The rand function returns a pseudo-random integer.
    Environmental limits
    5 The value of the RAND_MAX macro shall be at least 32767.
     
  19. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    _DEN_, самый нормальный и гибкий способ предложил.

    Я бы посмотрел на методы остальных, когда понадобится обрабатывать возвращаемое значение этих функций с разными типами, да ещё и количество параметров и их количество будет варьироваться.

    Вот готовый код:

    Код (Text):
    1. typedef boost::function<boost::any()> Function;
    2. vector<Function> handlers;
    3. handlers.push_back(boost::bind(&f0, "Hello", 11));
    4. handlers.push_back(boost::bind(&f1, 12.0, true));
    5. ...
    6. handlers.push_back(boost::bind(&f10, p1, ..., pn));
    7.  
    8. std::random_shuffle(handlers.begin(), handlers.end());
    9.  
    10. BOOST_FOREACH(Function f, handlers)
    11. {
    12.    f();
    13. }
     
  20. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    >> и их количество
    типы