Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
re-marka
0 / 0 / 0
Регистрация: 17.10.2011
Сообщений: 12
#1

Из некоторого непостоянного числа переменных одного типа выбрать случайную переменную - C++

19.10.2012, 14:41. Просмотров 559. Ответов 12
Метки нет (Все метки)

Такой вопрос.

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

Вот что написала, поискав в сети..

в заголовочном файле класса:

C++
1
2
template< class T > 
static T* selectRandomArgument(int num, T* first,...);
в cpp файле класса:

C++
1
2
3
4
5
6
7
template< class T > 
T* Util::selectRandomArgument(int num, T* first,...)
{
    T** poiner = &first;
    int rand = generateRandomIntegerValue(0, num);
    return *(poiner+rand);
}
не работает..
такая ошибка при вызове этой функции

C++
1
>AgentInfo.obj : error LNK2019: unresolved external symbol "public: static class std::vector<class std::vector<double,class std::allocator<double> >.....
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.10.2012, 14:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Из некоторого непостоянного числа переменных одного типа выбрать случайную переменную (C++):

Из одного созданного массива выбрать числа и записать их в новый массив - C++
Всем привет! Как из одного созданного массива выбрать числа и записать их в новый массив? вот задание &quot;сформировать новый массив,...

Перенос данных из переменной одного типа в переменную другого типа - Delphi
Добрый день! Одна часть программы размещает полученные данные(символы) в ПЕРЕМ1 типа ustring ( или string variant WideString), другие...

Использовать переменную(ссылочного типа) из одного метода в другом - C#
Требуется вытащить из Buttoun1_Click переменную FB, что бы использовать в Start_Click, т.к у меня там идет запрос в бд и всякая магия. ...

Подсчитать сумму элементов, больших по модулю некоторого заданного С, в последовательности чисел, используя одну переменную-указатель для след. числа - Pascal ABC
Подсчитать сумму элементов, больших по модулю некоторого заданного С, в последовательности вещественных чисел, используя одну...

Задать два множества А и В (одного и того же типа). Поменять местами значения А и В, не используя дополнительных переменных. - Pascal
Задать два множества А и В (одного и того же типа). Поменять местами значения А и В, не используя дополнительных переменных.

Как конвертировать переменную типа Double в переменную типа String? - Java
Как конвертировать переменную типа Double в переменную типа String. И наоборот.

12
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
19.10.2012, 14:47 #2
Для работы с переменным число аргументов нужен заголовочный файл <cstdarg>.
Ошибка которая у вас не понятно о чем, так как выведен не полный текст.
0
re-marka
0 / 0 / 0
Регистрация: 17.10.2011
Сообщений: 12
19.10.2012, 14:54  [ТС] #3
Цитата Сообщение от Герц Посмотреть сообщение
Для работы с переменным число аргументов нужен заголовочный файл <cstdarg>.
Ошибка которая у вас не понятно о чем, так как выведен не полный текст.
попробовала подключить, не помогло.
вот полный текст ошибки
если закомментить вызов функции этой, то все работает

а вообще по смыслу решение нормальное?

C++
1
>AgentInfo.obj : error LNK2019: unresolved external symbol "public: static class std::vector<class std::vector<double,class std::allocator<double> >,class std::allocator<class std::vector<double,class std::allocator<double> > > > * __cdecl Util::selectRandomArgument<class std::vector<class std::vector<double,class std::allocator<double> >,class std::allocator<class std::vector<double,class std::allocator<double> > > > >(int,class std::vector<class std::vector<double,class std::allocator<double> >,class std::allocator<class std::vector<double,class std::allocator<double> > > > *,...)" (??$selectRandomArgument@V?$vector@V?$vector@NV?$allocator@N@std@@@std@@V?$allocator@V?$vector@NV?$allocator@N@std@@@std@@@2@@std@@@Util@@SAPAV?$vector@V?$vector@NV?$allocator@N@std@@@std@@V?$allocator@V?$vector@NV?$allocator@N@std@@@std@@@2@@std@@HPAV12@ZZ) referenced in function "public: void __thiscall AgentInfo::addAndDeleteConections(class std::vector<int,class std::allocator<int> >,class std::vector<int,class std::allocator<int> >,double,double)" (?addAndDeleteConections@AgentInfo@@QAEXV?$vector@HV?$allocator@H@std@@@std@@0NN@Z)
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
19.10.2012, 15:09 #4
Так его не просто подключать, а использовать надо.
Функции с переменным числом параметров - зло.

