Comparing two different pointers to elements of a linked list - pointers

Anyone knows if there are there any method for comparing the two pointers, let's say there are two pointers ptr1 and ptr2, as shown in the picture, how can i perform some operations similar (ptr2 < ptr1) to check whether a specific pointer passed another pointer, for example to check whether ptr2 passed ptr1 such that ptr2 is on the right side while ptr1 is on the left side. Thank you in advance.

Comparing the pointer values themselves will not tell you which node is before the other one in a linked list. For that you will need to step through your linked list.
You could have these pointers traverse the linked list in tandem. The one that reaches the end of the list first is necessarily the one that is coming after the other one.
In pseudo code (c-style):
int compare(node* ptr1, node* ptr2) {
if (ptr1 == ptr2) return 0; // equal
while (ptr1 != NULL && ptr2 != NULL) {
ptr1 = ptr1->next;
ptr2 = ptr2->next;
}
return ptr2 == NULL ? -1 : 1;
}
If the list is long, and the pointers are not far from each other, you can gain some time by also checking whether one of the traversing pointers becomes equal to an original pointer. Then you can also take your conclusions:
int compare(node* ptr1, node* ptr2) {
if (ptr1 == ptr2) return 0; // equal
cur1 = ptr1;
cur2 = ptr2;
while (true) {
if (cur2 == NULL || cur1 == ptr2) return -1; // ptr1 before ptr2
if (cur1 == NULL || cur2 == ptr1) return 1; // ptr2 before ptr1
cur1 = cur1->next;
cur2 = cur2->next;
}
}
All this assumes that the given pointers are both pointing to members of the same linked list. With the above function you can now do:
// ...
int res = compare(ptr1, ptr2);
if (res < 0) output("*ptr1 comes before *ptr2");
if (res > 0) output("*ptr1 comes after *ptr2");
if (res == 0) output("*ptr1 is the same as *ptr2");

Related

Palindrome check throws infinite loop (using iterator and linked lists collection)

