I'm fairly new to C++ and I'm working on a method that will check whether two lists are identical using the == operator. Here's my code as it is right now.
bool List::operator==(const List& original) const {
if(this != &original){
if( mySize != original.getSize() ) { return false; }
unsigned counter = 0;
Node * nPtr = original.myFirst;
Node * myPtr = myFirst;
while (counter < mySize ) {
if( this->myFirst == nPtr ) {
if (counter == 0){
counter++;
nPtr = nPtr->myNext;
}
if (myFirst->myNext == nPtr) {
counter ++;
nPtr = nPtr->myNext;
}
} else {
return false;
}
}
}
return true; }
So, from what I understand, here's what my code is doing. It checks whether their addresses are the same and, if it is, it returns true. Otherwise, it checks to see that their sizes are identical. If not, returns false. If true, goes through the list and checks the different values starting at the first address and going through until it reaches the last one.
However, it's failing this test I wrote and I'm not sure why or how:
List list3;
list3.append(33);
List list4;
list4.append(33); // [33]
assert( list4 == list3 );
assert( list3 == list4 );
cout << " 3 " << flush;
My append method adds a certain value to the list and I've tested it. That method works fine.
I realize this question may be similar to this question already asked but that didn't really help me much. Thanks for any help you can provide!
Related
I'll do my best to be brief:
So I have an assignment where I am creating a 'Wordlist' class. In which I will store a list of words.
These are the member variables
class WordList
{ //...
unsigned int m_count; // Number of words currently in list
unsigned int m_max; // The total size of the list.
char** m_list; // The list storing the words
};
This is my constructor
WordList::WordList(const int max_words) {
if(max_words < 1){
m_list = nullptr;
m_max = 0;
m_count = 0;
}
else
m_list = new char*[max_words];
m_count = 0;
m_max = max_words;
for (int i = 0; i < max_words; i++) {
m_list[i] = new char[20];
}
}
And this is where I start to find problems.
The following add function is supposed to add a word in the form of a c-style string that is pointed to from the array of character pointers that is pointed to from **char m_list .
int WordList::add(const char word[]) {
if (m_count == 0 && m_list != nullptr ) {
strcpy (m_list[m_count], word);
m_count++;
return 0;
}
if (m_count < m_max) {
m_count++;
strcpy (m_list[m_count], word);
return 0;
}
if (m_count == m_max) {
m_count++;
m_max ++;
strcpy (m_list[m_count], word);
return 1;
}
if (strlen(word)==0) {
return -2;
}
if (m_list == nullptr ){
return -2;
}
else
return -2;
}
So the issue I am having is that I clearly not syntactically correct with my * because I am not getting an array of 5 pointers that point to full words rather I am getting the first letter saved to the final destination char but its not copying over everything like I want.
I'm sure I didn't translate my problem to English as well as I should have but hopefully thats a start. Thank you!
An example of how I will be calling my add function:
WordList *wordlist = new WordList(5);
wordlist->add("harry");
wordlist->add("ron");
wordlist->add("hermione");
And it should add to the bottom of the pointer array a pointer to each word
so
cout << wordlist->m_list[0][2] << endl; // Expect 'r'
cout << wordlist->m_list[1] << endl; // Expect "ron"
instead I get
r
printed out only
I don't see anything wrong with your use of double-pointers.
There are other issues, though:
in your WordList::add you should check for empty word or empty list first, and fail fast. Besides, in your code if the word was empty - you would already added it and returned form that function.
in if (m_count < m_max) block, you pre-increment m_count, leaving one element empty and risking to go out-of-bounds on the last entry.
in if (m_count == m_max) { you are CERTAINLY going out-of-bounds
Suggestion: instead of pre-allocating 20-character arrays, leave them nullptr; when you need to a word - use strdup(word); that would allocated a required space for you.
As for your I am getting the first letter saved - I am guessing you are not checking it right...
The problem is that you add the first word:
if (m_count == 0 && m_list != nullptr ) {
strcpy (m_list[m_count], word);
m_count++;
return 0;
}
Which increments m_count so now m_count is 1.
Then you add the second word:
if (m_count < m_max) {
m_count++;
strcpy (m_list[m_count], word);
return 0;
}
Which increments m_count BEFORE adding the word so the second word is at index 2 and index 1 is skipped altogether.
You need to always increment the count after copying the word because m_count is 1 based and the array is 0 based.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I've been trying make a function to get the height of a binary tree in recursive way.
int BSNode::getHeight() const //Returns the height of the tree.
{
if (this->_left == nullptr && this->_right == nullptr)
{
return 0;
}
else
{
return std::max(this->_left->getHeight(), this->_right->getHeight()) + 1;
}
}
I debugged my code and for some reason, I got access violation error on the 'if condition' line. I can't see why I'm still getting this error. I'm suppose that it happening because one of my left or right is null, but I cant see other way to make it.
This is my function for inserting a node to the tree:
void BSNode::insert(string value) //Inserts node to the tree.
{
if (value > this->_data)
{
if (this->_right != NULL)
{
this->_right->insert(value);
}
else
{
this->_right = new BSNode(value);
}
}
else if (value < this->_data)
{
if (this->_left != NULL)
{
this->_left->insert(value);
}
else
{
this->_left = new BSNode(value);
}
}
}
This is the class I built:
class BSNode
{
private:
string _data;
BSNode* _left;
BSNode* _right;
}
The negation of the condition in this if statement
if (this->_left == nullptr && this->_right == nullptr)
is
else if ( not ( this->_left == nullptr && this->_right == nullptr) )
that is in turn equivalent to
else if ( this->_left != nullptr || this->_right != nullptr )
However in the function there is ignored the fact that either this->_left or this->_right can be equal to nullptr.
return std::max(this->_left->getHeight(), this->_right->getHeight()) + 1;
Also it is unclear why the height has the signed type int instead of some unsigned type as for example size_t.
I suppose that the head of the tree is always unequal to nullptr. Otherwise you should rewrite the function as a static member function with one parameter: pointer to the head node.
The function can look the following way
size_t BSNode::getHeight() const //Returns the height of the tree.
{
return 1 + std::max(
this->_left == nullptr ? 0 : this->_left->getHeight(),
this->_right == nullptr ? 0 : this->_right->getHeight());
}
I have been going through the debugger but can't seem to pinpoint exactly what is going wrong. I have come to my own conclusion i must be missing a nullptr check somewhere or something. If anyone can provide some help it would be greatly appreciated.
error message from debugger
error msg
which looks like makes the program crash on this line:
if (node->children_[index] == nullptr) {
search function
Node* search(const string& word, Node* node, int index) const {
Node* temp;
//same as recurssive lookup just difference is returns node weather terminal or not
if (index < word.length()) {
index = node->getIndex(word[index]);
if (node->children_[index] == nullptr) {
return nullptr;
}
else {
temp = search(word, node->children_[index], index++);
}
}
return temp; // this would give you ending node of partialWord
}
Node struct for reference
struct Node {
bool isTerminal_;
char ch_;
Node* children_[26];
Node(char c = '\0') {
isTerminal_ = false;
ch_ = c;
for (int i = 0; i < 26; i++) {
children_[i] = nullptr;
}
}
//given lower case alphabetic charachters ch, returns
//the associated index 'a' --> 0, 'b' --> 1...'z' --> 25
int getIndex(char ch) {
return ch - 'a';
}
};
Node* root_;
int suggest(const string& partialWord, string suggestions[]) const {
Node* temp;
temp = search(partialWord, root_, 0);
int count = 0;
suggest(partialWord, temp, suggestions, count);
return count;
}
Might be a very simple thing. Without digging I am not sure about the rank of the -> operator versus the == operator. I would take a second and try putting parenthesis around the "node->children_[index] == nullptr" part like this:
(node->children_[index]) == nullptr
just to make sure that the logic runs like you seem to intend.
Dr t
I believe the root cause is that you're using index for two distinct purposes: as an index into the word you're looking for, and as an index into the node's children.
When you get to the recursion, index has changed meaning, and it's all downhill from there.
You're also passing index++ to the recursion, but the value of index++ is the value it had before the increment.
You should pass index + 1.
[An issue in a different program would be that the order of evaluation of function parameters is unspecified, and you should never both modify a variable and use it in the same parameter list. (I would go so far as to say that you should never modify anything in a parameter list, but many disagree.)
But you shouldn't use the same variable here at all, so...]
I would personally restructure the code a little, something like this:
Node* search(const string& word, Node* node, int index) const {
// Return immediately on failure.
if (index >= word.length())
{
return nullptr;
}
int child_index = node->getIndex(word[index]);
// The two interesting cases: we either have this child or we don't.
if (node->children_[child_index] == nullptr) {
return nullptr;
}
else {
return search(word, node->children_[child_index], index + 1);
}
}
(Side note: returning a pointer to a non-const internal Node from a const function is questionable.)
I'm implementing a trie to implmenta spelling dictionary. The basic element of a trie is a trienode, which consists of a letter part (char), a flag(whether this char is the last char of a word), and an array of 26 pointers.
Private part of the TrieNode class include:
ItemType item;//char
bool isEnd;//flag
typedef TrieNode* TrieNodePtr;
TrieNodePtr myNode;
TrieNodePtr array[26];//array of pointers
This is part of the test call:
Trie t4 = Trie();
t4.insert("for");
t4.insert("fork");
t4.insert("top");
t4.insert("tops");
t4.insert("topsy");
t4.insert("toss");
t4.print();
cout << t4.wordCount() << endl;
Right now I'm trying to traverse the trie to count how many words there are (how many flags are set to true).
size_t TrieNode::wordCount() const{
for (size_t i = 0; i < 26; i++){
if (array[i] == nullptr){
return 0;
}
if (array[i]->isEnd && array[i] != nullptr){
cout << "I'm here" << endl;
return 1 + array[i]->wordCount();
}
else if(!array[i]->isEnd && array[i]!=nullptr){
cout << "I'm there" << endl;
return 0 + array[i]->wordCount();
}
else{
// do nothing
}
}
}
Every time the function returns 0. I know it's because when the first element in the array is null, then the function exits, so the count is always 0. But I don't know how to avoid this, since every time I have start from the first pointer. I also get a warning:not all control paths return a value. I'm not sure where this comes from. How do I make the function continue to the next pointer in the array if the current pointer is null? Is there a more efficient way to count words? Thank you!
Here is a simple and clear way to do it(using depth-first search):
size_t TrieNode::wordCount() const {
size_t result = isEnd ? 1 : 0;
for (size_t i = 0; i < 26; i++){
if (array[i] != null)
result += array[i]->wordCount();
return result;
}
This is one of the solution of getting true or false from given set and target value
bool subsetSumExists(Set<int> & set, int target) {
if (set.isEmpty()) {
return target == 0;
} else {
int element = set.first();
Set<int> rest = set - element;
return subsetSumExists(rest, target)
|| (subsetSumExists(rest, target- element));
}
}
However, this solution will return true or false value only. How is it possible to get the element that involve in the subset(set that add together will equal to target) as well?
Do I have to use dynamic programming? Coz as i know.. recursion is building up stack actually and after the function return the value, the value inside the frame will be discarded as well.
So, is it possible to get the elements that add up equal to the target value.
Is passing an object a solution of the problem?
Thank you
First of all you can optimize your program a little bit - check if target is 0 and if it is always return true. Now what you need is to have somewhere to store the elements that you have already used. I will show you a way to do that with a global "stack"(vector in fact so that you can iterate over it), because then the code will be easier to understand, but you can also pass it by reference to the function or avoid making it global in some other way.
By the way the stl container is called set not Set.
vector<int> used;
bool subsetSumExists(Set<int> & set, int target) {
if (target == 0) {
cout << "One possible sum is:\n";
for (int i = 0; i < used.size(); ++i) {
cout << used[i] << endl;
}
return true;
} else if(set.empty()) {
return false;
}else {
int element = set.first();
Set<int> rest = set - element;
used.push_back(element);
if (subsetSumExists(rest, target- element)) {
return true;
} else {
used.pop_back();
}
return subsetSumExists(rest, target);
}
}
Hope this helps.