Remove node & setting limits

  • (2 Pages)
  • +
  • 1
  • 2

20 Replies - 1491 Views - Last Post: 16 March 2020 - 01:41 PM Rate Topic: -----

#1 PendeJoe   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 59
  • Joined: 09-October 19

Remove node & setting limits

Posted 12 March 2020 - 01:11 PM

Hi guys!

I need some help to remove nodes with a menu driven program and also setting a limit where if the user input anything else except numbers for either the year they viewed the movie or rating. This is what I got so far:

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>

using namespace std;

struct Movie
{
    string title;
    int viewed_year;
    int rating;
    Movie* next;
};

void programmerInfo();
void print_menu();
void arrange_by_title(Movie*);
void arrange_by_rating(Movie*);
void arrange_by_viewed(Movie*);
void update_movie(Movie*, int);
void remove_movie(Movie*, int);
void list_movie(const Movie*);

int main()
{
    int size = 0;
    char choice;

    Movie* firstMovie = 0;

    Movie a = { "movie3"};
    Movie b = { "movie2"};
    Movie c = { "movie1"};

    a.next = firstMovie;
    firstMovie = &a;
    size++;

    b.next = firstMovie;
    firstMovie = &b;
    size++;

    c.next = firstMovie;
    firstMovie = &c;
    size++;

    print_menu();
        cin >> choice;

    while(choice != 'Q' && choice != 'q')
    {
        switch(choice) {
            case 'U':
            case 'u':
                update_movie(firstMovie, size);
                break;

            case 'E':
            case 'e':
                remove_movie(firstMovie, size);
                size--;
                break;

            case 'L':
            case 'l':
                list_movie(firstMovie);
                break;

            case 'T':
            case 't':
                arrange_by_title(firstMovie);
                break;

            case 'V':
            case 'v':
                arrange_by_viewed(firstMovie);
                break;

            case 'R':
            case 'r':
                arrange_by_rating(firstMovie);
                break;

            default:
                cout << "**Invalid choice, please enter again**\n";
                break;
        }
        print_menu();
            cin >> choice;
    }
return 0;
}

void arrange_by_title(Movie* head) {
    for(Movie* p = head; p; p = p->next) {
        for(Movie* q = p->next; q; q = q->next) {
            if(q->title < p->title) {
                swap(*p, *q);
                swap(p->next, q->next);
            }
        }
    }
    list_movie(head);
}

void arrange_by_viewed(Movie* head) {
    for(Movie* p = head; p; p = p->next) {
        for(Movie* q = p->next; q; q = q->next) {
            if(q->viewed_year > p->viewed_year) {
                swap(*p, *q);
                swap(p->next, q->next);
            }
        }
    }
   list_movie(head);
}

void arrange_by_rating(Movie* head) {
    for(Movie* p = head; p; p = p->next) {
        for(Movie* q = p->next; q; q = q->next) {
            if(q->rating > p->rating) {
                swap(*p, *q);
                swap(p->next, q->next);
            }
        }
    }
    list_movie(head);
}

void print_menu() {
    cout << "MENU\n";
    cout << "U Update a movie\n";
    cout << "E rEmove a movie\n";
    cout << "L List all movies\n";
    cout << "T arrange by Title\n";
    cout << "V arrange by year Viewed\n";
    cout << "R arrange by Rating\n";
    cout << "Q Quit\n";
    cout << "...your choice:";
}

