searchable linked list in c++ - c++

everyone
I am working on an RPG game as a class project.
A linked listis used for the inventory.
I try to add a search function since I want the user to be able to sell inventory.
The ideal is that searchItem(string name) takes the given item name and goes through the list finding the name-matched item, then return address of the item. However, when the function called, the IDE throws a EXC_BAD_ACCESS(code=1, adress0x44) error.
I guess it doesn't return the right address but with my current ability, I can't figure out the solution.
Any help will be really appreciated.
Inventory.hpp
#include <stdio.h>
#include <list>
#include <iostream>
#include "Item.hpp"
using namespace std;
class Inventory{
private:
struct Inven{
Item item;
struct Inven *next = nullptr;
};
Inven *head;
public:
Inventory();
~Inventory();
void appandItem(Item obj);
void insertItem(Item obj);
void deleteItem(string name, int qt);
void displayInventory();
Item* searchItem(string name);
};
Inventory.cpp
I only posted searchItem function because others work fine
Item* Inventory::searchItem(string name){
// to go through the inventory
Inven *itemPtr = nullptr;
// to point to the previous item
Inven * previousItem = nullptr;
// if the invnetory is empty, nothing happands
if(!head)
return nullptr;
// determine if the first item is the one.
if(head->item.getName() == name){
// if so, return the address of item
return &itemPtr->item;
}else{
// Initialize itemPtr to head of inventory
itemPtr = head;
// skip all items whose name is not match
while (itemPtr != nullptr && itemPtr->item.getName() != name){
previousItem = itemPtr;
itemPtr = itemPtr->next;
}
// return the address found
if (itemPtr){
return &itemPtr->item;
}
}
return nullptr;
}
here is the code where searchItem is called, can not access to getSellValue() which is defined in Item class
#include "Shop.hpp"
// sell inventory for gold
int Shop::sell(Inventory inventory, string itemName, int qt){
this->goldEarned = inventory.searchItem(itemName)->getSellValue() * qt;
inventory.deleteItem(itemName, qt);
return this->goldEarned;
}
Let me know if more information is needed.

Related

How do you write a function that returns a node which value corresponds to a value stored in a variable?

I stumbled across this question in an old textbook I bought ages ago, whilst strictly speaking it is not too difficult, I could not find a post here that simply answered this one question. As such I thought "Hey perhaps someone starting out might be confused about this", and so I put together the following code:
#include <iostream>
using namespace std;
// Structures
struct charNode {
char Node;
charNode *next;
};
// Functions
charNode* getCharNode(char c) {
return ; //<----- Return Node Here
}
What this needs is to be put in a class or else you must have a global variable that points to the head of that singly linked list.
An example class could look like this:
#include <iostream>
class singly_linked_list {
struct charNode {
char Node;
charNode *next;
};
public:
// find the charNode with the value `c`:
charNode* getCharNode(char c) {
for(charNode* curr = head; curr != nullptr; curr = curr->next) {
if(curr->Node == c) return curr;
}
return nullptr;
}
// add member functions to add/remove charNode's from the list etc
// and implement one of "the rule of 3" or "the rule of 5"
private:
charNode* head = nullptr;
};
You can implement getCharNode() function like in following code. I used this function for an example of creating singly linked list of chars. Also created extra function print_list() which outputs linked list to console.
Notice that I did only allocation of nodes (new operator), and didn't do deallocation (delete), I left this task for you to do, if you care about memory leaks.
Try it online!
#include <iostream>
// Structures
struct charNode {
charNode(char value, charNode * _next = nullptr)
: Node(value), next(_next) {}
char Node;
charNode *next;
};
// Functions
charNode* getCharNode(char c, charNode * next = nullptr) {
return new charNode(c, next);
}
void print_list(charNode const * node) {
if (!node)
return;
std::cout << node->Node << " ";
print_list(node->next);
}
int main() {
charNode * list = getCharNode('a',
getCharNode('b', getCharNode('c')));
print_list(list);
}
Output:
a b c

Linked list overwrites the previous value

