Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сгенерировать число любой длины в заданном диапазо 
:(
    Опции темы
Alexey91
Дата 12.4.2011, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 195
Регистрация: 18.9.2008

Репутация: нет
Всего: нет



Сложно это..

Применяю для представления целых чисел любой длины тип AnsiString, т.е. с самой генерацией чисел проблем не возникает:
Берем нужную длину числа, и в цикле пока всю длину не прошли, присваиваем строке random(10);

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

Вообщем, не знаю что делать.

Выкладываю, кусок НЕрабочего кода, может кого наведут какие мысли:

Код

AnsiString genInt(int l1, int l2, AnsiString min, AnsiString max)   // int max=9
{
 int i;
 int t;
 int len;
 int pos;
 int f;
 AnsiString ret="";
 AnsiString buf="";
 AnsiString tmp="";

 if(l1 < l2)
 {
  for(i=0; i < l2-l1; i++)
  {
   min="0"+min;
   l1++;
  }

 }
 ShowMessage("min");
 ShowMessage(min);

 for(i=1; i <= l1; i++)       {
  if(min[i] < max[i])
  {
   t=random(max[i]-min[i]+1)+min[i];
   ret+=t;
  }
  else if(min[i] == max[i] && min[1] < max[1])
  {
   //buf+=min[i];

   if(rand()%2 == 0)   {
    t=random(10);
    ret+=t;
   }

   else
   {
    t=random(max[i]+1);
    ret+=t;

    tmp=StrToInt(ret[i-1])+1;
    ret[i-1]=tmp[1];
   }
  }



  t=random(max[i]-min[i]+1)+min[i];
  ret+=t;
 }

 return ret;
}



По коду. Как я решил делать: сначала делаю проверку если у нас число разрядов у чисел не одинаковые, то дописываю нули у числа, у которого
меньше разрядов. Потом сравнениваю. Если первый разряд первого числа меньше первого разряда второго числа, то по значит
в первом числе могут быть сгенерированы любые числа после первого разряда.

Это не работает, скажем на примере:

351 452



Это сообщение отредактировал(а) Alexey91 - 12.4.2011, 09:48
PM   Вверх
A5uKa
Дата 12.4.2011, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


TЋ♥s F1rȜ iƧ BurȠiƞg
***


Профиль
Группа: Awaiting Authorisation
Сообщений: 1928
Регистрация: 30.8.2008

Репутация: 2
Всего: 16



Код

int genInt(int l1, int l2)
{
  return (I1 + random(I2+1) );
}


- это ? или я ничего не понимаю
PM   Вверх
borisbn
Дата 12.4.2011, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



Цитата(Alexey91 @  12.4.2011,  09:44 Найти цитируемый пост)
Применяю для представления целых чисел любой длины тип AnsiString

Цитата(Alexey91 @  12.4.2011,  09:44 Найти цитируемый пост)
миллион чисел длины по знаков 50

A5uKa, у человека, походу, арифметика длинных чисел

Alexey91, генери число от 0 до (max - min), а затем добавляй min, как ты это делаешь на бумажке в столбик
Цитата

 8567225478
+1249745356
--------------
 9816970834
  11  1 11



Это сообщение отредактировал(а) borisbn - 12.4.2011, 13:21


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
A5uKa
Дата 12.4.2011, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


TЋ♥s F1rȜ iƧ BurȠiƞg
***


Профиль
Группа: Awaiting Authorisation
Сообщений: 1928
Регистрация: 30.8.2008

Репутация: 2
Всего: 16



Цитата(borisbn @ 12.4.2011,  13:15)
A5uKa, у человека, походу, арифметика длинных чисел

опять не понимаю  smile 
PM   Вверх
xvr
Дата 12.4.2011, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



1) Добиваешь короткую строку нулями слева (как у тебя и было)
2) Берешь самую левую цифру, точнее 2 цифры - минимум и максимум. Генерируешь цифру в диапазоне min-max
3) Если цифра не совпала с min (или max), то все дальнейшие цифры в min (max) числе принимаешь равными 0 (9)
4) Повторять, пока вся строка не будет сгенерена
 
PM MAIL   Вверх
borisbn
Дата 12.4.2011, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



вау ! ( это я  xvr-у )
хм... надо быть проще и к тебе люди потянутся ( это я себе smile )



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Alexey91
Дата 12.4.2011, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 195
Регистрация: 18.9.2008

Репутация: нет
Всего: нет