void update_movie(Movie* head, int index) {
    int update;

    Movie* current = head;

    cout << "Which movie to update [1-" << index << "]: ";
        cin >> update;
    while(update < 1 || update > index) {
        cout << "Invalid choice, please try again!\n";
        cout << "Which movie to update [1-" << index << "]: ";
            cin >> update;
    }

    string buf;
    string title;
    int count = 1;

    while(current != nullptr) {
        if(count == update) {
            cout << "Enter an updated name for " << current->title << "(within 30-characters): ";
            cin.ignore();
            getline(cin, title);
            while(title.length() > 30) {
                cout << title << " exceeds 30-characters.\n";
                cout << "Enter an updated name for " << current->title << "(within 30-characters): ";
                getline(cin, title);
            }

        current->title = title;
        cout << "Enter the year you saw " << current->title << " [like 2017]: ";
            cin >> buf;
        current->viewed_year = atoi(buf.c_str());
        cin.ignore(1000, 10);

        cout << "Enter your rating for " << current->title << " [1, 2, 3, 4, 5]: ";
            cin >> buf;
        current->rating = atof(buf.c_str());
        cin.ignore(1000, 10);

        while(current->rating < 1 || current->rating > 5) {
            cout << "Invalid rating, please try again!\n";
            cout << "Enter your rating for " << current->title << " [1, 2, 3, 4, 5]: ";
                cin >> buf;
            current->rating = atof(buf.c_str());
            cin.ignore(1000, 10);
        }
        cout << '\n';
        }
        current = current->next;
        count++;
    }
}

void remove_movie(Movie* head, int index) {
    int remove = 0;

    cout << "Which movie to remove [1-" << index << "]: ";
        cin >> remove;
    while(remove < 1 || remove > index) {
        cout << "Invalid choice, please try again!\n";
        cout << "Which movie to remove [1-" << index << "]: ";
            cin >> remove;
    }

    Movie* temp;

    int count = 1;

    while(temp != nullptr) {
        if(count == remove) {
            temp = head->next;
            head->next = temp->next;
            delete temp;
        } else {
            temp = temp->next;
            count++;
        }
    }
}

void list_movie(const Movie* head) {
    cout << "\n# " << setw(30) << left << "Title" << setw(7) << right << "Viewed" << setw(9) << "Rating\n";

    for(int i = 0; i < 47; i++) {
        cout << "=";
    }
    cout << '\n';

    int movieIndex = 1;

    for(const Movie* p = head; p; p = p->next) {
        cout << movieIndex << " " << setw(30) << left << p->title;
        cout << right << setw(7) << p->viewed_year;
        cout << setw(8) << p->rating << endl;
        movieIndex++;
    }
    cout << '\n';
}


Feel free to give me feedback and if there is other issues I might have missed, thanks!

- Joe

Is This A Good Question/Topic? 0
  • +

Replies To: Remove node & setting limits

#2 jimblumberg   User is online

  • member icon

Reputation: 5812
  • View blog
  • Posts: 17,743
  • Joined: 25-December 09

Re: Remove node & setting limits

Posted 12 March 2020 - 02:34 PM

Quote

Feel free to give me feedback and if there is other issues I might have missed, thanks!

You may want to check your "sort" routines, I don't think they're working properly. Also there is a lot of code duplication in those functions that you may want to try to reduce.

Also you should consider creating an "add" function instead of doing everything manually in main(), a "find" function would probably also be helpful as well.

It would also be better if you separated the User Interface (cin/cout) from the actual program logic where ever possible. For example the update_movie function could be broken to several smaller functions, each function doing one thing. Let the class handle the data and validation, and move the UI into separate functions.


Now to your actual question/problem:

Quote

I need some help to remove nodes


What is the actual problem? This is another place where separating the UI from the program logic would probably help.

Jim
Was This Post Helpful? 0
  • +
  • -

#3 PendeJoe   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 59
  • Joined: 09-October 19

Re: Remove node & setting limits

Posted 12 March 2020 - 08:30 PM

Can you be more specific where my sort functions are not working properly? I can't see anything wrong with it.
The reason why I have put it in the main function manually is because it was a requirement.

And about my question, I im trying to make my remove node function to work, for some reason it either removes 2 nodes or just crashes
Was This Post Helpful? 0
  • +
  • -

#4 Salem_c   User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 2426
  • View blog
  • Posts: 4,566
  • Joined: 30-May 10

Re: Remove node & setting limits

