For Looping Link List using Templates - list

Having used the various search engines (and the wonderful stackoverflow database), I have found some similar situations, but they are either far more complex, or not nearly as complex as what I'm trying to accomplish.
C++ List Looping
Link Error Using Templates
C++:Linked List Ordering
Pointer Address Does Not Change In A Link List
I'm trying to work with Link List and Node templates to store and print non-standard class objects (in this case, a collection of categorized contacts). Particularly, I want to print multiple objects that have the same category, out of a bunch of objects with different categories. When printing by category, I compare an sub-object tmpCategory (= "business") with the category part of a categorized contact.
But how to extract this data for comparison in int main()?
Here's what I'm thinking. I create a GetItem member function in LinkList.tem This would initialize the pointer cursor and then run a For loop until the function input matches the iteration number. At which point, GetItem returns object Type using (cursor -> data).
template <class Type>
Type LinkList<Type>::GetItem(int itemNumber) const
{
Node<Type>* cursor = NULL;
for(cursor = first;
cursor != NULL;
cursor = (cursor -> next))
{
for(int i = 0; i < used; i++)
{
if(itemNumber == i)
{
return(cursor -> data);
}
}
}
}
Here's where int main() comes in. I set my comparison object tmpCategory to a certain value (in this case, "Business"). Then, I run a For loop that iterates for cycles equal to the number of Nodes I have (as determined by a function GetUsed()). Inside that loop, I call GetItem, using the current iteration number. Theoretically, this would let the int main loop return the corresponding Node from LinkList.tem. From there, I call the category from the object inside that Node's data (which currently works), which would be compared with tmpCategory. If there's a match, the loop will print out the entire Node's data object.
tmpCategory = "Business";
for(int i = 0; i < myCategorizedContact.GetUsed(); i++)
{
if(myCategorizedContact.GetItem(i).getCategory() == tmpCategory)
cout << myCategorizedContact.GetItem(i);
}
The problem is that the currently setup (while it does run), it returns nothing at all. Upon further testing ( cout << myCategorizedContact.GetItem(i).getCategory() ), I found that it's just printing out the category of the first Node over and over again. I want the overall scheme to evaluate for every Node and print out matching data, not just spit out the same Node.
Any ideas/suggestions are greatly appreciated.

Please look at this very carefully:
template <class Type>
Type LinkList<Type>::GetItem(int itemNumber) const
{
Node<Type>* cursor = NULL;
// loop over all items in the linked list
for(cursor = first;
cursor != NULL;
cursor = (cursor -> next))
{
// for each item in the linked list, run a for-loop
// counter from 0 to (used-1).
for(int i = 0; i < used; i++)
{
// if the passed in itemNumber matches 'i' anytime
// before we reach the end of the for-loop, return
// whatever the current cursor is.
if(itemNumber == i)
{
return(cursor -> data);
}
}
}
}
You're not walking the cursor down the list itemNumber times. The very first item cursor references will kick off the inner-for-loop. The moment that loop index reaches itemNumber you return. You never advance your cursor if the linked list has at least itemNumber items in the list.. In fact, the two of them (cursor and itemNumber) are entirely unrelated in your implementation of this function. And to really add irony, since used and cursor are entirely unrelated, if used is ever less than itemNumber, it will ALWAYS be so, since used doesn't change when cursor advances through the outer loop. Thus cursor eventually becomes NULL and the results of this function are undefined (no return value). In summary, as written you will always either return the first item (if itemNumber < used), or undefined behavior since you have no return value.
I believe you need something like the following instead:
template< class Type >
Type LinkList<Type>::GetItem(int itemNumber) const
{
const Node<Type>* cursor = first;
while (cursor && itemNumber-- > 0)
cursor = cursor->next;
if (cursor)
return cursor->data;
// note: this is here because you're definition is to return
// an item COPY. This case would be better off returning a
// `const Type*` instead, which would at least allow you to
// communicate to the caller that there was no item at the
// proposed index (because the list is undersized) and return
// NULL, which the caller could check.
return Type();
}

Related

what is wrong with this reverse linklist code?

var reverseList = function(head) {
function reverse(cur,pre){
if(!cur) return pre
next = cur.next
cur.next = pre
return reverse(next,head)
}
return reverse(head.next,head)
}
I tried a recursion way to write this,
this code output is not correct running, whats wrong with this code?
This is what i think:
If we go by your logic for let's say this case (1->2->3->null), then end result is - first node has address of second node in its 'next' & second node has address of first in its 'next'. So, a loop is formed (1->2 and 2->1). If you want to print such a list, it'll end up in an infinite loop kind of situation in an online platform.
As Thomas Mailund has correctly pointed out, null list case also needs to be covered.
I'd also suggest you to keep your variable names distinct from each other to avoid confusion.
(e.g. you used 'next' as variable name in your inner function which is used already for linked list).
Taking these factors into consideration, here's the rectified working version of your code:
var reverseList = function(head) {
var r = null;
function reverse(p, q) {
q.next = r;
r = q;
if (p == null) return q;
return reverse(p.next, p);
}
return (!head) ? head : reverse(head.next,head)
}

