Set (abstract data type)

In computer science, a set is an abstract data type that can store distinct values, without any particular order. It is a computer implementation of the mathematical concept of a finite set. Unlike most other collection types, rather than retrieving a specific element from a set, one typically tests a value for membership in a set.

Some set data structures are designed for static or frozen sets that do not change after they are constructed. Static sets allow only query operations on their elements — such as checking whether a given value is in the set, or enumerating the values in some arbitrary order. Other variants, called dynamic or mutable sets, allow also the insertion and deletion of elements from the set.

A multiset is a special kind of set in which an element can appear multiple times in the set.

Type theory

In type theory, sets are generally identified with their indicator function (characteristic function): accordingly, a set of values of type A{\displaystyle A} may be denoted by 2A{\displaystyle 2^{A}} or P(A){\displaystyle {\mathcal {P}}(A)}. (Subtypes and subsets may be modeled by refinement types, and quotient sets may be replaced by setoids.) The characteristic function F{\displaystyle F} of a set S{\displaystyle S} is defined as:

F(x)={1,if xS0,if xS{\displaystyle F(x)={\begin{cases}1,&{\mbox{if }}x\in S\\0,&{\mbox{if }}x\not \in S\end{cases}}}

In theory, many other abstract data structures can be viewed as set structures with additional operations and/or additional axioms imposed on the standard operations. For example, an abstract heap can be viewed as a set structure with a min(S) operation that returns the element of smallest value.

Operations

Core set-theoretical operations

One may define the operations of the algebra of sets:

  • union(S,T): returns the union of sets S and T.
  • intersection(S,T): returns the intersection of sets S and T.
  • difference(S,T): returns the difference of sets S and T.
  • subset(S,T): a predicate that tests whether the set S is a subset of set T.

Static sets

Typical operations that may be provided by a static set structure S are:

  • is_element_of(x,S): checks whether the value x is in the set S.
  • is_empty(S): checks whether the set S is empty.
  • size(S) or cardinality(S): returns the number of elements in S.
  • iterate(S): تُرجع دالة تُرجع قيمة إضافية واحدة لـ S في كل استدعاء، بترتيب عشوائي.
  • enumerate(S): تُرجع قائمة تحتوي على عناصر S بترتيب عشوائي.
  • build(x1,x2,…,xn,): ينشئ بنية مجموعة بقيم x 1 ، x 2 ،...، x n .
  • create_from(collection): ينشئ بنية مجموعة جديدة تحتوي على جميع عناصر المجموعة المعطاة أو جميع العناصر التي تم إرجاعها بواسطة المكرر المعطى .

المجموعات الديناميكية

تتضمن هياكل المجموعات الديناميكية عادةً ما يلي:

  • create(): ينشئ بنية مجموعة جديدة فارغة في البداية.
    • create_with_capacity(n): ينشئ بنية مجموعة جديدة، فارغة في البداية ولكنها قادرة على استيعاب ما يصل إلى n عنصرًا.
  • add(S,x): يضيف العنصر x إلى S ، إذا لم يكن موجودًا بالفعل.
  • remove(S, x): يزيل العنصر x من S ، إذا كان موجودًا.
  • capacity(S): تُرجع هذه الدالة الحد الأقصى لعدد القيم التي يمكن أن تحتويها المجموعة S.

قد تسمح بعض هياكل المجموعات ببعض هذه العمليات فقط. وتعتمد تكلفة كل عملية على طريقة التنفيذ، وربما أيضاً على القيم المحددة المخزنة في المجموعة، وترتيب إدخالها.

عمليات إضافية

هناك العديد من العمليات الأخرى التي يمكن (من حيث المبدأ) تعريفها وفقًا لما سبق، مثل:

  • pop(S): تُعيد عنصرًا عشوائيًا من S ، وتحذفه من S. [ 1 ]
  • pick(S): تُعيد عنصرًا عشوائيًا من المجموعة S. [ 2 ] [ 3 ] [ 4 ] وظيفيًا، يمكن تفسير المُعدِّل popعلى أنه زوج من المُحدِّدات (pick, rest),حيث restتُعيد المجموعة التي تتكون من جميع العناصر باستثناء العنصر العشوائي. [ 5 ] يمكن تفسيره من حيث iterate. [ أ ]
  • map(F,S): تُرجع مجموعة القيم المميزة الناتجة عن تطبيق الدالة F على كل عنصر من عناصر S.
  • filter(P,S): تُرجع المجموعة الفرعية التي تحتوي على جميع عناصر S التي تحقق شرطًا معينًا P.
  • fold(A0,F,S): تُرجع القيمة A | S | بعد تطبيقها على كل عنصر e من لبعض العمليات الثنائية F. يجب أن تكون F تجميعية وتبديلية حتى يكون هذا مُعرّفًا جيدًا.Ai+1 := F(Ai, e)
  • clear(S): حذف جميع عناصر S .
  • equal(S1', S2'): يتحقق مما إذا كانت المجموعتان المعطيتان متساويتين (أي تحتويان على جميع العناصر نفسها فقط).
  • hash(S): returns a hash value for the static set S such that if equal(S1, S2) then hash(S1) = hash(S2)

Other operations can be defined for sets with elements of a special type:

  • sum(S): returns the sum of all elements of S for some definition of "sum". For example, over integers or reals, it may be defined as fold(0, add, S).
  • collapse(S): given a set of sets, return the union.[6] For example, collapse({{1}, {2, 3}}) == {1, 2, 3}. May be considered a kind of sum.
  • flatten(S): given a set consisting of sets and atomic elements (elements that are not sets), returns a set whose elements are the atomic elements of the original top-level set or elements of the sets it contains. In other words, remove a level of nesting – like collapse, but allow atoms. This can be done a single time, or recursively flattening to obtain a set of only atomic elements.[7] For example, flatten({1, {2, 3}}) == {1, 2, 3}.
  • nearest(S,x): returns the element of S that is closest in value to x (by some metric).
  • min(S), max(S): returns the minimum/maximum element of S.

Implementations

Sets can be implemented using various data structures, which provide different time and space trade-offs for various operations. Some implementations are designed to improve the efficiency of very specialized operations, such as nearest or union. Implementations described as "general use" typically strive to optimize the element_of, add, and delete operations. A simple implementation is to use a list, ignoring the order of the elements and taking care to avoid repeated values. This is simple but inefficient, as operations like set membership or element deletion are O(n), as they require scanning the entire list.[b] Sets are often instead implemented using more efficient data structures, particularly various flavors of trees, tries, or hash tables.

As sets can be interpreted as a kind of map (by the indicator function), sets are commonly implemented in the same way as (partial) maps (associative arrays) – in this case in which the value of each key-value pair has the unit type or a sentinel value (like 1) – namely, a self-balancing binary search tree for sorted sets (which has O(log n) for most operations), or a hash table for unsorted sets (which has O(1) average-case, but O(n) worst-case, for most operations). A sorted linear hash table[8] may be used to provide deterministically ordered sets.

Further, in languages that support maps but not sets, sets can be implemented in terms of maps. For example, a common programming idiom in Perl that converts an array to a hash whose values are the sentinel value 1, for use as a set, is:

my%elements=map{$_=>1}@elements;

Other popular methods include arrays. In particular a subset of the integers 1..n can be implemented efficiently as an n-bit bit array, which also support very efficient union and intersection operations. A Bloom map implements a set probabilistically, using a very compact representation but risking a small chance of false positives on queries.

The Boolean set operations can be implemented in terms of more elementary operations (pop, clear, and add), but specialized algorithms may yield lower asymptotic time bounds. If sets are implemented as sorted lists, for example, the naive algorithm for union(S,T) will take time proportional to the length m of S times the length n of T; whereas a variant of the list merging algorithm will do the job in time proportional to m+n. Moreover, there are specialized set data structures (such as the union-find data structure) that are optimized for one or more of these operations, at the expense of others.

Language support

One of the earliest languages to support sets was Pascal; many languages now include it, whether in the core language or in a standard library.

  • In C++, the Standard Template Library (STL) provides the set template class, which is typically implemented using a binary search tree (e.g. red–black tree); SGI's STL also provides the hash_set template class, which implements a set using a hash table. C++11 has support for the unordered_set template class, which is implemented using a hash table. In sets, the elements themselves are the keys, in contrast to sequenced containers, where elements are accessed using their (relative or absolute) position. Set elements must have a strict weak ordering.
  • The Rust standard library provides the generic HashSet and BTreeSet types.
  • توفر لغة جافا Setواجهة لدعم المجموعات (مع HashSetالفئة التي تنفذها باستخدام جدول تجزئة)، SortedSetوالواجهة الفرعية لدعم المجموعات المرتبة (مع TreeSetالفئة التي تنفذها باستخدام شجرة بحث ثنائية).
  • يوفر إطار عمل Foundation من Apple (جزء من Cocoa ) فئات Objective-C التاليةNSSet : NSMutableSetو NSCountedSetو NSOrderedSetو و NSMutableOrderedSet. وتوفر واجهات برمجة تطبيقات CoreFoundation أنواع CFSet و CFMutableSet للاستخدام في لغة C.
  • يحتوي بايثون على أنواع setمدمجةfrozenset منذ الإصدار 2.4، ومنذ الإصدارين 3.0 و2.7، يدعم القيم الحرفية للمجموعات غير الفارغة باستخدام صيغة الأقواس المعقوفة، على سبيل المثال: {x, y, z}; يجب إنشاء المجموعات الفارغة باستخدام set()، لأن بايثون يستخدم {}لتمثيل القاموس الفارغ.
  • يوفر إطار عمل .NET الفئات العامة التي تنفذHashSet الواجهة SortedSetالعامة ISet.
  • تتضمن مكتبة فئات SmalltalkSet كلاً من `and` و` IdentitySetand`، حيث تستخدم `alquality` و`include` لاختبار التضمين على التوالي. توفر العديد من اللهجات صيغًا مختلفة للتخزين المضغوط ( NumberSet``, CharacterSet``)، وللترتيب (` OrderedSet`, SortedSet``, إلخ)، أو للمراجع الضعيفة (` WeakIdentitySet`).
  • تتضمن المكتبة القياسية للغة روبيset وحدة تحتوي على Setفئات SortedSetتقوم بتنفيذ المجموعات باستخدام جداول التجزئة، وتسمح الأخيرة بالتكرار بترتيب مُرتب.
  • تحتوي المكتبة القياسية لـ OCamlSet على وحدة نمطية تقوم بتنفيذ بنية بيانات مجموعة وظيفية باستخدام أشجار البحث الثنائية.
  • يوفر تطبيق GHC للغة Haskell وحدةData.Set نمطية تقوم بتنفيذ المجموعات غير القابلة للتغيير باستخدام أشجار البحث الثنائية. [ 9 ]
  • توفر حزمة Tcl Tcllib وحدة نمطية تقوم بتنفيذ بنية بيانات مجموعة تعتمد على قوائم TCL.
  • تحتوي مكتبة Swift القياسية على Setنوع، منذ Swift 1.2.
  • تم تقديم JavaScriptSet ككائن مدمج قياسي مع معيار ECMAScript 2015 [ 10 ] .
  • تحتوي المكتبة القياسية لـ Erlangsets على وحدة نمطية.
  • تحتوي لغة Clojure على صيغة حرفية للمجموعات المجزأة، كما أنها تنفذ المجموعات المصنفة.
  • يدعم برنامج LabVIEW المجموعات بشكل أصلي، بدءًا من الإصدار 2019.
  • توفر آداAda.Containers.Hashed_Sets الحزم والملفات Ada.Containers.Ordered_Sets.

As noted in the previous section, in languages which do not directly support sets but do support associative arrays, sets can be emulated using associative arrays, by using the elements as keys, and using a dummy value as the values, which are ignored.

Multiset

A generalization of the notion of a set is that of a multiset or bag, which is similar to a set but allows repeated ("equal") values (duplicates). This is used in two distinct senses: either equal values are considered identical, and are simply counted, or equal values are considered equivalent, and are stored as distinct items. For example, given a list of people (by name) and ages (in years), one could construct a multiset of ages, which simply counts the number of people of a given age. Alternatively, one can construct a multiset of people, where two people are considered equivalent if their ages are the same (but may be different people and have different names), in which case each pair (name, age) must be stored, and selecting on a given age gives all the people of a given age.

Formally, it is possible for objects in computer science to be considered "equal" under some equivalence relation but still distinct under another relation. Some types of multiset implementations will store distinct equal objects as separate items in the data structure; while others will collapse it down to one version (the first one encountered) and keep a positive integer count of the multiplicity of the element.

As with sets, multisets can naturally be implemented using hash table or trees, which yield different performance characteristics.

The set of all bags over type T is given by the expression bag T. If by multiset one considers equal items identical and simply counts them, then a multiset can be interpreted as a function from the input domain to the non-negative integers (natural numbers), generalizing the identification of a set with its indicator function. In some cases a multiset in this counting sense may be generalized to allow negative values, as in Python.

Where a multiset data structure is not available, a workaround is to use a regular set, but override the equality predicate of its items to always return "not equal" on distinct objects (however, such will still not be able to store multiple occurrences of the same object) or use an associative array mapping the values to their integer multiplicities (this will not be able to distinguish between equal elements at all).

Typical operations on bags:

  • contains(B, x): checks whether the element x is present (at least once) in the bag B
  • is_sub_bag(B1, B2): checks whether each element in the bag B1 occurs in B1 no more often than it occurs in the bag B2; sometimes denoted as B1B2.
  • count(B, x): returns the number of times that the element x occurs in the bag B; sometimes denoted as B # x.
  • scaled_by(B, n): given a natural numbern, returns a bag which contains the same elements as the bag B, except that every element that occurs m times in B occurs n * m times in the resulting bag; sometimes denoted as nB.
  • union(B1, B2): returns a bag containing just those values that occur in either the bag B1 or the bag B2, except that the number of times a value x occurs in the resulting bag is equal to (B1 # x) + (B2 # x); sometimes denoted as B1B2.

Multisets in SQL

في قواعد البيانات العلائقية ، يمكن أن يكون الجدول مجموعة (رياضية) أو مجموعة متعددة، اعتمادًا على وجود قيود التفرد على بعض الأعمدة (مما يحوله إلى مفتاح مرشح ).

يسمح SQL بتحديد الصفوف من جدول علائقي: ستؤدي هذه العملية بشكل عام إلى مجموعة متعددة، ما لم DISTINCTيتم استخدام الكلمة الرئيسية لإجبار الصفوف على أن تكون جميعها مختلفة، أو يتضمن التحديد المفتاح الأساسي (أو مفتاح مرشح).

في لغة ANSI SQL، يمكن استخدام الكلمة MULTISETالمفتاحية لتحويل استعلام فرعي إلى تعبير مجموعة:

حدد التعبير 1 ، والتعبير 2 ... من اسم الجدول ...

عبارة SELECT عامة يمكن استخدامها كتعبير استعلام فرعي لاستعلام آخر أكثر عمومية، بينما

MULTISET ( SELECT expression1 , expression2 ... FROM table_name ...)

يحول الاستعلام الفرعي إلى تعبير مجموعة يمكن استخدامه في استعلام آخر، أو في تعيينه لعمود من نوع المجموعة المناسب.

انظر أيضاً

ملحوظات

  1. على سبيل المثال، في لغة بايثون،pickيمكن تنفيذ ذلك على فئة مشتقة من الفئة المدمجةsetعلى النحو التالي:
    class Set ( set ): def pick ( self ): return next ( iter ( self ))
  2. يمكن إدخال العنصر في وقت O (1) ببساطة عن طريق الإدخال في النهاية، ولكن إذا تجنب المرء التكرارات، فإن هذا يستغرق وقتًا قدره O ( n ).

مراجع

  1. بايثون: pop()
  2. إدارة ومعالجة هياكل البيانات المعقدة: ورشة العمل الثالثة حول نظم المعلومات والذكاء الاصطناعي، هامبورغ، ألمانيا، 28 فبراير - 2 مارس 1994. وقائع المؤتمر، تحرير كاي فون لوك، هاينز ماربورغر، ص 76
  3. مشكلة بايثون رقم 7212 : استرجاع عنصر عشوائي من مجموعة دون حذفه؛ راجع الرسالة رقم 106593 بخصوص الاسم القياسي
  4. ميزة روبي: إضافة Set#pick و Set#pop
  5. التركيب الاستقرائي للبرامج الوظيفية: التخطيط الشامل، وطي البرامج المحدودة، وتجريد المخططات عن طريق الاستدلال القياسي، أوتي شميد ، سبرينغر، 21 أغسطس 2003، ص 240
  6. الاتجاهات الحديثة في تحديد أنواع البيانات: ورشة العمل العاشرة حول تحديد أنواع البيانات المجردة بالاشتراك مع ورشة عمل COMPASS الخامسة، سانتا مارغريتا، إيطاليا، 30 مايو - 3 يونيو 1994. أوراق مختارة، المجلد 10، تحرير إيجيديو أستيسيانو، جيانا ريجيو، أندريه تارليكي، ص 38
  7. روبي: flatten()
  8. وانغ، توماس (1997)، جدول التجزئة الخطي المصنف ، مؤرشف من الأصل في 12 يناير 2006
  9. ستيفن آدامز، " المجموعات الفعالة: عملية موازنة " ، مجلة البرمجة الوظيفية 3(4):553-562، أكتوبر 1993. تم الاطلاع عليه في 2015-03-11.
  10. "مواصفات لغة ECMAScript 2015 - ECMA-262 الإصدار السادس" . www.ecma-international.org . تاريخ الاطلاع: 11 يوليو 2017 .