I´m trying to write a method to determine if a singly linked list of type string is a palindrome.
The idea is to copy the second half to a stack, then use an iterator to pop the elements of the stack and check that they are the same as the elements from 0 to around half of the singly linked list.
But my iterator method is throwing an infinite loop:
public static boolean isPalindrome(LinkedList<String> list, Stack<String> stack ) {
int halfList = (int) Math.ceil(list.size()/2); // we get half the list size, then round up in case it´s odd
// testing: System.out.println("half of size is " + halfList);`
// copy elements of SLL into the stack (push them in) after reaching the midpoint
int count = 0;
boolean isIt = true;
Iterator<String> itr = list.iterator();
Iterator<String> itr2 = list.iterator();
System.out.println("\n i print too! ");
// CHECK!! Node head = list.element();
// LOOP: traverse through SLL and add the second half to the stack (push)
// if even # of elements
if ( list.size() % 1 == 0 ) {
System.out.println("\n me too! ");
while ( itr.hasNext() ) {
String currentString = itr.next(); // this throws an exception in thread empty stack exception
count ++;
if ( count == halfList ) stack.push(list.element());
// THIS IS THE INFINITE LOOP
System.out.println("\n me three! ");
}
}
// else, if odd # of elements
else {
while ( itr.hasNext() ) {
count ++;
if ( count == halfList -1 ) stack.push(list.element());
}
}
// Now we compare the first half of the SLL to the stack (pop off elements)
// even
if ( list.size() % 1 == 0 ) {
while ( itr2.hasNext() ) {
count ++;
if ( count == halfList +1 ) break;
int compared = stack.pop().compareTo(list.element());
if ( compared != 0) isIt = false; // if when comparing the two elements, they aren´t similar, palindrome is false
}
}
// odd
else {
while ( itr2.hasNext() ) {
count ++;
if ( count == halfList ) break;
int compared = stack.pop().compareTo(list.element());
if ( compared != 0) isIt = false;
}
}
return isIt;
}
What am I doing wrong?
There are many issues:
list.size() % 1 == 0 is not checking whether the size is even. The correct check is % 2.
The stack exception cannot occur on the line where you put that comment. It occurs further down the code where you have stack.pop(). The reason for this exception is that you try to pop an element from a stack that has no more elements.
The infinite loop does not occur where you put that comment. It would occur in any of the other loops that you have further in the code: there you never call itr.next() or itr2.next(), and so you'll loop infinitely if you ever get there.
The stack never gets more than 1 value pushed unto it. This is because you have a strict equality condition that is only true once during the iteration. This is not what you want: you want half of the list to end up on the stack. This is also the reason why you get a stack error: the second half of your code expects there to be enough items on the stack.
push(list.element()) is always going to push the first list value to the stack, not the currently iterated one. This should be push(currentString).
count ++; is placed at an unintuitive place in your loops. It makes more sense if that line is moved to become the last statement in the loop.
The if ( count statements are all wrong. If you move count ++ to be the last statement, then this if should read if ( count >= halfList ) for the even case, and if ( count > halfList ) for the odd case. Of course, it would have been easier if halfList would have been adapted, so that you can deal equally with the odd and even case.
The second part of your code has not reset the counter, but continues with count ++. This will make that if ( count == halfList ) is never true, and so this is another reason why the stack.pop() will eventually raise an exception. Either you should reset the counter before you start that second half (with count = 0;) or, better, you should just check whether the stack is empty and then exit the loop.
The second half of your code does not need to make the distinction between odd or even.
Instead of setting isIt to false, it is better to just immediately exit the function with return false, as there is no further benefit to keep on iterating.
The function should not take the stack as an argument: you always want to start with an empty stack, so this should be a local variable, not a parameter.
There is no use in doing Math.ceil on a result that is already an int. Division results in an int when both arguments are int. So to round upwards, add 1 to it before dividing: (list.size()+1) / 2
Avoid code repetition
Most of these problems are evident when you debug your code. It is not so helpful to put print-lines with "I am here". Beter is to print values of your variables, or to step through your code with a good debugger, while inspecting your variables. If you had done that, you would have spotted yourself many of the issues listed above.
Here is a version of your code where the above issues have been resolved:
public static boolean isPalindrome(LinkedList<String> list) {
Stack<String> stack = new Stack<String>();
int halfList = (list.size()+1) / 2; // round upwards
Iterator<String> itr = list.iterator();
while (halfList-- > 0) itr.next(); // skip first half of list
while ( itr.hasNext() ) stack.push(itr.next()); // flush rest unto stack
Iterator<String> itr2 = list.iterator();
while ( itr2.hasNext() && !stack.empty()) { // check that stack is not empty
if (stack.pop().compareTo(itr2.next()) != 0) return false; // no need to continue
}
return true;
}

Exiting reading two strings with gets in do while loop

I am trying to ask a user to type two strings and then the system makes some action as concatenation.
The program I want to be executed at least once and when the first string is equal to '0' to exit.
Could you please help me do it ?
Because something I make wrong.
#include<stdio.h>
int main()
{
char s1[100],s2[100];
int len = 0;
do
{
len = strlen(s1);
printf("\nString1:");
gets(s1);
printf("String2:");
gets(s2);
} while(s1[0] == '0' && s1[len-1] =='\0');
return 0;
}
Thanks in advance
As per the condition (s1[0] == '0' && s1[len-1] == '\0') the loop will continue only if the first string is '0' and the second string is blank. For all other inputs the loop will exit.
I think your requirement is the condition (s1[0] != '0')

How can lParam be casted into more than one structures?

I saw this piece of code below in here. I tested it and it works all right.
// g_hLink is the handle of the SysLink control.
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code) // CAST TO NMHDR*
{
case NM_CLICK: // Fall through to the next case.
case NM_RETURN:
{
PNMLINK pNMLink = (PNMLINK)lParam; // CAST TO NMLINK*
LITEM item = pNMLink->item;
if ((((LPNMHDR)lParam)->hwndFrom == g_hLink) && (item.iLink == 0))
{
ShellExecute(NULL, L"open", item.szUrl, NULL, NULL, SW_SHOW);
}
else if (wcscmp(item.szID, L"idInfo") == 0)
{
MessageBox(hDlg, L"This isn't much help.", L"Example", MB_OK);
}
break;
}
}
break;
The parameter lParam is casted to both NMHDR* and NMLINK* types. The documentation of WM_NOTIFY message says that lParam can be casted to NMHDR*, but NMLINK is a different structure which encapsulates NMHDR.
What does actually happen when we cast lParam to an arbitrarily chosen structure between these two?
NMLINK contains NMHDR as its first element:
struct NMLINK {
NMHDR hdr;
LITEM item;
};
And so pointer to NMLINK equals to the pointer to its first member (which is NMHDR structure sitting at offset 0), they are the same. It means that you can cast NMHDR* to NMLINK*.