Posted 12 March 2020 - 10:32 PM

Lines 30 to 45 and line 215 are a problem.

You're deleting something you never made with new.
Was This Post Helpful? 0
  • +
  • -

#5 jimblumberg   User is online

  • member icon

Reputation: 5812
  • View blog
  • Posts: 17,743
  • Joined: 25-December 09

Re: Remove node & setting limits

Posted 12 March 2020 - 11:08 PM

Quote

Can you be more specific where my sort functions are not working properly? I can't see anything wrong with it.

Try with different data. I only really played with the titles, try with different length strings, different order of the same strings, etc.

Jim
Was This Post Helpful? 0
  • +
  • -

#6 PendeJoe   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 59
  • Joined: 09-October 19

Re: Remove node & setting limits

Posted 13 March 2020 - 01:29 AM

Jim: Yeah I noticed that capital letters matter at the moment, working on a limit! Also cut down on the repeated codes to make it more readable.

Salem: Can you explain 30-45? This is the way my teacher showed me
Was This Post Helpful? 0
  • +
  • -

#7 jimblumberg   User is online

  • member icon

Reputation: 5812
  • View blog
  • Posts: 17,743
  • Joined: 25-December 09

Re: Remove node & setting limits

Posted 13 March 2020 - 07:01 AM

Quote

Can you explain 30-45? This is the way my teacher showed me

The problem is the combination of lines 30 - 45 and line 215.

What is the first requirement for using delete?

Quote

Yeah I noticed that capital letters matter at the moment,

It isn't just capital letters, the sort seems to also be order sensitive, and even possibly length of the string sensitive.

Try with something like:
    Movie a = { "movie3"};
    Movie b = { "movie1"};
    Movie c = { "movie2"};



Quote

The reason why I have put it in the main function manually is because it was a requirement.


What exactly is this "it" you're talking about? Perhaps you should share the requirements?


Jim
Was This Post Helpful? 0
  • +
  • -

#8 PendeJoe   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 59
  • Joined: 09-October 19

Re: Remove node & setting limits

Posted 13 March 2020 - 12:17 PM

Quote

The reason why I have put it in the main function manually is because it was a requirement.


So in this assignment I was required to have it like this :
1 Movie a = { "movie3"};
2 Movie b = { "movie1"};
3 Movie c = { "movie2"};


and we couldn't add more nodes we just had to go with the 3 we manually created.

Quote

The problem is the combination of lines 30 - 45 and line 215.
What is the first requirement for using delete?


I think I should ask my teacher that because I was not told how to use delete didn't even know I could use it before I was checking how to remove nodes online

This post has been edited by PendeJoe: 13 March 2020 - 12:18 PM

Was This Post Helpful? 0
  • +
  • -

#9 jimblumberg   User is online

  • member icon

Reputation: 5812
  • View blog
  • Posts: 17,743
  • Joined: 25-December 09

Re: Remove node & setting limits

Posted 13 March 2020 - 12:34 PM

Quote

I think I should ask my teacher that because I was not told how to use delete didn't even know I could use it before I was checking how to remove nodes online

Did you read all of Salem's post? For example:

Quote

You're deleting something you never made with new.


That's the first rule about using delete, you must first use new. Where in your code did you use new?

Quote

and we couldn't add more nodes we just had to go with the 3 we manually created.


What? There is no reason you can't use more "nodes" for testing the program. But since the program isn't working properly with three nodes not adding more is not really necessary.

And without seeing your actual assignment I still think you could simplify main() and also the rest of the program by adding more functions.


Jim
Was This Post Helpful? 0
  • +
  • -

#10 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7291
  • View blog
  • Posts: 24,675
  • Joined: 05-May 12

Re: Remove node & setting limits

Posted 13 March 2020 - 04:30 PM

View PostPendeJoe, on 13 March 2020 - 03:17 PM, said:

I was not told how to use delete didn't even know I could use it before I was checking how to remove nodes online

