Забивка рендом
Спасибо.
Нужна максимально рациональная ф-ция, забивающая рендом (по модулю, например на 10) массив без повторений.
Спасибо.
Нужна. И что?
Пожалуйста.
Нужна максимально рациональная ф-ция, забивающая рендом (по модулю, например на 10) массив без повторений.Спасибо.
Используется т.н. линейный конгруэнтный метод. (Дядя Кнут. Иск.прог. Т.2)
X[n+1] = (a*X[n]+c) mod m
Для массива из 100 элементов,
напр. m = 100, c = 17, a = 21
================================
1) НОД(c,m) = 1 (т.е. c и m взаимно просты);
2) a - 1 кратно p для всех простых p - делителей m;
3) a - 1 кратно 4, если m кратно 4.
Используется т.н. линейный конгруэнтный метод. (Дядя Кнут. Иск.прог. Т.2)
X[n+1] = (a*X[n]+c) mod m
Для массива из 100 элементов,
напр. m = 100, c = 17, a = 21
================================
1) НОД(c,m) = 1 (т.е. c и m взаимно просты);
2) a - 1 кратно p для всех простых p - делителей m;
3) a - 1 кратно 4, если m кратно 4.
Спасибо, но как это применить в конкретной ф-ции?
Можно использовать такой алгоритм:
2 начиная со второй проверяем предыдущие ячейки на повторение,
пока есть повторение - обновляем ренд и сравниваем,
если повторений нет - продолжаем забивать массив
Как это реализовать в коде? Как обновлять ренд (случайное число) методом вызова?
Допустим m = 100, нужно заполнить массив int a[100];
for(int i=0;i<m;i++)
{
a = x;
x = (a*x+c)%m;
}
Если неизвестно наперед размерность массива, тогда наверно придется написать ф-ю, которая по заданному m вычислит a и c.
Допустим m = 100, нужно заполнить массив int a[100];
for(int i=0;i<m;i++)
{
a = x;
x = (a*x+c)%m;
}
Регардсы, попробую.
Если неизвестно наперед размерность массива, тогда наверно придется написать ф-ю, которая по заданному m вычислит a и c.
Допустим m = 100, нужно заполнить массив int a[100];
for(int i=0;i<m;i++)
{
a = x;
x = (a*x+c)%m;
}
Не получается... Компилятор не понимает a*, с не определено.
Все -таки мой алгоритм ,наверное ,адаптированей...
Как обновлять значение rand() в разных участках программы?
Спасибо, но как это применить в конкретной ф-ции?
Можно использовать такой алгоритм:
2 начиная со второй проверяем предыдущие ячейки на повторение,
пока есть повторение - обновляем ренд и сравниваем,
если повторений нет - продолжаем забивать массив
Как это реализовать в коде? Как обновлять ренд (случайное число) методом вызова?
Попробуй реализовать мой алгоритм плз.
Не получается... Компилятор не понимает a*, с не определено.
Все -таки мой алгоритм ,наверное ,адаптированей...
Конечно твой алгоритм адаптированней. В ней хоть все переменные определены :D. А что мешает написать
{
int x = rand()%m;
for(int i=0;i<m;i++)
{
array = x;
x = (a*x+c)%m;
}
}
Вызов где-то в программе
void main()
{
int a[100];
fillArray(a, 21, 17, 100);
...
}
Или Randomize(), или RandSeed = число. В зависимости от того, что нужно. Всегда другая последовательность или одна и та же последовательность при разных вызовах программы. Если я правильно понял вопрос.
Попробуй реализовать мой алгоритм плз.
Архи неэффективный алгоритм, но пусть будет, в "моей" нужно бы определять коэф. a, c
{
Randomize(); //при каждом вызове другая последовательность
for(int i=0; i<m; i++)
{
while(true)
{
int x = rand()%m;
for(int j=0; j<i; j++)
{
if(ar[j]==x)
{
x = -1;
break;
}
}
if(x!=-1)
{
ar = x;
break;
}
}
}
}
Архи неэффективный алгоритм, но пусть будет, в "моей" нужно бы определять коэф. a, c
{
Randomize(); //при каждом вызове другая последовательность
for(int i=0; i<m; i++)
{
while(true)
{
int x = rand()%m;
for(int j=0; j<i; j++)
{
if(ar[j]==x)
{
x = -1;
break;
}
}
if(x!=-1)
{
ar = x;
break;
}
}
}
}
Какие заголовки грузить(Randomize(); не понимает)?
Фенкс! На счет 20-ти копеек или 7 алтынов - без Б. Считайте каждую консультацию (их будет достаточно :)), а потом все вместе и оплачу вебманями ;)
Какие заголовки грузить(Randomize(); не понимает)?
Фенкс! На счет 20-ти копеек или 7 алтынов - без Б. Считайте каждую консультацию (их будет достаточно :)), а потом все вместе и оплачу вебманями ;)
У меня Visual C++, MSDN нет :(
Какие заголовки грузить(Randomize(); не понимает)?
Оппа. Я думал, что это ветка Buildera.
Для Visual C, вместо Randomize() нужно вызвать
srand((unsigned)time(NULL));
и подключить #include <time.h>
У меня Visual C++, MSDN нет :(
Все OK, я испльзовал srand(time(NULL)); Спасибо за оперативную помощь, на вашем счету 20 центов .:D
...
С тебя 20 копеек на счет sq_deep
От этих 20 коп. отказываюсь: я здесь ни при чём.
А как насчёт заполнения массива с помощью STL? Вот пример из MSDN:
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
int main( ) {
using namespace std;
vector <int> v1;
vector <int>::iterator Iter1, Iter2;
int i;
for ( i = 1 ; i <= 9 ; i++ )
{
v1.push_back( i );
}
random_shuffle( v1.begin( ), v1.end( ) );
cout << "The original version of vector v1 is: ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")." << endl;
// Shuffled once
random_shuffle( v1.begin( ), v1.end( ));
push_heap( v1.begin( ), v1.end( ) );
cout << "Vector v1 after one shuffle is: ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")." << endl;
// Shuffled again
random_shuffle( v1.begin( ), v1.end( ));
push_heap( v1.begin( ), v1.end( ) );
cout << "Vector v1 after another shuffle is: ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")." << endl;
}
Vector v1 after one shuffle is: ( 1 4 7 9 2 5 8 6 3 ).
Vector v1 after another shuffle is: ( 3 2 8 5 4 9 6 7 1 ).
От этих 20 коп. отказываюсь: я здесь ни при чём.
Ok. Просто Вы любите решать студ.задачи, наверно для отдыха.
А как насчёт заполнения массива с помощью STL? Вот пример из MSDN:
// compile with: /EHsc
...
Нормально. Даже можно бы написать не stl версию алгоритма.
Даже можно бы написать не stl версию алгоритма.
Кстати, я думаю — почти уверен, — что std::random_shuffle() использует именно алгоритм из Кнута, который Вы предложили. Тогда там должна быть и предоженная Вами "функция, которая по заданному m вычислит a и c". Если бы версия STL от Microsoft была написана хоть чуть-чуть более "reader-friendly", я бы посмотрел в их тексты, чтобы это проверить. Интересно было бы узнать, как они это делают, но копаться в их коде, в котором все идентификаторы называются "_a", "_l" и т.п. у меня нет ни малейшего желания.
Кстати, когда-то давно я использовал бейсик от Hewlett-Packard, в котором допускались только двухсимвольные идентификаторы типа A1, C8 и т.п. А идом массива там могло быть только однобуквенное слово, и таким образом в программе не могло быть больше 26 массивов. Вот это была хорошая шутка! даже лучше, чем в MS STL. До сих пор забыть не могу :roll:
От этих 20 коп. отказываюсь: я здесь ни при чём.
А как насчёт заполнения массива с помощью STL? Вот пример из MSDN:
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
int main( ) {
using namespace std;
vector <int> v1;
vector <int>::iterator Iter1, Iter2;
int i;
for ( i = 1 ; i <= 9 ; i++ )
{
v1.push_back( i );
}
random_shuffle( v1.begin( ), v1.end( ) );
cout << "The original version of vector v1 is: ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")." << endl;
// Shuffled once
random_shuffle( v1.begin( ), v1.end( ));
push_heap( v1.begin( ), v1.end( ) );
cout << "Vector v1 after one shuffle is: ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")." << endl;
// Shuffled again
random_shuffle( v1.begin( ), v1.end( ));
push_heap( v1.begin( ), v1.end( ) );
cout << "Vector v1 after another shuffle is: ( " ;
for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
cout << *Iter1 << " ";
cout << ")." << endl;
}
Vector v1 after one shuffle is: ( 1 4 7 9 2 5 8 6 3 ).
Vector v1 after another shuffle is: ( 3 2 8 5 4 9 6 7 1 ).
Тоже вариант.
Тоже вариант.
Тогда гони 20-у sq_deep :D
Тогда гони 20-у sq_deep :D
Обоим по twenty cents.
Обоим по twenty cents.
sq_deep: А Биллу Гейтсу?!!
Stalcer: Послушайте, sq_deep, ну при чём здесь Билл Гейтс?