I want to create a linked list with classes. I have two classes, one LinkedList and another LinkedNode. My problem is that my function InsertAtEnd always delete the current node. So when I want to print my linked list, I can't see anything.
I know thanks to debugger that in the function InsertAtEnd, we don't enter in the while loop, this is the problem. But after several attemps I can't resolve my problem.
This is my code:
void LinkedList::InsertAtend(int data)
{
LinkedNode* node = new LinkedNode();
node->setData(data); node->setNext(nullptr);
LinkedNode* tmp = _header;
if (tmp != NULL)
{
while (tmp->getNext() != nullptr)
{
tmp = tmp->getNext();
}
tmp->setData(data);
tmp->setNext(nullptr);
}
else
{
_header = node;
}
}
My class LinkedNode:
class LinkedNode
{
public:
LinkedNode();
~LinkedNode();
void setData(int data);
void setNext(LinkedNode* next);
int getData() const;
LinkedNode* getNext() const;
private:
int _data;
LinkedNode* _next;
};
My class LinkedList:
#pragma once
#include
#include "LinkedNode.h"
using namespace std;
class LinkedList
{
public:
LinkedList();
~LinkedList();
void PrintList();
void InsertAtend(int data);
void PrintList() const;
private:
LinkedNode* _header;
};
Thanks for your help !
tmp->setData(data);
Your tmp is not the node that you're trying to add, but the last in your list.
tmp is the last Node, so if you don't want to delete it you shouldn't write value data in it. You should link it with the new Node, which you named node.
Instead of
tmp->setData(data);
tmp->setNext(nullptr);
You should write
tmp->setNext(node)
At the end of the loop, the tmp is the last node in the current list. As you want to add the new node after the last node, you need to
tmp->setNext(node);
to append it (and not set the data as the data are already set to the new node).
Also note that you actually do not need to iterate through the entire list at all, if you keep another member variable to the current end of the list (_tail). Then you can access it directly and simply append and update.

How to initialize a Queue (linked list) and insert an element?

I have an assignment where I have to create a linked list and add and remove items from it. I'm having a problem understanding how to initialize the linked list in my constructor and adding items to it as well.
Here's my header file for it.
#ifndef CONGERA3_H
#define CONGERA3_H
const int MAX_STRING = 6;
typedef char Element300[MAX_STRING + 1];
class Queue300
{
public:
Queue300 ();
Queue300 (Queue300 &old);
~Queue300();
void enQueue300 (const Element300);
void deQueue300 (Element300);
void view300();
private:
struct Node300;
typedef Node300 * NodePtr300;
struct Node300
{
Element300 element;
NodePtr300 next;
};
NodePtr300 front, rear;
};
#endif
Here's my implementation file as well. I've removed the other functions for now, I feel like if I can get the constructor and enQueue down I can figure out the rest of them.
#include <iostream>
#include "congera3.h"
using namespace std;
Queue300::Queue300 ()
{
front = NULL;
return;
}
void Queue300::enQueue300 (const Element300 element)
{
Node300 temp;
temp.element = element;
}
I feel like I need to add a lot more to the constructor, such as setting the rear to point to the front. In the enQueue I think I need to have rear point towards the element I'm passing in and then have that element's next point towards front.

Searching for a node in a tree structure

I need help finding and returning a "node" in a general tree structure. Each node can have more than 2 children so it's not a binary tree. I've been given the following code, this Element object has a list to contain its children, I create one element node pointer in main and using that I have to add and search for children. This is for a school project but I'm not looking for answers (an answer wouldn't hurt). Any advice on how to go about this problem would be much appreciated, thanks!
#pragma once
#include <iostream>
#include <list>
#include <sstream>
using namespace std;
class Element
{
private:
list<Element*> children;
char* _tag;
int _value;
// private methods
public:
// default constructor
Element();
// non-default constructors
Element( char* name); // value is set to -99 if not given
Element(char* name, char* value);
// destructor, must recursively destruct its children
// and release the memory allocated for _tag
~Element();
// ostream operator ( pre-order traversal)
friend ostream& operator << (ostream& out, const Element& E);
void display_xml(); // print out the tree in xml-- format
void addChild( Element* child); // add a child
// Find the first element such that _tag == tag
// returns “this” pointer of this element
Element* findTag( char* tag);
char* getName();
int getValue();
void setName(char* name);
void setValue( int value);
int height(); //b return the height
int size(); // return the size
// other methods
};
this is my best attempt at a solution, it has obvious problems but I'm new to all of this and some explanation on a proper solution, or some sample code would be very helpful!
Element* Element::findTag(char* tag)
{
list<Element*> temp = children;
int s = temp.size();
if(getName() == tag)
{
return this;
}
else
{
for(int i = 0; i < s; i++)
{
findTag((*temp.front()).getName());
temp.pop_front();
}
}
}
I will give you a pseudo-code for searching for a node that has a value val in a tree rooted at root:
find(Node root, val)
if(root.value == val) return root //-- if the recursion found the node we are searching for
else
for every child x of root //-- re-cursing on the children of root
if(find(x, val) != null) return x //-- if one of the calls found the node we are searching for
return null //-- if we did not find the node we want in the sub-tree rooted at root

C++ compiler error: "isLeaf() has not been declared" - but it was

#include <cstdlib>
#include <iostream>
#include "Node.h"
#ifndef HW4_H
#define HW4_H
using namespace std;
/**
You are to implement the two functions in this class.
You can add any other method or members to it as well.
However, you cannot change their signature.
**/
class HW4{
public:
int count(Node* r) const
{
if(r->next==NULL&&r->bro==NULL) { return 0;}
if(r.isLeaf())
{
return ((1+count(r->next)+count(r->bro)));
}
count(r->next);
}
/*
This method will return true if the tree rooted at node sn can answer
the demand induced by its leaves.
*/
bool canDemandBeAnswered(Node* root)
{
if(count(root)>(root.getCapacity()))
{
return 0;
exit(0);
}
else
{
return (canDemandBeAnswered(root->next)&&canDemandBeAnswered(root->bro));
}
}
/*
This method should return a linked list of nodes representing the
customers with the overall highest revenue.
The resulting list should conform to the capacity limitations.
*/
// Node* getBestCustomers(Node* root);
};
#endif
#include <cstdlib>
#ifndef NODE_H
#define NODE_H
/**
The Node class. You must implement the two methods isLeaf() and addChild(Node*) below.
Otherwise, you can add any methods or members your heart's desire.
The only limitation is that they have to be in this file.
**/
class Node {
private:
int capacity;
int price;
public:
/**
Hint: to be used for saving the Node's children and for returning the linked list
**/
Node* next;
Node* bro;
Node(){
capacity = 0;
price = 0;
}
Node(int capacity_){
capacity = capacity_;
price = 0;
}
//should return true if this node has no children, false otherwise.
//this method adds a child to this node.
int getCapacity(){
return capacity;
}
int getPrice(){
return price;
}
void setPrice(int price_){
price = price_;
}
bool isLeaf()
{
if((this->next)->capacity==0)
return 1;
else return 0;
}
void addChild(Node* child)
{
Node* temp;
if(this->next!=NULL)
{
temp=this->next;
child->bro=temp;
this->next=child;
}
else
this->next=child;
}
};
#endif
I get the following error: "isLeaf() has not been declared". I don't understand why - I declared both.
bool canDemandBeAnswered(Node* root)
{
if(count(root)>(root.getCapacity()))
This attempts to call getCapacity on a Node *. But Node * doesn't have a function called getCapacity -- Node does.
You can use (*root).getCapacity() or the shorthand, root->getCapacity().
if(r.isLeaf())
You have the same issue here. r is a Node *.
Did you mean r->isLeaf() instead of r.isLeaf(), since r is a pointer?
You should be using -> instead of . to access those functions because r is a pointer.
Member access for pointers is different. You must use the indirection operator ->. These are not the actual objects but just pointers to them.