Skip to content

structure: set #111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 12, 2023
Merged

structure: set #111

merged 5 commits into from
Mar 12, 2023

Conversation

zFl4wless
Copy link
Contributor

Since this data structure is just using the methods of the hash table, I thought that extra testing is not relevant. Correct me if I'm wrong

Copy link
Contributor

@appgurueu appgurueu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an interface the HashTable (which should perhaps be renamed to HashSet) implements rather than a class which delegates everything to the HashTable. Currently this is pretty much just useless boilerplate.

@zFl4wless
Copy link
Contributor Author

@appgurueu Is this what you mean? I found your comment a bit confusing

@appgurueu
Copy link
Contributor

Not quite. The interface is correct, but you should have simply renamed the HashTable to HashSet rather than renaming the Set class. The Set class is obsolete and should be removed.

@zFlxw
Copy link
Contributor

zFlxw commented Mar 10, 2023

But a hash table and a hash set are two different things, or am I wrong? A hash set stores a set of single values (e. g. "{1, 2, 3, ...}"). A hash table stores a set of key-pair values (e. g. "{a -> 1, b -> 2, c -> 3, ...}"). So therefore, renaming the hash table to a hash set would change the meaning of it. Feel free to correct me, if I misunderstood something.

@zFl4wless
Copy link
Contributor Author

zFl4wless commented Mar 10, 2023

But a hash table and a hash set are two different things, or am I wrong? A hash set stores a set of single values (e. g. "{1, 2, 3, ...}"). A hash table stores a set of key-pair values (e. g. "{a -> 1, b -> 2, c -> 3, ...}"). So therefore, renaming the hash table to a hash set would change the meaning of it. Feel free to correct me, if I misunderstood something.

Ye, i guess. But implementing a Set based on a HashTable is pretty much the same except ignoring the value and just using the key. As @appgurueu said, it is pretty much just useless boilerplate.

I could implement the Set based on a LinkedList, so that it really shows some extra logic. Currently, the HashTable is handling everything itself.

@appgurueu
Copy link
Contributor

appgurueu commented Mar 10, 2023

Yes, you're right! Sorry, I glossed this over and mostly saw what looked like boilerplate... I'm used to implementing it the other way around (implementing a "map" as a special "set" which requires the "hack" of find returning the found entry).

Your initial changes were fine. Perhaps somewhat cleaner would be a general abstraction to convert a map into a set. If you want to, you can implement the following:

  • A Map<K, V> interface for the HashTable (which should be renamed to HashMap rather than HashSet, sorry about that)
  • A general Set<K> interface
  • A MapSet<K, V> abstract class which implements this boilerplate once for a generic Map<K, V> map (instance variable)
  • A HashMapSet<K> class which extends MapSet<K> and sets the map = new HashMap<K, V>(...) in the constructor.

@zFl4wless
Copy link
Contributor Author

Yes, you're right! Sorry, I glossed this over and mostly saw what looked like boilerplate... I'm used to implementing it the other way around (implementing a "map" as a special "set" which requires the "hack" of find returning the found entry).

Your initial changes were fine. Perhaps somewhat cleaner would be a general abstraction to convert a map into a set. If you want to, you can implement the following:

* A `Map<K, V>`  interface for the `HashTable` (which should be renamed to `HashMap` rather than `HashSet`, sorry about that)

* A general `Set<K, V>` interface

* A `MapSet<K, V>` abstract class which implements this boilerplate _once_ for a generic `Map<K, V> map` (instance variable)

* A `HashMapSet<K, V>` class which extends `MapSet<K, V>` and sets the `map = new HashMap<K, V>(...)` in the constructor.

Shouldn't the Set only have one generic? Because there is no key-value pair stored.

@appgurueu
Copy link
Contributor

appgurueu commented Mar 10, 2023

Shouldn't the Set only have one generic? Because there is no key-value pair stored.

Yes of course, sorry again. Fixed.

@zFl4wless
Copy link
Contributor Author

btw something offtopic. Maybe it would make sense to group some of the data structures because there are multiple implementations and sorts of one data structure.

@appgurueu
Copy link
Contributor

btw something offtopic. Maybe it would make sense to group some of the data structures because there are multiple implementations and sorts of one data structure.

Yes, multiple implementations of the same data structure should be grouped in a common package. Feel free to refactor this.

@zFl4wless
Copy link
Contributor Author

Alrighty, I implemented your suggestion!

I still got some questions:

  1. Wouldn't it make more sense for the Set classes/interfaces to choose the letter "V"(Value) or "E"(Element) instead of "K"(Key)?
  2. I was unsure about how the current files from the set and the map are grouped. Are you okay with the folder name "hashing" or should i create the folders "set" and "map"?

@zFl4wless zFl4wless requested review from appgurueu and removed request for raklaptudirm March 10, 2023 14:45
Copy link
Contributor

@appgurueu appgurueu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set and Map should still have their own files, since they aren't necessarily tied to their Hash* implementations (in general, it is considered good practice to have one interface / class per file). The Set interface doesn't need a get method, has suffices.

The abstract MapSet<K> class should not have a HashMap<K, null> type, but rather any generic Map<K, null>. It should also have an abstract method protected abstract Map<K, null> initMap(); to be overridden. The constructor should then simply be map = initMap(). The HashMapSet<K> class then boils down to Map<K, null> initMap() { return new HashMap<K, null>(); } (this is the Template Method Pattern; TS doesn't allow abstract constructors).

Alternatively, you could make MapSet<K> concrete and have it take the map as a parameter. The HashMapSet<K> would then boil down to constructor() { super(new HashMap<K, null>()); }.

@zFl4wless
Copy link
Contributor Author

zFl4wless commented Mar 11, 2023

Alright, what about my questions in the previous comment?

@appgurueu
Copy link
Contributor

  1. K for Key is definitely fine (e.g. C++ uses this). I prefer this since the items are actually used as keys (into the HashMap). E is what Java uses and is fone too. I haven't seen V yet; it could be argued for since it is a set of values (everything is a value in the end). I'd say all are fine.
  2. The HashMap and HashSet may go in a hashing folder; Set and Map do not belong there however (IMO you can put them straight in the data_structures folder).

@zFl4wless zFl4wless requested a review from appgurueu March 11, 2023 23:24
Copy link
Contributor

@appgurueu appgurueu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution!

@zFl4wless
Copy link
Contributor Author

No problem, it helps me improving too :)

@raklaptudirm raklaptudirm merged commit 63cbf8f into TheAlgorithms:master Mar 12, 2023
@zFl4wless zFl4wless deleted the structure/set branch March 12, 2023 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants