Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.10.2012, 20:53   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию Массивы. Множество как один.

Доброго времени суток!

Есть список объектов, каждый объект наделен структурой:
Код:
type
   TMyStruct=packed record
   Buff:array of string;
   Len:NativeUInt; //Length(Buff)
   Count:NativeUInt; //Len-1
   Size:NativeUInt; //SizeOf(Buff)
   end;
Есть некий менеджер этих объектов.
Задача менеджера в том, чтобы собрать из N массивов, 1 большой массив и оттуда, случайно, выдернуть любой элемент.

Как создать 1 большой массив?
Варианты:
Объявить buff:array of string у менеджера и туда загнать все массивы через CopyMemory.

Другой вариант:
Принять все массивы за 1 массив, не объединяя их в 1 массив(Сложить длинны всех массивов), выбрать случайное число, потом как-то узнать к какому массиву принадлежит это число.

Мои мысли(вариант 2):
Код:
var
  i, i2, BuffMax: Integer;
  iRand: Int64;
begin
  for i := 0 to Count - 1 do
    BuffMax := BuffMax + Items[i].Images.BuffCount;
  // Общая длинна всех массивов

  Randomize;
  iRand := RandomRange(0, BuffMax); // Случайный номер

  for i := 0 to Count - 1 do
  begin
    if (iRand < Items[i].Images.BuffCount) then
    begin
      for i2 := 0 to (Count - 1 - i) do
        iRand := iRand - Items[i2].Images.BuffCount;
      // Вычисляю позицию эл-та, вычитая наименьшие массивы.

      Result := Items[i].Images.Buff[i];
    end;
  end;
end;

Последний раз редактировалось Человек_Борща; 23.10.2012 в 22:50.
Человек_Борща вне форума Ответить с цитированием
Старый 23.10.2012, 21:08   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Общее к-во есть. Рандомно исходя из него взять индекс. Пробежаться в цикле по списку объектов и вычислить в каком из них находится строка соответствующая индексу. Взять строку

Вариант 2. Рандомно вычислить индекс объекта в списке. В нем рандомно вычислить индекс строки в массиве
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 23.10.2012 в 21:12.
Аватар вне форума Ответить с цитированием
Старый 23.10.2012, 21:12   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Задача менеджера в том, чтобы собрать из N массивов, 1 большой массив
Те массивы ведь размещены в памяти? Так собери в один большой массив указатели на элементы тех массивов, а не сами массивы. Сделай а-ля индексацию данных.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.10.2012, 21:13   #4
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию

Так?
Код:
var
  i, i2, BuffMax: Integer;
  iRand: Int64;
begin
  for i := 0 to Count - 1 do
    BuffMax := BuffMax + Items[i].Images.BuffCount;
  // Общая длинна всех массивов

  Randomize;
  iRand := RandomRange(0, BuffMax); // Случайный номер

  for i := 0 to Count - 1 do
  begin
    if (iRand < Items[i].Images.BuffCount) then
    begin
      for i2 := 0 to (Count - 1 - i) do
        iRand := iRand - Items[i2].Images.BuffCount;
      // Вычисляю позицию эл-та, вычитая наименьшие массивы.

      Result := Items[i].Images.Buff[i];
    end;
  end;
end;
Stilet, что имеется ввиду? Куда собрать, во что?
Человек_Борща вне форума Ответить с цитированием
Старый 23.10.2012, 21:19   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Похоже, но 2-ой вариант мне более симпатичен - циклов нет и все та же рандомность
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 23.10.2012, 21:28   #6
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

_Собирать_ обязательно, или только выдернуть надо?
Если только выдернуть - можно просто запомнить индексы той записи где массив и самой строки в некий списочек, а потом по нему взять рандом.
Пример:
запись1: массив (а, б, в), запись2: массив(г, д), запись3: массив(е)
собираем: 1(1,1) 2(1,2) 3(1,3) 4(2,1) 5(2,2) 6(3,1) - массив из 6 элементов, рандомим 6 и тянем по индексам нужную строку.

А вообще, задачу не уловил... как-то абстрактно, да ещё терминология путаная.
Замечу только ещё, что copymemory для строк не надо делать, они и так ведь указатели, просто сграбить все в кучу и всё (только не менять)
phomm вне форума Ответить с цитированием
Старый 23.10.2012, 21:44   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
что имеется ввиду? Куда собрать, во что?
Ну я может тоже не правильно понял, но подумал что тебе нужна карта массивов, по которой можно быстро найти любой элемент в любом массиве, и уже отталкиваясь от нее обрабатывать все массивы, как будто это один большой массив, не смотря на фрагментацию.
не?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.10.2012, 22:34   #8
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию

Аватар, я сбит с толку вашим ответом
phomm
, Stilet,
Есть одномерные массивы в количестве N, и разных размеров X.
Необходимо их собрать в 1 массив, и оттуда взять случайный элемент.

Тут проблема:
1. массивов может быть очень много, или они будут иметь очень большой размер.
Я думаю, что это имеет значение при сборки их в 1 массив, путем CopyMemory,memcpy или же через цикл:
Код:
var
  a,b:array of string;
...
  for j:=0 to Length(b) do
  begin
  SetLength(a,Length(a)+1);
  a[Length(a)]:=b[j];
  end;
Довольно долго.

Придумал вариант, не собирать их действительно в массив, а образно сложить все размеры массивов в 1, выбрать оттуда число.. :
Как определить к какому массиву принадлежит выбранное это число?

Код, приведенный в посте 4-е - это вроде бы делает.
Человек_Борща вне форума Ответить с цитированием
Старый 23.10.2012, 22:37   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
я сбит с толку вашим ответом
Пост 2 почитайте, я там добавлял. Но прочитав ваш #8 я перестал понимать пост #1
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 23.10.2012 в 22:39.
Аватар вне форума Ответить с цитированием
Старый 23.10.2012, 22:51   #10
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию

Аватар,
Цитата:
Но прочитав ваш #8 я перестал понимать пост #1
Странно я тоже... обновил пост №1

Перечитал ваш пост, думаете это тоже самое, что собрать все в кучу и вытащить X?

Последний раз редактировалось Человек_Борща; 23.10.2012 в 22:58.
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как вставить диапазоны ячеек из разных файлов в один, но так чтобы они шли один ниже другого? Squarded Microsoft Office Excel 4 24.07.2011 19:24
Множество, содержащее натуральные числа из первой сотни. Сформировать новое множество из простых чисел первого множества Aimet Паскаль, Turbo Pascal, PascalABC.NET 3 16.06.2011 20:50
Дано множество А, напечатать четные элементы, входящие в другое множество (Паскаль) Марийка92 Помощь студентам 4 03.04.2011 17:38
Задано некоторое множество М и множество Т того же типа dark999 Помощь студентам 5 01.04.2011 14:17
обьединить массивы в один diliana PHP 5 16.07.2010 13:55