|
Ok so I get the initials bit, but how does "bad first" mean take the first letter of each following word?
|
|
|
|
|
"Bad" because the first letters are not in order. They were in my initial response but that was a typo on my part.
It goes without saying
|
|
|
|
|
I obviously didn't pay much attention to the letters in your solution.
|
|
|
|
|
I've implemented a list with circular buffer semantics meaning adding or removing from either end of the list is very efficient.
Because of this, the list can be efficiently used as a queue, a double ended queue, or a stack.
Well, right now I don't have any special methods to reflect the more efficient add and remove ops.
Doing an efficient add just means list.Add(item) for the end or list.Insert(0,item) for the beginning. Doing an efficient remove is similar with either list.RemoveAt(0) or list.RemoveAt(list.Count-1) .
My question is this - should I add special methods for these efficient ops and if so what should they be?
I can go the .NET route that MS took and add methods like Enqueue() and Dequeue() (queue-like) but that only covers adding to the back, and removing from the front. I can add Pop() and Push() (stack-like) but that only covers adding and removing from the back. I can add both but that's cluttered and sill doesn't handle removing from the front.
Or I can take a page from C++/STL and add methods like PushFront() and PushBack() and similar remove methods, even though there's nothing in .NET like this.
Or I can just not add those extra methods and I can document the existing methods with the specially performing cases.
What would you do? Any ideas?
Real programmers use butterflies
|
|
|
|
|
How come there's any end to a circular thing?
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
because that's just the underlying data structure.
Real programmers use butterflies
|
|
|
|
|
That was more of a mathematician's observation rather than a developper's one.
Naming the methods, though, is more of a preferences' question. It does not really matter provided their behaviour is clearly and unambiguously documented.
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
So, since you Add and Remove from the underlying structure, you need to aim your naming towards that as well.
|
|
|
|
|
I mean right, but microsoft adds and removes to queues with Enqueue and Dequeue, and to stacks with Push and Pop, not Add or Remove
I'd rather follow their conventions as much as I can in .NET. I believe in when in rome when it comes to interface design.
Real programmers use butterflies
|
|
|
|
|
For the Circular part I would follow Microsofts convention on their LinkedList. (Which is Circular BTW, Reference Source[^] )
So AddBefore(), AddAfter(), AddFirst(), AddLast(), Remove(), RemoveFirst(), and RemoveLast().
But as soon as you treat it as a List, use the conventions of a list.
|
|
|
|
|
Add them. I don't care much what they're called, but add them. Having a handful of special cases of Insert and RemoveAt means that proper use relies on reciting the Special Magic Words every time.
|
|
|
|
|
fair enough. I'd like some methods too, but i just don't know what to call them. I'll stew on it some more.
Real programmers use butterflies
|
|
|
|
|
Have an Add and a Remove method, but add an overload for the special cases that uses an enum to control where it goes or comes from. Yes, it's a little less efficient (but a delegate table can help with that if the enum indexes into it) but it's a load easier to keep track of mentally than half a dozen or so Add methods.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I think i'll pass on that. It's more types, and it breaks with the way microsoft does things on their list based datastructures like Stack<T> and Queue<T>
Real programmers use butterflies
|
|
|
|
|
What you could do is add them as extension methods, either on your own (base-)class or interface or on IList<T>.
That way, you keep the base interface/implementation clean, while still offering utility methods that possibly extend to every implementation of your interface.
If you go that way, I'd recommend creating an ICircularList<T>, inherit from IList<T>, and add the extension methods there.
Or just add PushFront and PushBack, which is easy and straight-forward
|
|
|
|
|
I actually thought about doing that but I don't want to add them to standard list interfaces, just this one. I don't like putting inefficient methods on standard lists because it will encourage poor programming.
As far as adding them just to the CircularList that way, or creating ICircularList<t>, I don't really want the latter as I'd like to follow what microsoft has done (most of the time) with their list based data structures like Queue<T> and Stack<T> and just create the class itself. I can add extension methods, and I almost did, but the rest of my class is factored as partial classes - CircularList.cs, CircularList.ICollection.cs, CircularList.IList.cs, etc so I'll probably just add it like that.
I'm leaning toward PushFront/PopFront/PushBack/PopBack like STL, because it's also at least somewhat like Microsoft's pattern in .NET
Real programmers use butterflies
|
|
|
|
|
|
First, it's not a linked list, circular or otherwise.
That would be a much different structure, with much different methods.
It's a circular buffer exposed as a IList<T>
Given your seeming confusion about that it might prompt me to rename though i'm not sure to what.
Because it's a circular buffer IList<T> , and ICollection<T> serve me fine. Sure you *can* call Insert(1, item) or RemoveAt(2) and that's not efficient, but it's no less efficient than doing it on a straight List<T> so I'm fine with it.
Real programmers use butterflies
|
|
|
|
|
In this case, all that I would recommend is to write a specialization of the generic Queue<t> collection if it's good for your task, otherwise implement your own.
Specifically, first invoke, for example:
Queue<string> numbers = new Queue<string>();
numbers.Enqueue("one");
numbers.Enqueue("two");
numbers.Enqueue("three");
numbers.Enqueue("four");
numbers.Enqueue("five");
And then, implement some kind of push_front, push_back and pop_front, pop_back, as well as buffer shifting functionality to have an ability to perform circular ops.
|
|
|
|
|
I've already done that. I'm just trying to figure out what to name them.
Right now everything, including the efficient push_back/push_front/etc are done through the IList<t> interface.
Literally all i need to do at this point is just create names for the methods with the efficient ops. the ops are already implemented and exposed through IList<t> standard Insert/Add/Remove/RemoveAt
i think after this thread I'm going with
PushFront/PushBack/PopFront/PopBack
Real programmers use butterflies
|
|
|
|
|
If you use Queue<t> as the base class, then the derived class name should be something kind of CircularQueue<t> and ICircularQueue<t> if it's an interface. Otherwise, try out a different name.
|
|
|
|
|
I'm not deriving from anything. It's backed by an array, just like List<t> is
Real programmers use butterflies
|
|
|
|
|
As I've already explained, the suggestions for the class naming are:
CircularQueue<t> and CircularBuffer<t>
|
|
|
|
|
Also, since you've implemented the functionality required as a C#.NET class library used in your project, then you can name the class and interface such as MyProjCircularBuffer<t> and IMyProjCircularBuffer<t>.
|
|
|
|
|
You ask a lot of programming questions in the Lounge, and to be honest, in my opinion, they should be in the forums where others can benefit from them. The majority of members who use this site are not active participants in the Lounge.
Also, the Lounge is not for programming questions.
I know I came off as a jerk here, but it had to be said.
It's much easier to enjoy the favor of both friend and foe, and not give a damn who's who. -- Lon Milo DuQuette
|
|
|
|