map interface pointer method receiver

I have a the following code
http://play.golang.org/p/d-bZxL72az
package main
import "fmt"
type Variables struct {
sum uint64
highest uint64
}
type Data struct {
count uint64
mValue map[string]Variables
}
func (v Variables) Add(value Variables) Variables {
v.sum += value.sum
if v.highest == 0 {
v.highest = value.highest
} else if v.highest < value.highest {
v.highest = value.highest
}
return v
}
func (v *Variables) AddPointer(value Variables) {
v.sum += value.sum
if v.highest == 0 {
v.highest = value.highest
} else if v.highest < value.highest {
v.highest = value.highest
}
}
func main() {
var instances [2]Variables
instances[0] = Variables{sum: 5, highest: 3}
instances[1] = Variables{sum: 10, highest: 2}
var d Data
d.mValue = make(map[string]Variables)
for i:= 0; i < len(instances); i++ {
d.mValue["one"] = d.mValue["one"].Add(instances[i])
d.mValue["two"].AddPointer(instances[i])
}
fmt.Println(d.mValue["one"])
fmt.Println(d.mValue["two"])
}
I get the error
# command-line-arguments
/tmp/sandbox209565070/main.go:42: cannot call pointer method on d.mValue["two"]
/tmp/sandbox209565070/main.go:42: cannot take the address of d.mValue["two"]
(I think) I understand the second error cannot take address - because, it is a map, it cannot take the address (is that correct?)
Is it the same reason for the first error as well (cannot call pointer method)?
Is there a way to use pointer methods on structures that are within the maps..
Yes, same reason. In order to call a method with a pointer receiver, you either need to have a pointer in the first place, or you need an addressable value and Go will automatically take the pointer for you.
What you can do, then, is to make mValue a map[string]*Variables instead of a map[string]Variables. Then you will be storing a pointer to an already-allocated, guaranteed-addressable Variables in the map, and you'll be able to call methods on that pointer.
To expand on the previous answer…
In practice, this isn't usually a problem. If the type makes more sense without pointers (e.g. a small struct where value semantics make more sense) then you wouldn't have pointer receivers and the issue wouldn't arise.
If pointer receivers make sense then you should probably be using pointers to the type in most places, such as in maps (as hobbs said) and you wouldn't have methods that took non-pointer arguments or returned non-pointer values (non-pointer receivers could still make sense and would be easy to use). Again, the issue wouldn't arise.
In the first case if you wanted to use a pointer receiver with a non-pointer map entry, you could use a temporary (addressable) variable and reassign it back into the map.
x := d.mValue["two"]
x.AddPointer(instances[i])
// AddPointer uses a pointer receiver; `x` needs to be addressable,
// it will contain a copy of the value from the map and that copy may
// be changed by the method so we need to copy the new version back
// into the map.
d.mValue["two"] = x
In the second case a few issues arise. First, to avoid nil pointers you need to either initialize the map entries or check for nil/existance on map reads (or make make your pointer receiver methods handle nil valued receivers, but that doesn't help for non-pointer receiver methods though). Second, if for some silly reason you have pointers but still have a method that returned a non-pointer you'd have to use a different syntax to assign to the map.
Something like this perhaps:
// Initialize some map entries to avoid nil pointers
d.mValue = map[string]*Variables{
"one": &Variables{},
"two": &Variables{},
}
for i := 0; i < len(instances); i++ {
// Just calling the non-pointer reciever is easy/fine:
d.mValue["one"].Add(instances[i])
// But you can't do this:
//d.mValue["one"] = d.mValue["one"].Add(instances[i])
// cannot use d.mValue["one"].Add(instances[i]) (type Variables) as type *Variables in assignment
*d.mValue["one"] = d.mValue["one"].Add(instances[i])
d.mValue["two"].AddPointer(instances[i])
}

QGraphicsItem: Why no `stackAfter` method?

I'm having an annoying time trying to get around the 'recommended' way of doing something.
So, I have a stack of cards. I want to make it so that when I deal a card, it becomes the last-drawn object of the entire scene (typical bring_to_front functionality).
The recommended way to do this is just adding to the object's zValue until it is larger than all the rest, but I was hoping to do away with rather "lazy" integers running around all over the place with judicious use of the stackBefore method, which simulates reorganizing the order in which objects were added to the scene.
This works perfectly fine when I shuffle my cards in a limited set (get list of selected items, random.shuffle, for item do item.stackBefore(next item)), but it is certainly not working when it comes to bubbling the card to the top of the entire scene.
I considered adding a copy of the object to the scene and then removing the original, but it just seems like I should be able to do stackAfter like I would when using a Python list (or insertAt or something).
Sample code:
def deal_items(self):
if not self.selection_is_stack():
self.statusBar().showMessage("You must deal from a stack")
return
item_list = self.scene.sorted_selection()
for i,item in enumerate(item_list[::-1]):
width = item.boundingRect().width()
item.moveBy(width+i*width*0.6,0)
another_list = self.scene.items()[::-1]
idx = another_list.index(item)
for another_item in another_list[idx+1:]:
another_item.stackBefore(item)
This works. It just seems somewhat... ugly.
self.scene.items returns the items in the stacking order (link). So if you want to stackAfter an item, you can just query the z value of the current topmost item and then set the z value of the new topmost card to a value one larger.
item.setZValue(self.scene.items().first().zValue() + 1)
Hope that helps.
Edit added src for stackBefore and setZValue from http://gitorious.org/qt/
src/gui/graphicsview/qgraphicsitem.cpp
void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
{
if (sibling == this)
return;
if (!sibling || d_ptr->parent != sibling->parentItem()) {
qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
return;
}
QList<QGraphicsItem *> *siblings = d_ptr->parent
? &d_ptr->parent->d_ptr->children
: (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
if (!siblings) {
qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
return;
}
// First, make sure that the sibling indexes have no holes. This also
// marks the children list for sorting.
if (d_ptr->parent)
d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
else
d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
// Only move items with the same Z value, and that need moving.
int siblingIndex = sibling->d_ptr->siblingIndex;
int myIndex = d_ptr->siblingIndex;
if (myIndex >= siblingIndex) {
siblings->move(myIndex, siblingIndex);
// Fixup the insertion ordering.
for (int i = 0; i < siblings->size(); ++i) {
int &index = siblings->at(i)->d_ptr->siblingIndex;
if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
++index;
}
d_ptr->siblingIndex = siblingIndex;
for (int i = 0; i < siblings->size(); ++i) {
int &index = siblings->at(i)->d_ptr->siblingIndex;
if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
siblings->at(i)->d_ptr->siblingOrderChange();
}
d_ptr->siblingOrderChange();
}
}
void QGraphicsItem::setZValue(qreal z)
{
const QVariant newZVariant(itemChange(ItemZValueChange, z));
qreal newZ = newZVariant.toReal();
if (newZ == d_ptr->z)
return;
if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
// Z Value has changed, we have to notify the index.
d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
}
d_ptr->z = newZ;
if (d_ptr->parent)
d_ptr->parent->d_ptr->needSortChildren = 1;
else if (d_ptr->scene)
d_ptr->scene->d_func()->needSortTopLevelItems = 1;
if (d_ptr->scene)
d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
itemChange(ItemZValueHasChanged, newZVariant);
if (d_ptr->flags & ItemNegativeZStacksBehindParent)
setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
if (d_ptr->isObject)
emit static_cast<QGraphicsObject *>(this)->zChanged();
}

Resources