Зачем в твоем методе второй параметр, каково его назначение?

Добавлено через 9 минут
Вот тебе пример:
http://liveworkspace.org/code/0a4cdca140f4417861a9a31c2250b2cf
0
re-marka
0 / 0 / 0
Регистрация: 17.10.2011
Сообщений: 12
19.10.2012, 15:10  [ТС] #5
Цитата Сообщение от Герц Посмотреть сообщение
Так его не просто подключать, а использовать надо.
Функции с переменным числом параметров - зло.

Зачем в твоем методе второй параметр, каково его назначение?
я не спец, но сейчас поясню, как я поняла из того что прочитала

передаваемые в функцию аргументы помещаются в стек, и к ним можно обратиться по указателю, если знать адрес первой переменной и ее тип (это для того, чтобы объявить сам указатель).
Для этого и передается второй параметр. Т.е. знаем адрес первого аргумента, прибавляем к указателю номер аргумента, получаем адрес n-того - к любому доступ имеем

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

как-то так.
0
soon
2542 / 1307 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
19.10.2012, 15:10 #6
re-marka, если тип одинаков для всех - засовывайте в контейнер. Если нет, то можно попробовать написать compile-time генератор рандомных чисел и использовать tuple. Либо так
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
#include <iostream>
#include <utility>
#include <random>
 
template <class T>
void show(T&& t)
{
    std::cout << std::forward<T>(t) << std::endl;
}
 
template <class T>
void show_random(T&& t)
{
    show(std::forward<T>(t));
}
 
template <class T, class... Args>
void show_random(T&& t, Args&&... args)
{
    if(std::random_device()() & 1)
        show(std::forward<T>(t));
    else
        show_random(std::forward<Args>(args)...);
}
 
int main()
{
    show_random(3.14, 42, 36, "Hi");
    return 0;
}
0
re-marka
0 / 0 / 0
Регистрация: 17.10.2011
Сообщений: 12
19.10.2012, 15:13  [ТС] #7
Цитата Сообщение от Герц Посмотреть сообщение
Функции с переменным числом параметров - зло.
мне просто нужно часто выбирать из 1-5 разных векторов или переменных других типов один случайный
как это лучше сделать?
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
19.10.2012, 15:13 #8
передаваемые в функцию аргументы помещаются в стек, и к ним можно обратиться по указателю, если знать адрес первой переменной и ее тип (это для того, чтобы объявить сам указатель).
Для этого и передается второй параметр. Т.е. знаем адрес первого аргумента, прибавляем к указателю номер аргумента, получаем адрес n-того - к любому доступ имеем
Это неверно, так как существуют разные соглашения о передаче параметров в процедуры.
мне просто нужно часто выбирать из 1-5 разных векторов или переменных других типов один случайный
как это лучше сделать?
http://liveworkspace.org/code/0a4cdca140f4417861a9a31c2250b2cf
Но лучше всего использовать контейнеры. Вы же все равно не сможете генерировать список параметров переменной длины прямо во время исполнения программы, это можно сделать лишь во время компиляции.
0
re-marka
0 / 0 / 0
Регистрация: 17.10.2011
Сообщений: 12
19.10.2012, 15:28  [ТС] #9
Цитата Сообщение от Герц Посмотреть сообщение
Это неверно, так как существуют разные соглашения о передаче параметров в процедуры.

http://liveworkspace.org/code/0a4cdca140f4417861a9a31c2250b2cf
спасибо за ссылку
попробую

Цитата Сообщение от Герц Посмотреть сообщение
Но лучше всего использовать контейнеры. Вы же все равно не сможете генерировать список параметров переменной длины прямо во время исполнения программы, это можно сделать лишь во время компиляции.
мне и не надо во время исполнения
просто у меня часто встречается такая ситуация, например v1, v2, v3 - разные векторы, хранятся в разных классах, нужно из них выбрать случайный
использовать контейнеры - это засовывать каждый раз все в вектор, генерить случайный индекс и по нему выбирать?
просто мне как раз в самом коде хотелось иметь простую функцию, в которую передаешь несколько адресов, а она выбирает один случайный, а не писать по сто раз одно и то же..