How to check if element exists in a linked list in c++?

The problem:
Imagine there is a linked list class which has multiple methods to use. The main part of the code is like this:
int main ()
{
List l;
l.push_back (86);
l.push_front (43);
l.push_front (12);
int intToSearchFor = 12;
if (l.exists (intToSearchFor))
{
cout << "(" << intToSearchFor << ") found :)";
}
else
{
cout << "(" << intToSearchFor << ") not found :(";
}
}
As you can see in this piece of code, the List class has two methods to prepend and append new items to the list. And also it has an iterator method which lets us loop over the items and check the data in each node.
The issue?
I want to create a method which check existence of an element. For example l.exists(12) should return either true or false.
My Solution:
Start to loop over the items with iterator.
Check if the item data is equal to the one you are looking for.
If it is equal then return true. Otherwise if there are more items in the list, move into the next item in the list and go to step 2.
If there are no more items in the list return false.
bool List::exists (int x)
{
Iterator it = this->get_iterator ();
do {
if (it.current->data == x) {
return true;
}
it.current = it.current->next;
} while (it.has_more_elements ());
return false;
}
Full answer:
http://cpp.sh/6cfdh
You should check whether a pointer points to nullptr before accessing data pointed by the pointer (see has_more_elements()). Better naming may avoid some confusion.
while(it.current->data!=x && it.has_more_elements())
it.current=it.current->next;
return (it.current->data==x)?true:false;
If x is not present and it reaches end of list, it.current->data will cause run time error as it may be NULL.
while(it.has_more_elements() && it.current->data!=x)
it.current = it.current->next;
return it.current!=NULL;

C++ Recursion variable

I guess my Problem is really easy, but I tried to fix it for hours now, and I don't seem to get it. I have an ast tree (created with boost-library) and im iterating through it with recursion. I'm saving all Nodes in a List of NodeDescriptions, that contain the number of the actual node, the name of the actual Node, and node that is the parent node to the actual node. However, my parent node always has the wrong number. I guess I'm doing something wrong with the scope of my variables, passing it the wrong way, or anything like this. I would be glad if someone could help me:
void convert_to_parsetree(BOOST_SPIRIT_NAMESPACE::tree_match<iterator_t>::const_tree_iterator parse_node, int calNode) {
int remNum = calNode;
std::string node_value(parse_node->value.begin(), parse_node->value.end());
//First Element: Node-Counter, Second Element, Name of Node, Third Element: Parent Node Number
myList.push_back(NodeDescription(counter++, node_value, remNum));
if (parse_node->children.size() > 0) {
if (parse_node->children.size() > 1) {
//std::string value(parse_node->children[0].value.begin(), parse_node->children[0].value.end());
//std::string value2(parse_node->children[1].value.begin(), parse_node->children[1].value.end());
BOOST_SPIRIT_NAMESPACE::tree_match<iterator_t>::const_tree_iterator children_it = parse_node->children.begin();
for (int i = 0; i < parse_node->children.size(); ++i) {
convert_to_parsetree(children_it, counter);
children_it++;
}
} else {
convert_to_parsetree(parse_node->children.begin(), counter);
}
}
}
Quite simple, but somehow it doesn't work. Thanks in Advance and kind regards.
The problem is that in your recursive call, you are passing the value in the global variable counter as the second parameter. However, your recursive function uses the second parameter as the "Parent Node Number" (since it is saved in remNum), and the global counter gets incremented. This means the for loop that iterates over the children with the recursive calls will be passing in a different counter value at each iteration, even though each recursive call is supposed to be from the same "Parent".
The current level of recursion should remember the current counter value as its node number before it is incremented, and this remembered value is what should be passed into each iteration of the for loop.
In the fixed version of the code below, I simplified your function to improve readability.
typedef BOOST_SPIRIT_NAMESPACE::tree_match<iterator_t>::const_tree_iterator
MyTreeIterator;
void convert_to_parsetree (MyTreeIterator parse_node, int parent_number) {
int node_number = counter++;
std::string node_name(parse_node->value.begin(), parse_node->value.end());
myList.push_back(NodeDescription(node_number, node_name, parent_number));
for (MyTreeIterator children_it = parse_node->children.begin();
children_it != parse_node->children.end();
++children_it) {
convert_to_parsetree(children_it, node_number);
}
}

C++ - Single Linked List - Ideas

