Как определить элемент множества [РЕШЕНО]
Модератор: Модераторы
Как определить элемент множества [РЕШЕНО]
Добрый день форумчане!
Работаю с множествами и наткнулся на проблему. Я не могу определить значение элемента множества. Самое простое, есть множество из N элементов и есть подмножество из K элементов (N>K). Мне требуется в подмножестве определить значение какого любого элемента. Как это сделать не понятно. В цикле перебрать элементы множества и инкрементируя счетчик не очень подходит. Так как очень критично к времени исполнения. И это все в нескольких вложенных циклах. Хорошо бы как в массиве обратиться по индексу, но с множествами такое не проходит.
Кто чего посоветуе?
ЗЫ. Длинну множества тоже хочется определить.
Работаю с множествами и наткнулся на проблему. Я не могу определить значение элемента множества. Самое простое, есть множество из N элементов и есть подмножество из K элементов (N>K). Мне требуется в подмножестве определить значение какого любого элемента. Как это сделать не понятно. В цикле перебрать элементы множества и инкрементируя счетчик не очень подходит. Так как очень критично к времени исполнения. И это все в нескольких вложенных циклах. Хорошо бы как в массиве обратиться по индексу, но с множествами такое не проходит.
Кто чего посоветуе?
ЗЫ. Длинну множества тоже хочется определить.
Последний раз редактировалось vada 06.09.2011 11:41:10, всего редактировалось 1 раз.
Обращение по индексу говорите? да нет ничего проще (зная внутреннее устройства множеств).
Код: Выделить всё
type
TSet = set of 0..31;
function IsSet(const aSet: TSet; const aIndex: Integer): Boolean;
begin
Result:=Boolean(dword(aSet) and (1 shl aIndex));
end; -
SAK
- постоялец
- Сообщения: 158
- Зарегистрирован: 17.02.2006 23:45:14
- Откуда: Тим
- Контактная информация:
Что значит "определить значение какого любого элемента"? Это же не массив. Можно определить есть конкретный элемент в множестве или нет.
А зачем знать внутреннее устройство? Есть же стандартная операция: Result := аIndex in аSet
Но насколько я понял автор топика желает обращаться только к существующим в множестве элементам.
Mr.Smart писал(а):Обращение по индексу говорите? да нет ничего проще (зная внутреннее устройства множеств).Код: Выделить всё
...
Result:=Boolean(dword(aSet) and (1 shl aIndex));
...
А зачем знать внутреннее устройство? Есть же стандартная операция: Result := аIndex in аSet
Но насколько я понял автор топика желает обращаться только к существующим в множестве элементам.
SAK точно! Навелосипедничал немного
Понедельник, такой понедельник...
Не. Это не очень. Множество у меня генерится программно и я заранее не знаю его состав. Получить значение true при Index=3 мне не о чем.
Я не знаю длинну подмножества и не знаю элементы в него входящие. А перебирать в цикле как-то не хочется.
В результате неких манипуляций получаем множество OtherOnly содержащее некоторое количество элементов. Вот мне и хотелось бы определить:
1) Количество элементов в множестве OtherOnly;
2) Значение I-го элемента множества OtherOnly.
Добавлено спустя 2 минуты 29 секунд:
В том и дело что это не массив. Но мне нужно получить значение именно как в массиве.
И желательно обойтись без циклов.
Например, если третий элемент множества есть ns15 то мне кое-что надо сделать с другим множеством, а если он ns18 то его убрать из множества... Ну где-то так.
Код: Выделить всё
type
TSetNagr = (ns01, ns02, ns03, ns04, ns05, ns06, ns07, ns08, ns09, ns10,
ns11, ns12, ns13, ns14, ns15, ns16, ns17, ns18, ns19, ns20);
var
OtherOnly: TSetNagr;
В результате неких манипуляций получаем множество OtherOnly содержащее некоторое количество элементов. Вот мне и хотелось бы определить:
1) Количество элементов в множестве OtherOnly;
2) Значение I-го элемента множества OtherOnly.
Добавлено спустя 2 минуты 29 секунд:
Что значит "определить значение какого любого элемента"? Это же не массив. Можно определить есть конкретный элемент в множестве или нет.
В том и дело что это не массив. Но мне нужно получить значение именно как в массиве.
Например, если третий элемент множества есть ns15 то мне кое-что надо сделать с другим множеством, а если он ns18 то его убрать из множества... Ну где-то так.
- Brainenjii
- энтузиаст
- Сообщения: 1351
- Зарегистрирован: 10.05.2007 00:04:46
Не совсем понял, что именно имеется в виду, но может это поможет:
Код: Выделить всё
TSetNagr = (ns01 = 1, ns02 = 2, ns03 = 3, ns04 = 4, ns05 = 5, ns06 = 24, ns07 = 25, ns08 = 26, ns09 = 33, ns10 = 34,
ns11 = 38, ns12 = 41, ns13 = 22, ns14 = 90, ns15 = 66, ns16 = 31, ns17 = 29, ns18 = 54, ns19 = 61, ns20 = 66);
...
WriteLn(Integer(ns13));
...
Не. Не так.
vada писал(а):Например, если третий элемент множества есть ns15 то мне кое-что надо сделать с другим множеством, а если он ns18 то его убрать из множества... Ну где-то так.
Множества в паскале не упорядочены, в них не бывает "третьего элемента".
Если важен порядок элементов (например, если ns15 стоит третьим элементом -- нужно сделать что-то с другим множеством, а если четвёртым -- то не нужно ничего делать), то помогут обычные списки (TList или его наследники).
Если порядок элементов не важен, но нужна возможность пробежаться по элементам подмножества, то я бы использовал сортированный список с двоичным поиском по нему. Из коробки двоичный поиск есть только у TStringList, но можно написать собственный список с такой возможностью для другого типа.
Odyssey писал(а):Множества в паскале не упорядочены, в них не бывает "третьего элемента".
Жаль.
Хотя, когда я просматриваю сформированное множество, то вижу что оно в том порядке в каком я его создавал. Вот это и натолкнуло на мысль...
А списки не годятся. Это ОЧЕНЬ медленно.
Задача у меня перебрать все варианты из множества длинной максимум 7. Это 7! = 5040 штук комбинаций. Такого порядка множеств у меня 3. Эти три множества надо между собой перемешать. Еще туча вариантов. Какие-то элементы выбрасывать из-за несовместимости. В общем, там дофига переборов получается.
-
SAK
- постоялец
- Сообщения: 158
- Зарегистрирован: 17.02.2006 23:45:14
- Откуда: Тим
- Контактная информация:
vada писал(а):перебрать все варианты из множества длинной максимум 7
Не знаю всей сути задачи, но на мой взгляд напрашивается просто массив с дополнительной переменной указывающей его размер. Некоторая аналогия типу string. Или ещё добавить функции для упрощения работы с этим массивом и всё объединить в один тип как object или даже класс. Получится аналогия множествам, но с возможностью свободного раширения функциональности.
PS. Количество элементов в множестве называется мощностью множества.
Всем спасибо!
Переработал алгоритм. Скрестил множества со TStringList. Все получилось элегантно понятно и работает быстро.
Переработал алгоритм. Скрестил множества со TStringList. Все получилось элегантно понятно и работает быстро.
http://www.pascal.helpov.net/index/pasc ... rogramming
Для работы с перечисляемыми типами существуют следующие функции, которые хранятся в библиотеке системных функций, и программист имеет к ним доступ:
ord(N) – возвращает номер элемента N в множестве;
succ(N) – возвращает следующее значение для N;
pred(N) – возвращает предыдущее значение для N.
Для работы с перечисляемыми типами существуют следующие функции, которые хранятся в библиотеке системных функций, и программист имеет к ним доступ:
ord(N) – возвращает номер элемента N в множестве;
succ(N) – возвращает следующее значение для N;
pred(N) – возвращает предыдущее значение для N.