borisbn К сожалению не понял(

xvr

На примере 903 и 1107

1) Дописываю нули 0903, 1107
2) Беру 0 и 1
Случайные числа нахожу по такой формуле: random(max[i]-min[i]+1)+min[i]
Получаю например 0
0 совпал с min[i]

что дальше? Исходя из твоего алгоритма  smile 




Это сообщение отредактировал(а) Alexey91 - 12.4.2011, 17:34
PM   Вверх
borisbn
Дата 12.4.2011, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



мда, поспешил я хвалить...
при min=999999, max=1999999 и при первом рандоме, равном 0, рез-т будет всегда 999999, т.е. в 50% будет нормальный ранд, в 50% - всегда равен min...

Цитата(Alexey91 @  12.4.2011,  17:20 Найти цитируемый пост)
borisbn К сожалению не понял(

тебе нужно создать ф-ции вычитания и сложения чисел, представленных в виде строки.
такие ф-ции проще всего реализовать методом, который все в школе учили - в столбик.
Берёшь одно число, снизу под ним пишешь другое, выровняв нулями вначале меньшее из них.
Затем начиная справа (последний символ в строке) складывашь две цифры. Остаток от деления на 10 записываешь в рез-т, а рез-т целочисленного деления на 10 добавляешь к следующей сумме...
Школа 1-й или 2-й класс.

а дальше вызывая эти ф-ции делаешь то же самое, что и с обычными числами
Цитата

str_random( str_max - str_min +1) + str_min

ну, а сама ф-ция str_random будет уже попроще, т.к. мин. число у неё 0.
вот её, кстати, можно реализовывать как предложил xvr

Это сообщение отредактировал(а) borisbn - 12.4.2011, 17:56


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
borisbn
Дата 12.4.2011, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



так и быть, лови сумму
Код

#include <string>

std::string str_add( const std::string & a, const std::string & b )
{
    std::string result;
    int a_length = a.length();
    int b_length = b.length();
    std::string shortest = ( a_length <= b_length ? a : b );
    const std::string & largest = ( a_length > b_length ? a : b );
    int shortestLength = ( a_length < b_length ? a_length : b_length );
    int largestLength = ( a_length > b_length ? a_length : b_length );
    for ( int i = shortestLength; i < largestLength; ++i )
    {
        shortest = "0" + shortest;
    }
    int shiftDigit = 0;
    for ( int i = largestLength - 1; i >= 0; --i )
    {
        int aDigit = shortest[ i ] - '0';
        int bDigit = largest[ i ] - '0';
        int summ = aDigit + bDigit + shiftDigit;
        result = (char)( ( summ % 10 ) + '0' ) + result;
        shiftDigit = summ / 10;
    }
    if ( shiftDigit != 0 )
    {
        result = (char)( shiftDigit + '0' ) + result;
    }
    return result;
}

#include <iostream>
int main()
{
    std::cout << str_add( "935", "89" ) << std::endl;
}

http://liveworkspace.org/code/c3c088470490...6919d945eea835a
разность - сам. по аналогии и по школьному курсу за 1-й класс smile.

Это сообщение отредактировал(а) borisbn - 12.4.2011, 21:00


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Alexey91
Дата 12.4.2011, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 195
Регистрация: 18.9.2008

Репутация: нет
Всего: нет



borisbn, спасибо  smile 

А я вывел следующий алгоритм (рабочий):

На примере двух чисел: 603, 2954

Если длина разная, то дописываем (длина_второй_строки-длина_первой_строки) нулей к первому числу
Получаем: 0603, 2954

Берем первые разряды двух предельных значений (>=, <=), т.е. 0 и 2
И генерируем число в диапазоне этих двух первых разрядов (т.е. в данном случае 0 и 2)

Если сгенерированное значение равно 1, то последующие разряды генерируемого числа можем забивать числами от 0 до 9
(в самом деле, если первый разряд 1, то остальные разряды могут быть из любых цифр... 1504, 1999, 1704, 1613 - все они в любом
случае войдут в заданный диапазон)

Если сгенерированное значение равно 0, то работаем с первым числом (0603), а именно таким образом:

1.Берем второй разряд (6) и генерируем числа в диапазоне от 6 до 9
2.Если сгенерированное число равно 6, то смотрим следующие разряды (возвращаемся к пункту 1 и берем третий разряд и.т.д.)
3.Если нет (получились 7, 8, 9), то последующие разряды забиваем любыми числами от 0 до 9
(734,799,954 все они в любом случае будут больше 609)

Если сгенерированное значение равно 2, то работаем со вторым число (2954), а именно таким образом:

1.Берем второй разряд (9) и генерируем числа в диапазоне от 0 до 9
2.Если сгенерированное число равно 9, то смотрим следующие разряды (возвращаемся к пункту 1 и берем третий разряд и.т.д.)
3.Если нет (получились 0,1,2,4,5,6,7,8),то последующие разряды забиваем лбыми числами от 0 до 9
(2854,2299,2899,2403 все они в любом случае будут меньше 2954)

Добавлено @ 18:41
Рано я обрадовался, нужно еще генерировать вещественные числа, и учитывать то, что они могут быть отрицательными  smile 

Это сообщение отредактировал(а) Alexey91 - 12.4.2011, 18:46
PM   Вверх
borisbn
Дата 12.4.2011, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



1. Это ничем не отличается от алгоритма xvr. Почти
2. Проверь при при min=999999, max=1999999 и первом рандоме, равном 0
3. У меня в ф-ции ошибка. В строке, где выбирается shortest нужно поменять < на <=


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
xvr
Дата 12.4.2011, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(borisbn @  12.4.2011,  17:52 Найти цитируемый пост)
мда, поспешил я хвалить...
при min=999999, max=1999999 и при первом рандоме, равном 0, рез-т будет всегда 999999, т.е. в 50% будет нормальный ранд, в 50% - всегда равен min...

Да, есть такая бяка. И она будет у любого алгоритма, генерирующего цифры поштучно  smile Что бы получить хорошее распределение у результирующего числа его надо создавать именно как число. Твой вариант с str_random не является исключением. Как генерировать эту самую рандомную строку/число?  Если по 1 цифре, то получим то же самое, что и в моем варианте  smile 

Цитата(Alexey91 @  12.4.2011,  17:20 Найти цитируемый пост)
На примере 903 и 1107
что дальше? Исходя из твоего алгоритма

Псевдокод. MinStr, MaxStr - строки (уже дополненные нулями)
Код

String get_rnd_str(String MinStr, String MaxStr)
{
 bool nomin=false, nomax=false;
 String rv;
 for(int i=MinStr.Length();i;i--)
  {
   char sym=rand_range(nomin?'0':MinStr[i],nomax?'9':MaxStr[i]);
   rv+=sym;
   if (sym!=MinStr[i]) nomin=true;
   if (sym!=MaxStr[i]) nomax=true;
  }
 return rv;
}

PM MAIL   Вверх
borisbn
Дата 12.4.2011, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



Цитата(xvr @  12.4.2011,  20:42 Найти цитируемый пост)
Твой вариант с str_random не является исключением. 

если генерить [ 0; max ], то твой алгоритм должен работать.

--------------
отредактировал сообщение с ф-цией str_add и пример на liveworkspace

 smile  smile  smile 
давно хотел попросить boostcoder'а, чтобы он сделал на сайте liveworkspace пометочку какой щаз используется компилятор, версия boost и т.п. 

boostcoder, если читаешь, сделай, плиз.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 12.4.2011, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 3
Всего: 85



Цитата(Alexey91 @  12.4.2011,  09:44 Найти цитируемый пост)
Применяю для представления целых чисел любой длины тип AnsiString

Цитата(Alexey91 @  12.4.2011,  09:44 Найти цитируемый пост)
Но преподавателя интересует и быстродействие

Если интересует быстродействие, то нужно писать нормальную арифметику длинных чисел, а не представлять числа в символьном десятичном виде. Только так можно сделать по-настоящему юниформ-рандом генератор случайных чисел в заданном диапазоне.
Кстати по настоящему юниформ-рандом гсч, тоже отрбасывает неподходящие числа, до тех пор пока не сгенерирует подходящее. иначе никак. Просто в двоичном виде в самом худшем варианте будет 50% вероятности получить правильное число, что приемлемо. В десятичном виде (в общем случае) вероятность гораздо меньше.
Ну а с символьным представлением вообще о быстродействии можно забыть.



PM MAIL   Вверх
borisbn
Дата 13.4.2011, 08:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



Цитата(borisbn @  12.4.2011,  21:06 Найти цитируемый пост)
если генерить [ 0; max ], то твой алгоритм должен работать.

неа. не будет. (0...1000000). надо что-то другое думать.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0585 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.