And there in lies your problem. You just looked online and likely just copied the code presented there without understanding what you were copying or the code that was presented. The code that you found online has the nodes dynamically allocated from the heap by new and therefore should be deallocated by calling delete. In the case of the code you are presenting, you are using automatic variables. Automatic variables live on the stack and are deallocated at the end of their scope.
Was This Post Helpful? 0
  • +
  • -

#11 Salem_c   User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 2426
  • View blog
  • Posts: 4,566
  • Joined: 30-May 10

Re: Remove node & setting limits

Posted 13 March 2020 - 11:03 PM

The whole thing stinks of being code found on the internet, then being cluelessly hacked about.

From 2017 -> https://www.cplusplu...eginner/223484/

> swap(*p, *q);
This defeats the entire purpose of having a linked list to begin with.
That purpose being, if you want to rearrange things, you're only supposed to modify the next pointers.

Regardless of whether this 'works' or not, doing something like that would be an instant grade 'F' in my class.
Was This Post Helpful? 0
  • +
  • -

#12 PendeJoe   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 59
  • Joined: 09-October 19

Re: Remove node & setting limits

Posted 15 March 2020 - 03:19 PM

So the only part I looked online for was the remove part, how main is structured is from our teacher where we were told to start off this way. I have skipped the delete part and changed a little and now I get the 2nd & 3rd movie to be removed but still can't figure out how to remove the first movie. Does it have anything to do with:
Movie* firstMovie = nullptr;

    Movie a = { "movie3"};
    Movie b = { "movie2"};
    Movie c = { "movie1"};

    a.next = firstMovie;
    firstMovie = &a;
    size++;

    b.next = firstMovie;
    firstMovie = &b;
    size++;

    c.next = firstMovie;
    firstMovie = &c;
    size++;

Was This Post Helpful? 0
  • +
  • -

#13 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7291
  • View blog
  • Posts: 24,675
  • Joined: 05-May 12

Re: Remove node & setting limits

Posted 15 March 2020 - 04:23 PM

Without seeing your updated code, it's really hard to say exactly why you are having problems with removing the first movie.

Personally, though, I think that part of the issue may have to do with the signature of your function:
void remove_movie(Movie* head, int index);



If the movie to be removed is the first movie, then how will this function tell the caller that there is now a new head? Recall that C and C++ are pass by value by default.
Was This Post Helpful? 0
  • +
  • -

#14 PendeJoe   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 59
  • Joined: 09-October 19

Re: Remove node & setting limits

Posted 15 March 2020 - 08:55 PM

So this is what I have come up with so far :
void remove_movie(Movie* head, int index) {
    int remove = whatMovieRem(index); //Gather input from user of what movie to remove

    int count = 1;

    Movie* current = head;
    Movie* prev = nullptr;

    while(current != 0) {        //find node to remove
        if(count == remove) {    //If the node for the desired movie to remove is found break
            break;
        }
        prev = current;          //Otherwise keep looking until right node is found 
        current = current->next;
        count++;
    }
    if(current) {                      //Issue within this body, help here pls
        if(prev) {                         
            prev->next = current->next;
        } else {
            head = current->next;
        }
    }
}


Am I missing something? If so explain please! I've been through lecture files and looking for online guides and I can't find anything that explains it good enough.
Was This Post Helpful? 0
  • +
  • -

#15 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7291
  • View blog
  • Posts: 24,675
  • Joined: 05-May 12

Re: Remove node & setting limits

Posted 16 March 2020 - 06:14 AM

Your line 21 is not really passing the value back out of your remove_movie().

Give this a quick try and see what results you get:
#include <iostream>

void add(int a, int b, int sum)
{
    sum = a + b;
}

int main()
{
    int sum = 0;
    add(1, 1, sum);
    std::cout << sum << std::endl;
}


The reason why sum didn't change is because C++ is pass by value.

In your code in post #14, even though you changed head, that change is only local to your function. You need to somehow pass that change back out of the function.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2