Добавлено через 45 секунд
Цитата Сообщение от soon Посмотреть сообщение
re-marka, если тип одинаков для всех - засовывайте в контейнер. Если нет, то можно попробовать написать compile-time генератор рандомных чисел и использовать tuple. Либо так
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
#include <iostream>
#include <utility>
#include <random>
 
template <class T>
void show(T&& t)
{
    std::cout << std::forward<T>(t) << std::endl;
}
 
template <class T>
void show_random(T&& t)
{
    show(std::forward<T>(t));
}
 
template <class T, class... Args>
void show_random(T&& t, Args&&... args)
{
    if(std::random_device()() & 1)
        show(std::forward<T>(t));
    else
        show_random(std::forward<Args>(args)...);
}
 
int main()
{
    show_random(3.14, 42, 36, "Hi");
    return 0;
}
Вам тоже спасибо )) попробую разобраться, так сходу сложно для меня.

Добавлено через 1 минуту
Цитата Сообщение от Герц Посмотреть сообщение
Это неверно, так как существуют разные соглашения о передаче параметров в процедуры.
а что именно неверно? т.е. для переменных одного типа, я по описанной мной схеме не смогу обратиться к произвольной?
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
19.10.2012, 15:33 #10
Т.е. знаем адрес первого аргумента, прибавляем к указателю номер аргумента, получаем адрес n-того - к любому доступ имеем
Откуда у вас уверенность, что нужно именно прибавлять?
Они вовсе не обязательно лежат там в таком же порядке, в котором вы их передаете в функцию.
0
re-marka
0 / 0 / 0
Регистрация: 17.10.2011
Сообщений: 12
19.10.2012, 19:56  [ТС] #11
Цитата Сообщение от Герц Посмотреть сообщение
Откуда у вас уверенность, что нужно именно прибавлять?
Они вовсе не обязательно лежат там в таком же порядке, в котором вы их передаете в функцию.
ну про такие тонкости я не знаю, прочитала, что лежат так
кстати, я проверила, действительно так и лежат.
а чего зависит, как они туда складываться будут? от компилятора? (может глупый вопрос..)

*
с проблемой разобралась, ошибка вообще не в этом была
мой вариант тоже работает.
всем спасибо.
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
19.10.2012, 20:01 #12
От компилятора, от системы, к примеру ms c++ compiler позволяет указывать всякие fastcall'ы и т.п., такие функции тоже будут передавать аргументы не так, как ты ожидаешь.

Лучше использовать тот вариант, который я выложил на LiveWorkspace, он хотя бы по стандарту. А твой нет )
1
re-marka
0 / 0 / 0
Регистрация: 17.10.2011
Сообщений: 12
19.10.2012, 20:04  [ТС] #13
Цитата Сообщение от Герц Посмотреть сообщение
От компилятора, от системы, к примеру ms c++ compiler позволяет указывать всякие fastcall'ы и т.п., такие функции тоже будут передавать аргументы не так, как ты ожидаешь.
понятно примерно.

Цитата Сообщение от Герц Посмотреть сообщение
Лучше использовать тот вариант, который я выложил на LiveWorkspace, он хотя бы по стандарту. А твой нет )
я его и использовала в итоге )
0
19.10.2012, 20:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.10.2012, 20:04
Привет! Вот еще темы с ответами:

Как вывести случайную переменную из массива(ТЕКСТ) - Turbo Pascal
Вот в чем проблема. Я пытался сделать следующее, взял переменную Text:String; Text = array of string; и дальше в бегине задал...

Выделение памяти для переменных./Как создать переменную Н-значного числа - PascalABC.NET
Здравствуйте! Такой вопрос, можно ли создать переменную, которая будет вмещать в себя данных столько, сколько я хочу? Например,...

Выбрать случайную букву русского алфавита - Lazarus
Если ли команда чтобы выбиралась рандомом любоя буква алфавита русского?

Описать функцию IsSquare (K) логического типа, возвращает True, если целый параметр K (> 0) является квадратом некоторого целого числа, и False в прот - C++ Builder
Описать функцию IsSquare (K) логического типа, возвращает True, если целый параметр K (&gt; 0) является квадратом некоторого целого числа, и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.