- Special link-list algorithm help - 14 Updates
- Concept of "cbegin"able? - 1 Update
- Hello, on demand world - 1 Update
- High horse - 4 Updates
- Compilers which produce minimum #include set - 1 Update
- Christianity is a religion - 1 Update
- Concept of "cbegin"able? - 1 Update
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jul 05 09:39PM -0400 I have a two-way link-list that traverses a long chain (10s to 100s of thousands of nodes). The final chain that's prepared is made up of things that are comprised of sub-parts. Initially I start out with something like this: _ _ _ _ _ |a|--|b|--|c|--|d|-- ... --|z| It's a node that's in the range of a..z (26 nodes let's say for this example). I have a control structure that indicates where it starts and stops: struct SControl { SNode *beg; // First node, points to a SNode *end; // Last node, points to z }; In normal processing, need to process other things which produce new node chains, and then inject them into the original a..z node chain, making that chain longer. It can be visualized like this: _ _ _ _ _ |a|--|b|-+ +-|c|--|d|-- ... --|z| | | +-----+ +-----+ | _ _ _ | +-|1|--|2|--|3|-+ So the 1..3 nodes were injected into the a..z chain, making the whole chain longer. This is no problem and I have code which does this nicely. However, when I add these new nodes I maintain information about the injection, resulting in two SControl structs which are populated as such (pseudo-code): SControl nodes[2] = { { a, z }, // First part starts a, ends z { 1, 3 } // Second part starts 1, ends 3 }; From here, I continue processing which may consume/inject nodes here and there, and I need a good way to maintain the beg and end members throughout as they are processed. If node |1| was consumed, then the beg member would need to move to |2|. If |3| was consumed, the end member would need to move to |2|, and so on. If a new |4| node was added after |3|, then the end member needs to move to |4|, and so on. And if 1..3 are all deleted, then its nodes[] entry needs to be set to NULL on both pointers, with |b| being again directly linked to |c|. However, during my processing, I am not maintaining information that is relative to the loaded SControl structure. I simply traverse the chain node-by-node as I go through it. The only solutions I can think of are to (1) add a callback function to my delete_node() function which calls a function designed to scan through nodes[] to see if the node being deleted touches any of the beg or end members indicated, or (2) to add a new member to each SNode struct which is a pointer to the parent SControl it relates to. (1) is doable and is my algorithm of choice at present, and (2) seems like it would waste memory but be faster. Does anybody have better suggestion or an alternate algorithm? Thank you in advance. -- Rick C. Hodgin |
Siri Cruise <chine.bleu@yahoo.com>: Jul 05 07:55PM -0700 In article <phmh9a$514$1@dont-email.me>, > { a, z }, // First part starts a, ends z > { 1, 3 } // Second part starts 1, ends 3 > }; Why? If this is what is causing you problems, reconsider if you need it. If you're doing this to impose a tree on the list, why not use a tree? -- :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @ 'I desire mercy, not sacrifice.' /|\ I'm saving up to buy the Donald a blue stone This post / \ from Metebelis 3. All praise the Great Don! insults Islam. Mohammed |
nobody@example.org (Scott): Jul 06 05:03AM On Thu, 5 Jul 2018 21:39:52 -0400, "Rick C. Hodgin" >However, during my processing, I am not maintaining information that >is relative to the loaded SControl structure. I simply traverse the >chain node-by-node as I go through it. ... >Does anybody have better suggestion or an alternate algorithm? Most of the time, if adding or removing linked list nodes involves scanning the list, it means you're not really understanding how to use a linked list. That said, it seems to me that your data structure is really a list of lists. In your example, you'd begin with a list of one list [A-Z], and end up with a list of three lists [A-B], [1-3] and [C-Z]. Keeping track of all the endpoints is automatic and inherent to the data structure, with no cruft. |
Rosario19 <Ros@invalid.invalid>: Jul 06 11:58AM +0200 On Thu, 5 Jul 2018 21:39:52 -0400, "Rick C. Hodgin" wrote: > +-----+ +-----+ > | _ _ _ | > +-|1|--|2|--|3|-+ for me you have to have at last one pointer to the first node of the list so the situation is pointerStart->|a|--|b|-+ +-|c|--|d|-- ... --|z| | | +-----+ +-----+ | _ _ _ | +-|1|--|2|--|3|-+ and when add some sub node pointerStart can change example pointerStart->+ |a|-|b|-|c|--|d|-- ... --|z| | | | +-----+-----+ | _ _ _ | +-|1|--|2|--|3|-+ if double linked list for find the node |z| it would be enougt node |1| (or in general the first node or the node pointerStart point to) has its prec pointer point to |z| the last but possible i remember wrong... what i remember of my linker list is that each linked list and each node of it has one value, one signature that identify the list ( i don't remember why i put the extra space, possibly for not make easy using some data trhu some pointer for corrupt all the list) linkedList a; a would be u32* pointeStart u32 size u32 randomValueIdentifyTheList but possible i not understand |
Richard Damon <Richard@Damon-Family.org>: Jul 06 10:20AM -0700 On 7/5/18 6:39 PM, Rick C. Hodgin wrote: > it would waste memory but be faster. > Does anybody have better suggestion or an alternate algorithm? > Thank you in advance. A fundamental property is that if an update to object A requires some change to object B then there needs to be some way to find object B given object A. It helps to have those changes to object A be localized (so the code to initiate the update to B is also localized). Your comment that you are not maintaining the information in SControl says that something is not being done right. If the SControl information is fundamental to the list operation, then it should be part of it, and the maintenance of it part of the primitives. If the SControl information is an addon, then the list operations wouldn't have that information, but all accesses to the list should be through an API layer that uses the basic list operations but adds the needed updates to the SControl structures. In C++, you could make this SControl based list derive from the basic linked list, and use virtual functions to do this API redirect, allowing much of the code to not need to know the distinction. This is harder to do is C. |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jul 06 01:35PM -0400 On 7/6/2018 1:20 PM, Richard Damon wrote: > (so the code to initiate the update to B is also localized). > Your comment that you are not maintaining the information in SControl > says that something is not being done right. Oh, I thought I did make it clear above that I am maintaining SControl. It is setup to be as the structure and pseudo-code initialization data above indicates. I have the initial list from a..z, and as portions are added, such as the 1..3 portion, the SControl list expands to hold all start/end nodes for each portion of the link list > If the SControl information is fundamental to the list operation, then > it should be part of it, and the maintenance of it part of the primitives. Agreed. This is my current solution the (1) solution above. > wouldn't have that information, but all accesses to the list should be > through an API layer that uses the basic list operations but adds the > needed updates to the SControl structures. .. > linked list, and use virtual functions to do this API redirect, allowing > much of the code to not need to know the distinction. This is harder to > do is C. I appreciate the consideration, thought, and advice, Richard. I have considered using C++ for this code, but my goals are toward CAlive, and whereas I will support some features of C++ in CAlive, I will not support them all, nor even 1/3rd of them. As such, I stick closer to C until I am able to later boostrap my code in my language, and expand it as the needs arise. -- Rick C. Hodgin |
Bart <bc@freeuk.com>: Jul 06 08:17PM +0100 On 06/07/2018 18:35, Rick C. Hodgin wrote: > above indicates. I have the initial list from a..z, and as portions > are added, such as the 1..3 portion, the SControl list expands to hold > all start/end nodes for each portion of the link list Are there only two levels of list? So you can't have this: A B C D 1 2 3 x y Is it possible for two second level lists to meet? Like this: A B C D 1 2 3 x y Can a second level list be before the first top-level item or after the last? Like this: A B C D or: A B C D 1 2 3 1 2 3 Can items from the top level list be deleted to result in any of those situations? Will there always be one top level portion, and 0 to N second level lists? Can the top level list be empty? Can it become empty while there are still second level lists? Is the control structure also a linked list? Is the first entry always the bounds of the top level list, and any subsequent ones always the second level? How is the insertion point specified; would it be {B,C} for my top example (so always with two elements), or after {B} or before {C}? If a second level span is deleted, does its entry disappear in the control structure? (Here whether it is a linked list is important; if not, then any back pointers into it will be problematical if the list needs to close up.) Sorry these are just random questions but you need to know the answers before attempting any coding and I think we're all somewhat in the dark. So a more rigorous specification might be in order. -- bart |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jul 06 03:28PM -0400 On 7/6/2018 3:17 PM, Bart wrote: >> are added, such as the 1..3 portion, the SControl list expands to hold >> all start/end nodes for each portion of the link list > Are there only two levels of list? There are no levels. It is a continuous list that is at the same level. > 1 2 3 1 2 3 > Can items from the top level list be deleted to result in any of those > situations? The 1 2 3 items are simply injected somewhere between A and Z in the A B C .. X Y Z chain. > second level lists? > Is the control structure also a linked list? Is the first entry always the > bounds of the top level list, and any subsequent ones always the second level? For the SControl structure, I use something called a builder, which is an array that expands up/down as needed. It basically contains these members: struct SBuilder { char* buffer; int populated_length; int allocated_length; }; When allocated, populated_length is 0, allocated_length is some pre- defined size (like 4KB). Each SControl structure is 8 bytes, for example. So it continues up to reach 4KB before it re-allocates and expands its size. So, to answer succinctly: they are sequential in a buffer. > How is the insertion point specified; would it be {B,C} for my top example > (so always with two elements), or after {B} or before {C}? You can add before or after any node. In my original example, the chain 1..2..3 exists, and it is inserted between b and c, meaning it could be injected after b, or before c. > Sorry these are just random questions but you need to know the answers before > attempting any coding and I think we're all somewhat in the dark. > So a more rigorous specification might be in order. It's more or less as I laid out. A literal two-way link-list, and it has pointers to the start and end of each chain, and those chains can be inserted anywhere in the middle of the list. And after they are inserted, any of them can be deleted, or have others inserted, before or after, any other node. -- Rick C. Hodgin |
Bart <bc@freeuk.com>: Jul 06 09:22PM +0100 On 06/07/2018 20:28, Rick C. Hodgin wrote: >>> all start/end nodes for each portion of the link list >> Are there only two levels of list? > There are no levels. It is a continuous list that is at the same level. So you insert {1 2 3} between B and C in {A B C D} to result in: A B 1 2 3 C D This is just ordinary linked list processing where you insert or delete single items or insert sequences. But you have a separate structure that keeps tabs on certain subsequences in that list (like the injected {1 2 3} sequence, but noting the start and end item (as {1, 3} for this example), as well as the original starting sequence {A,D}. And you want to keep that structure up to date as a subsequences change. Adding extra stuff in the middle is not a problem (if allowed), but removing one of the end items (or the only item if subsequence is only one element long) means an update in the other structure. It sounds like you would rather not add extra links to each node to point into an entry in that structure but that seems the most sensible to me. This can be done with a link in each node of an insertion (but a long insertion can mean 1000s of updates). Or possible a link on the start item only, but this means that if deleted an item in the middle, you have to search for the start node. -- bart |
Anton Shepelev <anton.txt@gmail.com>: Jul 06 11:23PM +0300 Rick C. Hodgin: > is doable and is my algorithm of choice at present, and (2) seems like > it would waste memory but be faster. > Does anybody have better suggestion or an alternate algorithm? Can you maintain hash-tables of all the 'beg' and 'end' members and a. at deletion check whether the node being deleted is the beginning or the end of some chain, b. at insertion check whether the node before the one inserted is the end of some chain and the node after the one inserted is the beginning of some chain? That should work in O(1) time. -- () ascii ribbon campaign -- against html e-mail /\ http://preview.tinyurl.com/qcy6mjc [archived] |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jul 06 04:30PM -0400 On 7/6/2018 4:22 PM, Bart wrote: > that list (like the injected {1 2 3} sequence, but noting the start and end > item (as {1, 3} for this example), as well as the original starting sequence > {A,D}. Correct. > Adding extra stuff in the middle is not a problem (if allowed), but removing > one of the end items (or the only item if subsequence is only one element > long) means an update in the other structure. Correct. > It sounds like you would rather not add extra links to each node to point > into an entry in that structure but that seems the most sensible to me. It's my second option, and one I'm leaning toward the more I think about it. > insertion can mean 1000s of updates). Or possible a link on the start item > only, but this means that if deleted an item in the middle, you have to > search for the start node. Correct. And memory's cheap these days. -- Rick C. Hodgin |
Richard Damon <Richard@Damon-Family.org>: Jul 06 03:38PM -0700 On 7/6/18 10:35 AM, Rick C. Hodgin wrote: > above indicates. I have the initial list from a..z, and as portions > are added, such as the 1..3 portion, the SControl list expands to hold > all start/end nodes for each portion of the link list My comment was about your statement that: >>> However, during my processing, I am not maintaining information that >>> is relative to the loaded SControl structure. I simply traverse the >>> chain node-by-node as I go through it. If keeping these structures up to date is part of your requirements, then you need to maintain them. This should be part of your basic design, not something you try to 'bolt on' at the end. (And late changes of this type can be costly is development and/or processing time). >> it should be part of it, and the maintenance of it part of the >> primitives. > Agreed. This is my current solution the (1) solution above. (1) Using call backs would be more in line with my second case, where the SControl is considered an addon, and the basic list routines are providing hooks for a higher level set of controls. Your (2), putting a pointer to the SControls (you need plural, probably through a form of linked list) that started it would be one way to build it in, and likely the fastest. Cheaper on memory but more costly on time would be to have a list of the SControl structures available, and scan them every time you delete a node. > them all, nor even 1/3rd of them. As such, I stick closer to C until I > am able to later boostrap my code in my language, and expand it as the > needs arise. I gave some C++ advise, as you posted to both comp.lang.c and comp.lang.c++, while C++ derived from C, the 'C++ way' to do things is very often very different from the 'C Way' to do things. |
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Jul 06 03:51PM -0700 On 7/5/2018 6:39 PM, Rick C. Hodgin wrote: > +-----+ +-----+ > | _ _ _ | > +-|1|--|2|--|3|-+ Fwiw, one hackish way to identify a user node from a SControl node would be to steal a low order bit and use it as a tag. a -> b c -> d -> ... -> z | ^ v | cs(b->1) cs(3->c) | ^ v | 1 -> 2 -> 3 b would have a control structure that made it point to 1 -> 2 -> 3 3 would have a control structure that made it point to c -> d -> ... -> z. Check the stolen bit in the pointer value to tell normal nodes to ones with control structures. b and 3 would have this bit set. All others would not. Still not exactly sure why a double linked list would not work out here. One can easily inject multiple nodes at once anywhere in a doubly linked list. The stolen bits trick can allow for multiple different data structures to exist in the same overall data-structure. It tells us what type the pointer is pointing too. |
Richard Damon <Richard@Damon-Family.org>: Jul 06 04:24PM -0700 On 7/6/18 3:51 PM, Chris M. Thomasson wrote: > Still not exactly sure why a double linked list would not work out here. > One can easily inject multiple nodes at once anywhere in a doubly linked > list. He says the list is a "two-way linked-list", so I presume that is what you mean by double linked list (a has a pointer to b, and b has a back pointer to a). What it seems that Rick wants is to have saved "sub lists" on the main list so that he can either navigate the whole list a-b-1-2-3-c-d-e-... or he could navigate the sub list of 1-2-3 by calling up the SControl structure for the list (start at beg, and go till you have visited end). |
ram@zedat.fu-berlin.de (Stefan Ram): Jul 06 06:05PM >On 06/30/2018 09:30 AM, Stefan Ram wrote: >>Do C++ programmers have a word for a value that will yield an ^^^^^^^^^^^^^^^^^^ >>iterator when being the argument value in a call to cbegin? ^^^^^^^^ |
woodbrian77@gmail.com: Jul 06 10:22AM -0700 > six months on your project if we use my software as > part of the project. There are more details here: > http://webEbenezer.net/about.html This is still available. Brian |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jul 05 08:40PM -0400 On 07/05/2018 04:11 AM, Ian Collins wrote: > On 16/06/18 11:54, James Kuyper wrote: >> On 06/15/2018 05:30 PM, Ian Collins wrote: >>> On 16/06/18 03:47, James Kuyper wrote: ... > The key point form my side is that there often aren't "true > requirements", at least not in great detail. The customer says she > wants something to happen when an item is selected, she doesn't care how! The true requirements are the ones that the customer would articulate, if she could, and it's the system analyst's job to help her do so. I have met people so inarticulate that they've done the equivalent of claiming that the only requirement on the function sum() is that sum(1,2)==3. However, I've usually been able to convince them that what they actually mean is that sum(x,y) should return the sum of x and y. In more complicated cases, where I couldn't figure out what they were asking for the program to do, I've refused to start work on the program until they could articulate it more clearly - giving them the equivalent of int sum(int x, int y) { return 3;} would not have served any useful purpose. I was once hired specifically because of my expertise in APL, to take existing APL code and modify it to achieve a particular goal. I had no trouble reading the other guy's APL code (well-written APL is NOT actually a write-only language, jokes to the contrary notwithstanding). However, I could never get a clear explanation from my boss of what the modified program should do. So I spent most of my time of that job doing other tasks that involved C and PC/FOCUS. >> the possible inputs. I find it easier to imagine such software if it's >> only a small subroutine, and not an entire application. > You could argue the same form any testing philosophy. To the best of my knowledge, TDD is the only testing philosophy for which it is claimed, at least by some people, that the tests define the requirements. Therefore, it's the only one for which the fact that they can't define the requirements is a problem. Other testing philosophies, at least implicitly, accept that what tests can do is limited to sparsely sampling the set of all possible inputs, looking for failures to meet requirements. The key implication is that while failing a test proves that a requirement has not been met, passing all test does NOT prove that all requirements have been met. Therefore, the test can never be treated as semantically equivalent to a proper statement of the requirements. |
Ian Collins <ian-news@hotmail.com>: Jul 06 10:03PM +1200 On 06/07/18 12:40, James Kuyper wrote: >> wants something to happen when an item is selected, she doesn't care how! > The true requirements are the ones that the customer would articulate, > if she could, and it's the system analyst's job to help her do so. Most small software outfits don't have system analysts! > To the best of my knowledge, TDD is the only testing philosophy for > which it is claimed, at least by some people, that the tests define the > requirements. Maybe we should say in many cases, the TDD tests are the only form of requirements... -- Ian. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jul 06 07:33AM -0400 On 07/06/2018 06:03 AM, Ian Collins wrote: > On 06/07/18 12:40, James Kuyper wrote: >> On 07/05/2018 04:11 AM, Ian Collins wrote: >>> On 16/06/18 11:54, James Kuyper wrote: ... >> The true requirements are the ones that the customer would articulate, >> if she could, and it's the system analyst's job to help her do so. > Most small software outfits don't have system analysts! Which means that some person who has other tasks as well, possibly without adequate training, will have to act as a system analyst when dealing with the customer. That's no different, in principle, from the fact that sufficiently small outfits also don't necessarily have a single person specializing in HR, or Marketing, or QA, or testing, or Accounting, or janitorial work. Sufficiently small outfits don't even have someone specializing in management - the "Boss" may simply be one of the developers who also performs management tasks. Each of those tasks still need to be done, even if there's not enough work to justify hiring a specialist to do it. However, the lack of specialization also means that the task might not be done as well as it could have been done by a specialist. >> requirements. > Maybe we should say in many cases, the TDD tests are the only form of > requirements... Inadequately defined requirements are a very common problem - but that problem should be acknowledged as such. Formal requirements which are cross-referenced by the tests, rather than being defined by them, should at least be acknowledged as an inconvenient but desirable ideal. Instead, the supposed lack of need for such requirements seems to be trumpeted as an advantage of TDD, at least by some people. |
woodbrian77@gmail.com: Jul 06 10:13AM -0700 On Sunday, June 24, 2018 at 2:04:18 AM UTC-5, bitrex wrote: Brian Ebenezer Enterprises - Enjoying programming again. https://github.com/Ebenezer-group/onwards |
Manfred <invalid@add.invalid>: Jul 06 01:06PM +0200 On 7/5/2018 8:58 PM, Bart wrote: > I would say that that was quite difficult to do. In fact it is not how <windows.h> is supposed to be used. > Such a header will anyway be the result of one 'rendering' of a header; > the next one may produce different results because there has been a > subtle change in the environment. It is much better to use the #define's that are indicated in <windows.h> #define WIN32_LEAN_AND_MEAN will result in a minimal set, otherwise macros like NOGDI will suppress the related items (GDI functionality in this case) |
Random news lurker <grobbel@gmail.com>: Jul 06 09:03AM > > > The imposter here posted from an "en-GB" timezone using Giganews. > > I hope all of the mimicry could be halted sometime.... > where is rick now? I hope he is doing well. Yes, he is a bit odd, but isn't everyone who is still reading newsgroups? His non-relevant posting are just as easily skipped as the Amine's for instance, but the hatefull replies hurt my old eyes. A nice day to all who make this group worth reading! |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jul 05 08:08PM -0400 On 06/30/2018 09:30 AM, Stefan Ram wrote: > For example, cbegin would meaningfully accept an array, > a vector, an initialization list, or a string, but not > a pair (AFAIK), a stream, or a fundamental object. 24.7 p6 describes the only cbegin() in the standard that can take an argument and isn't a member function. It returns std::begin(c), and as a result of using a template with auto and decltype, doesn't care much about what type c or std::begin(c) has. 24.7p1 describes std::begin(c) as returning c.begin(). Again, as a result of templating, auto, and decltype, it doesn't care much what type c or c.begin() has. Therefore, I conclude that the only requirement for cbegin(c) is that c must have a class type with a member function named begin() that can be invoked with no arguments. Am I missing something? If not, is there any point in naming such a concept? |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment