I was starting to learn to use class object in different .cpp file..
What I did:
Created a class of node in one file and saved it with node.h
Created another file with name node_pair.cpp and included node.h
Created a function named pair() and called it from main()
Now, I want to ask two things:
I am getting error: reference to ‘pair’ is ambiguous
Here is the code for node.h file
#include "iostream"
#include"stdlib"
using namespace std;
class node
{
int data;
public:
node *next;
int insert(node*);
node* create();
int display(node *);
} *start = NULL, *front, *ptr, n;
int node::insert(node* np)
{
if (start == NULL)
{
start = np;
front = np;
}
else
{
front->next = np;
front = np;
}
return 0;
}
node* node::create()
{
node *np;
np = (node*)malloc(sizeof(node)) ;
cin >> np->data;
np->next = NULL;
return np;
}
int node::display(node* np)
{
while (np != NULL)
{
cout << np->data;
np = np->next;
}
return 0;
}
int main_node()
{
int ch;
cout << "enter the size of the link list:";
cin >> ch;
while (ch--)
{
ptr = n.create();
n.insert(ptr);
}
n.display(start);
cout << "\n";
return 0;
}
and here is the code for node_pair.cpp
#include"iostream"
#include"node.h"
using namespace std;
node obj;
int pair()
{
node* one, *two, *save;
one = start;
two = start->next;
while (two != NULL)
{
save = two->next;
two->next = one;
one->next = save;
}
}
int main()
{
main_node();
pair();
obj.display(start);
return 0;
}
What should I do to resolve this error
And now the second problem
2. I want to keep node* next pointer to be private in node class but if I do so then I will not get access for it in pair() function.
Please answer, thanks in advance.
Some tips:
Your function pair clashes with std::pair.
Don't use using namespace std;. It's a bad practice and creates errors like this.
Mixing node.js and C++ is an advanced topic. If you just begun to learn OOP, I recommend that you stick to pure C++.
You have a name collision with your pair() and std::pair.
Best practice is to avoid using the entire namespace std -- just use what you need. For example, if you only need std::cin you can use using std::cin; to add it to the global namespace but not std::pair. You can also replace all instances of cin with std::cin instead.
If you really want to use the entire namespace std you can also create your own namespace to put your code in -- in particular, you'd need to put your pair() in this new namespace. You do it like this:
namespace mynamespace {
int pair() {
// ...
}
// ... other code in mynamespace
} // end mynamespace
Related
I am trying to implement a suffix trie in C++ for a programming assignment. Now I think I have the right idea, but I keep getting a segmentation fault and I haven't been able to find what's causing it.
For this assignment, we are encouraged to use VIM/some other basic text editor, and compile programs from the console. Nevertheless, I've downloaded CLion to try and debug the code so I can find the error.
Now when running in CLion I get the message
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Trying to run the debugger gives the message
Error during pretty printers setup:
Undefined info command: "pretty-printer". Try "help info".
Some features and performance optimizations will not be available.
I'm new to CLion and I'm not sure what to do about this (The only JetBrains IDE I use is Pycharm). Can you help me resolve this?
Now the program itself consists of three classes, Trie, Edge and Node, whose implementations can be seen below. The main idea behind the implementation of the Trie is in the constructor of Trie.cpp.
The code is detailed in full below. I appreciate any help.
Main.cpp
#include <iostream>
using namespace std;
#include "Trie.hpp"
int main(){
string s = "Stef";
Trie trie(s);
return 0;
}
Trie.hpp
#ifndef TRIE_HPP
#define TRIE_HPP
#include <string>
#include "Node.hpp"
#include "Edge.hpp"
using namespace std;
class Trie{
private:
string T;
vector<Node> nodes;
void addWord(Node*, string);
public:
Trie(string);
};
#endif
Trie.cpp
#include <iostream>
#include <cstring>
#include "Trie.hpp"
using namespace std;
Trie::Trie(string T){
T += "#"; //terminating character
this->T = T;
vector<string> suffix; //array of suffixes
for(unsigned int i = 0; i < T.length(); i++)
suffix.push_back(T.substr(i, T.length()-i));
//Create the Root, and start from it
nodes.push_back(Node("")); //root has blank label
Node* currentNode = &nodes[0];
//While there are words in the array of suffixes
while(!suffix.empty()){
//If the character under consideration already has an edge, then this will be its index. Otherwise, it's -1.
int edgeIndex = currentNode->childLoc(suffix[0].at(0));
//If there is no such edge, add the rest of the word
if(edgeIndex == -1){
addWord(currentNode, suffix[0]); //add rest of word
suffix.erase(suffix.begin()); //erase the suffix from the suffix array
break; //break from the for loop
}
//if there is
else{
currentNode = (currentNode->getEdge(edgeIndex))->getTo(); //current Node is the next Node
suffix[0] = suffix[0].substr(1, suffix[0].length()); //remove first character
}
}
}
//This function adds the rest of a word
void Trie::addWord(Node* parent, string word){
for(unsigned int i = 0; i < word.length(); i++){ //For each remaining letter
nodes.push_back(Node(parent->getLabel()+word.at(i))); //Add a node with label of parent + label of edge
Edge e(word.at(i), parent, &nodes.back()); //Create an edge joining the parent to the node we just added
parent->addEdge(e); //Join the two with this edge
}
}
Node.hpp
#ifndef NODE_HPP
#define NODE_HPP
#include <string>
#include <vector>
#include "Edge.hpp"
using namespace std;
class Node{
private:
string label;
vector<Edge> outgoing_edges;
public:
Node();
Node(string);
string getLabel();
int childLoc(char);
void addEdge(Edge);
Edge* getEdge(int);
};
#endif
Node.cpp
#include "Node.hpp"
using namespace std;
Node::Node(){
}
Node::Node(string label){
this->label = label;
}
string Node::getLabel(){
return label;
}
//This function returns the edge matching the given label, returning -1 if there is no such edge.
int Node::childLoc(char label){
int loc = -1;
for(unsigned int i = 0; i < outgoing_edges.size(); i++)
if(outgoing_edges[i].getLabel() == label)
loc = i;
return loc;
}
void Node::addEdge(Edge e){
outgoing_edges.push_back(e);
}
Edge* Node::getEdge(int n){
return &outgoing_edges[n];
}
Edge.hpp
#ifndef EDGE_HPP
#define EDGE_HPP
#include <string>
using namespace std;
class Node; //Forward definition
class Edge{
private:
char label;
Node* from;
Node* to;
public:
Edge(char, Node*, Node*);
char getLabel();
Node* getTo();
Node* getFrom();
};
#endif
Edge.cpp
#include "Edge.hpp"
using namespace std;
Edge::Edge(char label, Node* from, Node* to){
this->label = label;
this->from = from;
this->to = to;
}
char Edge::getLabel(){
return label;
}
Node* Edge::getFrom(){
return from;
}
Node* Edge::getTo(){
return to;
}
&nodes[0];, &nodes.back() - you're storing pointers into a vector for later use, and these become invalid when the vector's underlying storage is relocated as you add elements to it.
Read about pointers in general, and dynamic allocation in particular, in your favourite C++ book.
If you don't yet have a favourite C++ book, pick one from this list.
I began to write a project today to learn more about binary search trees but while writing the class definitions and checking them my accessor was returning false
results returning 2 and then on the next line 4196704 in the terminal.
heres the code:
#include <iostream>
using namespace std;
class node
{private:
int data;
node *right,*left;
public:
node();
node(int d,node *r,node *l)
{
d= data;
r=right;
l=left;
}
int nodedata() ;
};
int node::nodedata()
{
return data;
}
int main()
{
node root(30,0,0);
node root2(77,0,0);
cout<< root.nodedata() << endl;
cout<< root2.nodedata() << endl;
return 0;
}
You are not writing c++ much I guess.
your definition of variable is wrong:
d= data;
should be
data = d;
And as for why it shows some werid data in output, those are digits in the actual memory location that your system has put there before you assign this chunck of memory, which you have not yet rewrite, to this object,
and for assigning pointers:
r=right;
l=left;
should be
right= r;
left=l;
and if you wanna access them, put them public or create method to access it
eg:
cout<<(root.right)-> nodedata() << endl; //if you make right && left public
First of all, let me say thank you for all the help I've been received in the last couple hours. I've been struggle with this problem, how to convert from raw pointer to unique pointer and got myself into a lot of errors. However, with the help of this community, I've been thankful that my program finally compiles without errors at all. But I'm not there yet, I guess. I feel like I'm like one minute away from the finish line, so I won't give up till I can solve it. My program crashes as soon as it runs, it says stack overflow and throw out the exception. I guess it must be the way that I declare and initialize the unique pointer as a class member in the constructor is not correct at all and therefore it crashes right from the minute it calls the constructor. Would anyone please tell me what I should do to fix this error ? Thanks.
This is my main cpp file:
#include"ContactList.h"
#include<memory>
using namespace std;
int main()
{
//ContactList* cl1 = new ContactList();
unique_ptr<ContactList> cl1(new ContactList());
string name;
while(true)
{
cout << "Enter a name or q to quit: " << endl;
cin >> name;
if(name == "q")
break;
cl1->addToHead(name);
}
cl1->PrintList();
return 0;
}
ContactList.h
#pragma once
#include"Contact.h"
#include<memory>
using namespace std;
class ContactList
{
public:
ContactList();
void addToHead(const std::string&);
void PrintList();
private:
//Contact* head;
unique_ptr<Contact> head;
int size;
};
ContactList.cpp
#include"ContactList.h"
#include<memory>
using namespace std;
ContactList::ContactList(): head(new Contact()), size(0)
{
}
void ContactList::addToHead(const string& name)
{
//Contact* newOne = new Contact(name);
unique_ptr<Contact> newOne(new Contact(name));
if(head == 0)
{
head.swap(newOne);
//head = move(newOne);
}
else
{
newOne->next.swap(head);
head.swap(newOne);
//newOne->next = move(head);
//head = move(newOne);
}
size++;
}
void ContactList::PrintList()
{
//Contact* tp = head;
unique_ptr<Contact> tp(new Contact());
tp.swap(head);
//tp = move(head);
while(tp != 0)
{
cout << *tp << endl;
tp.swap(tp->next);
//tp = move(tp->next);
}
}
Contact.h
#pragma once
#include<iostream>
#include<string>
#include<memory>
class Contact
{
friend std::ostream& operator<<(std::ostream& os, const Contact& c);
friend class ContactList;
public:
Contact(std::string name = "none");
private:
std::string name;
//Contact* next;
std::unique_ptr<Contact> next;
};
Contact.cpp
#include"Contact.h"
using namespace std;
Contact::Contact(string n):name(n), next(new Contact())
{
}
ostream& operator<<(ostream& os, const Contact& c)
{
return os << "Name: " << c.name;
}
This is the error I get:
Unhandled exception at 0x77E3DEFE (ntdll.dll) in Practice.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x002B2F58).
You didn't post the code for Contact, but I assume it's the same as in one of your previous questions:
Contact::Contact(string n):name(n), next(new Contact())
{
}
As you can see, constructing a Contact requires setting its next member to a new Contact.
In order to construct that Contact, you're going to create a new Contact for its next member.
And so on, et cetera, to infinity and beyond.
This is the cause of of the stack overflow - Contact construction never ends.
You probably don't want next to be anything in particular for a newly constructed Contact, so try
Contact::Contact(string n):name(n), next(0)
{
}
You have a problem in your ContactList::PrintList() method: you don't need unique_ptr when you iterate through some items just observing them.
When observing items, raw pointers are just fine.
In general, owning raw pointers are not good (except in some special cases), but observing raw pointers are just fine.
In addition, note also that in your ContactList default constructor, you don't need to allocate an empty Contact with new and assign it to head unique_ptr data member: unique_ptr default constructor will automatically initialize head to a nullptr.
Note also that the ContactList::PrintList() methods should be marked as const for proper const-correctness, since usually printing the content of some collection should not alter the items in the collection.
Finally, the ContactList allocation in your main() function can be simply done on the stack:
ContactList cl;
There's no need to use unique_ptr in this case (please program in C++, not in Java or C# style).
And, a style note: I don't like that some methods start with upper-case letter (e.g. PrintList()) and others with lower-case letter (e.g. addToHead()): choose one style, and be coherent with it (at list at the source file level, if not at the whole project level).
Below there's a single source file test code, based on your code with some fixes applied.
I compiled it and tested a bit with VC10 (Visual Studio 2010 SP1); it seems to work:
C:\Temp>test.exe
Enter a name or q to quit:
Bob
Enter a name or q to quit:
Jane
Enter a name or q to quit:
John
Enter a name or q to quit:
Mary
Enter a name or q to quit:
q
[Contact name: Mary]
[Contact name: John]
[Contact name: Jane]
[Contact name: Bob]
Compilable source code follows:
#include <iostream>
#include <memory>
#include <ostream>
#include <string>
using namespace std;
// "Imaginary" Contact implementation (you didn't provide it)
struct Contact {
Contact() {}
explicit Contact(const string& n) : name(n) {}
string name;
unique_ptr<Contact> next;
};
ostream& operator<<(ostream& os, const Contact& c) {
os << "[Contact name: " << c.name << "]";
return os;
}
class ContactList {
public:
ContactList();
void AddToHead(const string&);
void PrintList() const;
private:
unique_ptr<Contact> head;
int size;
};
ContactList::ContactList()
: size(0) {
// No need to initialize head pointer.
// It will be automatically initialized to nullptr.
}
void ContactList::AddToHead(const string& name) {
unique_ptr<Contact> newOne(new Contact(name));
if(head == 0) {
head.swap(newOne);
} else {
newOne->next.swap(head);
head.swap(newOne);
}
size++;
}
void ContactList::PrintList() const {
const Contact * pContact = head.get();
while (pContact != nullptr) {
cout << *pContact << endl;
pContact = pContact->next.get();
}
}
int main() {
// No need to allocate ContactList using unique_ptr.
// Stack scoped-based allocation is just fine.
ContactList cl;
while (true) {
cout << "Enter a name or q to quit: " << endl;
string name;
cin >> name;
if (name == "q")
break;
cl.AddToHead(name);
}
cl.PrintList();
}
I am looking for a concise and precise adjacency list representation of a graph in C++. My nodes are just node ids. Here is how I did it. Just want to know what experts think about it. Is there a better way?
This is the class implementation (nothing fancy, right now don't care about public/private methods)
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
class adjList {
public:
int head;
vector<int> listOfNodes;
void print();
};
void adjList :: print() {
for (int i=0; i<listOfNodes.size(); ++i) {
cout << head << "-->" << listOfNodes.at(i) << endl;
}
}
class graph {
public:
vector<adjList> list;
void print();
};
void graph :: print() {
for (int i=0; i<list.size(); ++i) {
list.at(i).print();
cout << endl;
}
}
My main function parses an input file line by line. Where each line is interpreted as following:
<source_node> <node1_connected_to_source_node> <node2_connected_to_source_node <node3_connected_to_source_node> <...>
Here is the main:
int main()
{
fstream file("graph.txt", ios::in);
string line;
graph g;
while (getline(file, line)) {
int source;
stringstream str(line);
str >> source;
int node2;
adjList l;
l.head = source;
while (str >> node2) {
l.listOfNodes.push_back(node2);
}
g.list.push_back(l);
}
file.close();
g.print();
getchar();
return 0;
}
I know I should add addEdge() function inside adjList class instead of directly modifying its variable from main() however, right now I just wonder about the best structure.
EDIT:
There is one shortcoming in my approach. For a complicated graph with large number of nodes, node will indeed be a struct/class and in that case I will be duplicating values by storing the whole object. In that case I think I should use pointers. For example for an undirected graph, I will be storing copies of node objects in the adjList (connection between node 1 and 2 means 1's adjacency list will have 2 and vice versa). I can avoid that by storing pointers of node objects in the adjList instead of the whole object. Check the dfs implementation which get benefited by this approach. There I need to insure that each node gets visited only once. Having multiple copies of the same node will make my life harder. no?
In this case my class definitions will change like this:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <map>
using namespace std;
class node {
public:
node() {}
node(int id, bool _dirty): node_id(id), dirty(_dirty) {}
int node_id;
bool dirty;
};
class adjList {
public:
node *head;
vector<node*> listOfNodes;
void print();
~adjList() { delete head;}
};
void adjList :: print() {
for (int i=0; i<listOfNodes.size(); ++i) {
cout << head->node_id << "-->" << listOfNodes.at(i)->node_id << endl;
}
}
class graph {
public:
vector<adjList> list;
void print();
void dfs(node *startNode);
};
void graph::dfs(node *startNode) {
startNode->dirty = true;
for(int i=0; i<list.size(); ++i) {
node *stNode = list.at(i).head;
if (stNode->node_id != startNode->node_id) { continue;}
for (int j=0; j<list.at(i).listOfNodes.size(); ++j) {
if (!list.at(i).listOfNodes.at(j)->dirty) {
dfs(list.at(i).listOfNodes.at(j));
}
}
}
cout << "Node: "<<startNode->node_id << endl;
}
void graph :: print() {
for (int i=0; i<list.size(); ++i) {
list.at(i).print();
cout << endl;
}
}
And this is how I implemented main() function. I am using a map<> to avoid duplication of objects. Creating a new object only when its not defined earlier. Checking existence of an object by its id.
int main()
{
fstream file("graph.txt", ios::in);
string line;
graph g;
node *startNode;
map<int, node*> nodeMap;
while (getline(file, line)) {
int source;
stringstream str(line);
str >> source;
int node2;
node *sourceNode;
// Create new node only if a node does not already exist
if (nodeMap.find(source) == nodeMap.end()) {
sourceNode = new node(source, false);
nodeMap[source] = sourceNode;
} else {
sourceNode = nodeMap[source];
}
adjList l;
l.head = sourceNode;
nodeMap[source] = sourceNode;
while (str >> node2) {
// Create new node only if a node does not already exist
node *secNode;
if (nodeMap.find(node2) == nodeMap.end()) {
secNode = new node(node2, false);
nodeMap[node2] = secNode;
} else {
secNode = nodeMap[node2];
}
l.listOfNodes.push_back(secNode);
}
g.list.push_back(l);
startNode = sourceNode;
}
file.close();
g.print();
g.dfs(startNode);
getchar();
return 0;
}
SECOND EDIT
After Ulrich Eckhardt suggestion to put adjacency list in node class, here is what I think is a better data structure to store a graph and perform dfs(), dijkstra() kind of operations. Please note that adjacency list is merged in node class.
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <map>
using namespace std;
class node {
public:
node() {
}
node(int id, bool _dirty): node_id(id), dirty(_dirty) {
//cout << "In overloaded const\n";
}
int node_id;
bool dirty;
vector<node*> listOfNodes;
};
class graph {
public:
vector<node*> myGraph;
void dfs(node* startNode);
};
void graph::dfs(node* startNode) {
startNode->dirty = true;
for (int j=0; j<startNode->listOfNodes.size(); ++j) {
if (!startNode->listOfNodes.at(j)->dirty) {
dfs(startNode->listOfNodes.at(j));
}
}
cout << "Node: "<<startNode->node_id << endl;
}
Can we do better than this?
There are a few things that could be improved, but in general your approach is reasonable. Notes:
You are using int as index into a container, which will give you warning from some compilers, because the size of a container could exceed the size representable as int. Instead, use size_t.
Rewrite your for (int i=0; i<list.size(); ++i) to for(size_t i=0, size=list.size(); i!=size; ++i). Using != instead of < will work with iterators. Reading and storing the size once makes it easier to debug and possibly even more efficient.
Inside the loop to print, you have list.at(i).print();. The list.at(i) will verify the index is valid and raise an exception when not. In this very simple case, I am sure that the index is valid, so using list[i] instead is faster. Also, it implicitly documents that the index is valid and not that you expect it to be invalid.
The print() functions should be constant.
I don't understand what the int head is. Is this some kind of ID for the node? And isn't the ID simply the index inside graph::list? If it is the index, you could compute that on demand using the address of the element minus the address of the first element, so there's no need to store it redundantly. Also, consider validating that index when reading, so you don't have any edges going to a vertex that doesn't exist.
If you don't care about encapsulation on a node-level (which is reasonable!), you could also make this a struct, which saves some typing.
Storing pointers instead of indices is tricky but could improve speed. The problem is that for reading, you might need a pointer to a vertex that doesn't exist yet. There is a hack that allows doing that without using additional storage, it requires first storing the indices in the pointer values (using reinterpret_cast) and after reading, making a second pass on the data where you adjust these values to the actual addresses. Of course, you can also use the second pass to validate that you don't have any edges going to vertices that don't exist at all (which is a place where the at(i) function becomes useful) so this second pass to verify some guarantees is a good thing anyway.
On explicit request, here's an example for how to store an index in a pointer:
// read file
for(...) {
size_t id = read_id_from_file();
node* node_ptr = reinterpret_cast<node*>(id);
adjacency_list.push_back(node_ptr);
}
/* Note that at this point, you do have node* that don't contain
valid addresses but just the IDs of the nodes they should finally
point to, so you must not use these pointers! */
// make another pass over all nodes after reading the file
for(size_t i=0, size=adjacency_list.size(); i!=size; ++i) {
// read ID from adjacency list
node* node_ptr = adjacency_list[i];
size_t id = reinterpret_cast<size_t>(node_ptr);
// convert ID to actual address
node_ptr = lookup_node_by_id(id);
if(!node_ptr)
throw std::runtime_error("unknown node ID in adjacency list");
// store actual node address in adjacency list
adjacency_list[i] = node_ptr;
}
I'm pretty sure that this works in general, though I'm not 100% sure if this is guaranteed to work, which was why I'm reluctant to post this here. However, I hope this also makes clear why I'm asking what exactly "head" is. If it is really just the index in a container, there is little need for it, neither inside the file nor in memory. If it is some kind of name or identifier for a node that you retrieved from a file, then you absolutely need it, but then you can't use it as index, the values there could as well start their IDs with 1 or 1000, which you should catch and handle without crashing!
I am trying to implement the trie as shown on the TopCoder page. I am modifying it a bit to store the phone numbers of the users. I am getting segmentation fault. Can some one please point out the error.
#include<iostream>
#include<stdlib.h>
using namespace std;
struct node{
int words;
int prefix;
long phone;
struct node* children[26];
};
struct node* initialize(struct node* root) {
root = new (struct node);
for(int i=0;i<26;i++){
root->children[i] = NULL;
}
root->word = 0;
root->prefix = 0;
return root;
}
int getIndex(char l) {
if(l>='A' && l<='Z'){
return l-'A';
}else if(l>='a' && l<='z'){
return l-'a';
}
}
void add(struct node* root, char * name, int data) {
if(*(name)== '\0') {
root->words = root->words+1;
root->phone = data;
} else {
root->prefix = root->prefix + 1;
char ch = *name;
int index = getIndex(ch);
if(root->children[ch]==NULL) {
struct node* temp = NULL;
root->children[ch] = initialize(temp);
}
add(root->children[ch],name++, data);
}
}
int main(){
struct node* root = NULL;
root = initialize(root);
add(root,(char *)"test",1111111111);
add(root,(char *)"teser",2222222222);
cout<<root->prefix<<endl;
return 0;
}
Added a new function after making suggested changes:
void getPhone(struct node* root, char* name){
while(*(name) != '\0' || root!=NULL) {
char ch = *name;
int index = getIndex(ch);
root = root->children[ch];
++name;
}
if(*(name) == '\0'){
cout<<root->phone<<endl;
}
}
Change this:
add(root->children[ch], name++, data);
// ---------------------^^^^^^
To this:
add(root->children[ch], ++name, data);
// ---------------------^^^^^^
The remainder of the issues in this code I leave to you, but that is the cause of your run up call-stack.
EDIT OP ask for further analysis, and while I normally don't do so, this was a fairly simple application on which to expand.
This is done in several places:
int index = getIndex(ch);
root = root->children[ch];
... etc. continue using ch instead of index
It begs the question: "Why did we just ask for an index that we promptly ignore and use the char anyway?" This is done in add() and getPhone(). You should use index after computing it for all peeks inside children[] arrays.
Also, the initialize() function needs to be either revamped or outright thrown out in favor of a constructor-based solution, where that code truly belongs. Finally, if this trie is supposed to be tracking usage counts of words generated and prefixes each level is participating in, I'm not clear why you need both words and prefix counters, but in either case to update the counters your recursive decent in add() should bump them up on the back-recurse.