I want to write a method to remove consecutive items with duplicate data values from a singly linked list. The method should return the number of items removed. The method should clean up memory as required, and should assume that memory was allocated using new.
For example, passing in the list
->a->b->c->c->a->b->b->b->a->null
should result in
->a->b->c->a->b->a->null
and return 3
The list item definition and function declaration are given below
struct litem {
char data;
litem* next;
};
int remove_consecutive_duplicates( litem*& list );
I have a simple logic to check the next element recursively & removing the element if its duplicate.
But, i would like to know how many efficient ways to do this ? All ideas welcome from C++ gurus..
You can use std::list, and before pushing element on it you must check:
if ((*l.rbegin()) == next)
{
return;
}
l.push_back(next);
in meta language:
item = items.first
while (item != null) {
while (item.next != null && item.value = item.next.value) {
temp = item.next
item.next = item.next.next
temp.dispose
}
item = item.next
}
As far as I can see, there's not a lot to optimize here. Returning the number of items used is just a case of incrementing a counter. Basically, if you find that litem->data == litem->next->data, then you need to do the removal like so:
litem* tmpItem = currentItem->next;
currentItem->next = tmpItem->next;
delete tmpItem;
Keep iterating until currentItem->next == NULL, to avoid referencing beyond the end of the list.

Array PopFront Method C++

Trying not to lose it here. As you can see below I have assigned intFrontPtr to point to the first cell in the array. And intBackPtr to point to the last cell in the array...:
bool quack::popFront(int& nPopFront)
{
nPopFront = items[top+1].n;
if ( count >= maxSize ) return false;
else
{
items[0].n = nPopFront;
intFrontPtr = &items[0].n;
intBackPtr = &items[count-1].n;
}
for (int temp; intFrontPtr < intBackPtr ;)
{
++intFrontPtr;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
return true;
}
In the else statement I'm simply reassigning to ensure that my ptrs are where I want them. For some reason I'm popping off the back instead of off the front.
Anyone care to explain?
I'm not entirely sure I understand what you're trying to do, but if I;m guessing right you're trying to 'pop' the 1st element of the array (items[0]) into the nPopFront int reference, then move all the subsequent elements of the array over by one so that the 1st element is replaced by the 2nd, the 2nd by the 3rd, and so on. After this operation, the array will contain one less total number of elements.
Not having the full declaration of the quack class makes most of the following guesswork, but here goes:
I'm assuming that item[0] represents the 'front' of your array (so it's the element you want 'popped').
I'm also assuming that 'count` is the number of valid elements (so item[count-1] is the last valid element, or the 'back' of the array).
Given these assumptions, I'm honestly not sure what top is supposed to represent (so I might be entirely wrong on these guesses).
Problem #1: your nPopFront assignment is reversed, it should be:
nPopFront = items[0].n;
Problem #2; your for loop is a big no-op. It walks through the array assigning elements back to their original location. I think you want it to look more like:
for (int i = 1; i < count; ++i)
{
items[i-1].n = items[i].n; // move elements from back to front
}
Finally, you'll want to adjust count (and probably top - if you need it at all) before you return to adjust the new number of elements in the data structure. The whole thing might look like:
bool quack::popFront(int& nPopFront)
{
if ( count >= maxSize ) return false;
if ( count == 0 ) return false; // nothing to pop
nPopFront = items[0].n;
intFrontPtr = &items[0].n; // do we really need to maintain these pointers?
intBackPtr = &items[count-1].n;
for (int i = 1; i < count; ++i)
{
items[i-1].n = items[i].n; // move elements from back to front
}
count -= 1; // one less item in the array
return true;
}
The original question seems to be that you don't understand why the function popFront returns 3 times when there are 3 elements?
If that's the case, I think you are missing the point of recursion.
When you make a recursive call, you are calling the same function again, basically creating a new stack frame and jumping back to the same function. So if there are 3 elements, it will recurse by encountering the first element, encountering the second element, encountering the third element, returning from the third encounter, returning from the second encounter, and returning from the first encounter (assuming you are properly consuming your array, which you don't appear to be).
The current function cannot return until the recursive call has iterated, thus it may appear to return from the last element before the second, and the second before the first.
That is how recursion works.
I wasn't able to make sense of your example, so I whipped one up real fast:
#include <iostream>
using namespace std;
bool popfront(int* ptr_, int* back_) {
cerr << ptr_[0] << endl;
if(ptr_ != back_) {
popfront(++ptr_, back_);
}
return true;
}
int main() {
int ar[4] = {4,3,2,1};
popfront(ar, ar + 3);
return 0;
}
That's not great, but it should get the point across.
Can't you just use a std::list?
That makes it really to pop from either end using pop_front or pop_back. You can also add to the front and the back. It also has the advantage that after popping from the front (or even removing from the middle of the list) you don't have to shift anything around (The link is simply removed) which makes it much more efficient than what you are, seemingly, proposing.
I'm assuming you're trying to assign the popped value to nPopFront?
bool stack::popFront(int& nPopFront)
{
//items[4] = {4,3,2,1}
if ( intFrontPtr < intBackPtr )
{
nPopFront = *intFrontPtr;
++intFrontPtr;
}
return true;
}
bool quack::popFront(int& nPopFront)
{
if(items.n==0) throw WhateverYouUseToSignalError;
nPopFront = items[0];
for (int =0;i<items.n-1,++i){
items[i]=items[i+1]
}
//update size of items array
}