Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/GAP/pkg/datastructures/gap/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 14.9.2025 mit Größe 4 kB image not shown  

Quelle  hashset.gi   Sprache: unbekannt

 
##
##  Datastructures: GAP package providing common datastructures.
##
##  Copyright (C) 2015-2017  The datastructures team.
##  For list of the team members, please refer to the COPYRIGHT file.
##
##  This package is licensed under the GPL 2 or later, please refer
##  to the COPYRIGHT.md and LICENSE files for details.
##

##
##  Implementation of a hash set for GAP.
##

#! @Chapter Hashsets
#! @Section API
InstallGlobalFunction(HashSet,
function(arg...)
    local hashfunc, eqfunc, capacity, res, values, v;

    values := [];
    hashfunc := HashBasic;
    eqfunc := \=;
    capacity := 16;

    if Length(arg) > 0 and IsList(arg[1]) then
        values := Remove(arg, 1);
        capacity := Maximum(capacity, Length(values));
    fi;
    if Length(arg) > 0 and IsFunction(arg[1]) then
        hashfunc := Remove(arg, 1);
    fi;
    if Length(arg) > 0 and IsInt(arg[Length(arg)]) then
        capacity := Remove(arg);
    fi;
    if Length(arg) = 1 and IsFunction(arg[1]) then
        eqfunc := Remove(arg);
    fi;
    if Length(arg) > 0 then
        Error("Invalid arguments");
    fi;

    res := DS_Hash_Create(hashfunc, eqfunc, capacity, true);
    for v in values do
        AddSet(res, v);
    od;
    return res;
end);

InstallMethod(PrintString, "for hashsets",
    [ IsHashSetRep ],
function(ht)
    local v, first, string;
    string := [];
    Add(string, "HashSet([\>\>");
    first := true;
    for v in ht do
        if first then
            first := false;
        else
            Add(string, ",\< \>");
        fi;
        Add(string, PrintString(v));
    od;
    Add(string, "\<\<])");
    return Concatenation(string);
end);

InstallMethod(String, "for hashsets",
    [ IsHashSetRep ],
function(ht)
    local v, first, string;
    string := [];
    Add(string, "HashSet([");
    first := true;
    for v in ht do
        if first then
            first := false;
        else
            Add(string, ", ");
        fi;
        Add(string, String(v));
    od;
    Add(string, "])");
    return Concatenation(string);
end);

#! @Description
#! Add <A>obj</A> to <A>hashset</A>.
#! @Arguments hashset, obj
InstallOtherMethod(AddSet,
    "for a hash set and a key",
    [ IsHashSetRep, IsObject ],
    DS_Hash_AddSet);

#! @Description
#! Test membership of <A>obj</A> in <A>hashset</A>
#! @Arguments obj, hashset
InstallOtherMethod( \in,
    "for a hash set and a key",
    [ IsObject, IsHashSetRep ],
    {key, ht} -> DS_Hash_Contains(ht, key));

#! @Description
#! Remove <A>obj</A> from <A>hashset</A>.
#! @Arguments hashset, obj
InstallOtherMethod( RemoveSet,
    "for a hash set and a key",
    [ IsHashSetRep, IsObject ],
    DS_Hash_Delete);

#! @Description
#! Return the size of a hashset
#! @Arguments hashset
#! Returns an integer
InstallOtherMethod( Size,
    "for a hash set",
    [ IsHashSetRep ],
    ht -> DS_Hash_Used(ht));

#! @Description
#! Test a hashset for emptiness.
#! @Arguments hashset
#! @Returns a boolean
InstallOtherMethod( IsEmpty,
    "for a hash set",
    [ IsHashSetRep ],
    ht -> DS_Hash_Used(ht) = 0);

#! @Description
#! Convert a hashset into a &GAP; set
#! @Arguments hashset
#! @Returns a set
InstallOtherMethod( Set,
    "for a hash set",
    [ IsHashSetRep ],
    ht -> Difference(Set(ht![5]),[fail]));

#! @Description
#! Convert a hashset into a &GAP; set
#! @Arguments hashset
#! @Returns an immutable set
InstallOtherMethod( AsSet,
    "for a hash set",
    [ IsHashSetRep ],
    ht -> MakeImmutable(Set(ht)));


BindGlobal( "NextIterator_HashSet", function(iter)
    local val, idx;
    if iter!.next > Length(iter!.list) then
        Error("<iter> is exhausted");
    fi;
    val := iter!.list[ iter!.next ];
    idx := iter!.next + 1;
    # skip to the next bound entry not equal to 'fail' (which marks deleted entries)
    while idx <= Length(iter!.list) and not
        (IsBound(iter!.list[idx]) and iter!.list[idx] <> fail) do
        idx := idx + 1;
    od;
    iter!.next := idx;
    return val;
end);

#! @Description
#! Create an iterator for the values contained in a hashset.
#! Note that elements added to the hashset after
#! the creation of an iterator are not guaranteed to be returned by that iterator.
#! @Arguments set
#! @Returns an iterator
InstallOtherMethod( Iterator,
    "for a hash set",
    [ IsHashSetRep ],
function(ht)
    local iter;
    iter := rec(list := ht![5], next := PositionProperty(~.list, x -> x <> fail));
    iter.ShallowCopy := iter -> rec(list := iter!.list, next := iter!.next);
    iter.IsDoneIterator := iter -> iter!.next > Length(iter!.list);
    iter.NextIterator   := NextIterator_HashSet;

    return IteratorByFunctions( iter );
end);


# TODO: things we could implement (but do we want to?)
# UnitSet
# Union
# Intersection
# ...
#
# But do we really want to???

[ Dauer der Verarbeitung: 0.28 Sekunden  (vorverarbeitet)  ]