0

Hello everyone can someone help me to delete the shortest word from the linked list without array?

I'am a first course student and learning pointers with linked list etc. This is my last task to do and I'am stuck.

This code finds the shortest word of the list and I need to delete that word.

I don't know how to delete that specific word.

My problem is that "del" function deletes wrong word:

void del (Node *shorter)
    {
        Node* temp;
        temp = shorter->next;
        shorter->next = temp->next;
        cout<<"Deleted: "<<temp->data<<endl;
        delete temp;
    }

This is my full code:

#include <iostream>
#include <vector>
#include <iterator>

using namespace std;

std::vector<std::string> split(const std::string& source, const std::string& delimiters = " ") {
    std::size_t prev = 0;
    std::size_t currentPos = 0;
    std::vector<std::string> results;

    while ((currentPos = source.find_first_of(delimiters, prev)) != std::string::npos) {
        if (currentPos > prev) {
            results.push_back(source.substr(prev, currentPos - prev));
        }
        prev = currentPos + 1;
    }
    if (prev < source.length()) {
        results.push_back(source.substr(prev));
    }
    return results;
}

struct Node {
    std::string data;
    Node* next;
};
struct Node* head = NULL;

Node* createList() {
    string text;
    cout << "Write text: ";
    getline(cin, text);

    Node *head = new Node();
    head->next = NULL;
    Node *current = head;

    string delimiters = " ,.-':;?()+*/%$#!\"@^&";
    auto results = split(text, delimiters);

    bool isFirst = true;
    for (const auto& word : results) {
        if (isFirst) {
            current->data = word;
            isFirst = false;
        } else {
            Node *newNode = new Node();
            newNode->data = word;
            current->next = newNode;
            current = newNode;
        }
    }

    return head;
}

void del (Node *shorter)
{
    Node* temp;
    temp = shorter->next;
    shorter->next = temp->next;
    cout<<"Deleted: "<<temp->data<<endl;
    delete temp;
}


void findShortestWord(Node* head) {
    Node *current = head;
    Node *shorter = head;

    while (current != NULL) {
        if (current->data.size() < shorter->data.size()) {
            shorter->data = current->data;
        } else if (current->data.size() > shorter->data.size()) {
            current = current->next;
        } else if (current->data.size() == shorter->data.size()) {
            current = current->next;
        }
    }
    cout << "_____________________________________________________________" << endl;
    cout << "Shortest word: " << shorter->data << "                                |" <<endl;
    cout << "_____________________________________________________________|" << endl;
    del(shorter);
}

void print(Node* head)
{
    if (head == NULL and cout << endl)
        return;
    cout<<"\nThe word you entered: ";
    cout << head->data << ' ';
    print(head->next);
}

int main() {

     Node *head = createList();
     print(head);
     findShortestWord(head);
     print(head);

    return 0;
}
Johnny Mopp
  • 12,641
  • 5
  • 36
  • 62
Gronila
  • 11
  • 1
  • 3
    Did you try stepping through the code with a debugger? – Quimby May 31 '22 at 11:30
  • Some questions to ponder: what does `shorter` point to at the end of the loop? Does `del(shorter)` actually delete the node pointed to by `shorter`? What happens if `shorter` was the last node of the list? – Botje May 31 '22 at 11:33
  • 2
    Draw the act of removing a node out on paper. You will see the node previous to the node being deleted is also needed. – Johnny Mopp May 31 '22 at 11:35
  • Memory leak: https://godbolt.org/z/11Ezohr9c – Marek R May 31 '22 at 11:42
  • Your `del` is wrong it deletes next item not current one. You need `void del (Node **shorter)` or `void del (Node *&shorter)`. – Marek R May 31 '22 at 11:49
  • @MarekR Thanks but I tried it and nothing changes. – Gronila May 31 '22 at 12:10
  • Since you have to change more then just declaration of this function. This was just a hint. – Marek R May 31 '22 at 12:12
  • @Quimby No and I don’t really know how to do it – Gronila May 31 '22 at 12:15
  • Learn to use Debugger ASAP. The more skilled developer is then less he needs use the debugger. Newbie should use it constantly. There plenty instruction how to do it and it is easy. – Marek R May 31 '22 at 12:17
  • @MarekR I'm sorry to ask but could you help me to complete the code? Because I’ve been trying to do it for over two days and have to deliver by tomorrow – Gronila May 31 '22 at 12:18
  • Yes I could (I already have something), but you will not learn anything with this approach. – Marek R May 31 '22 at 12:20
  • @Gronila Then I suggest to learn, it's very useful skill. – Quimby May 31 '22 at 12:22
  • @MarekR Yes I understand that and I don't know what to do, because I need to write another code and do another university tasks because it is the end of the semester. – Gronila May 31 '22 at 12:31
  • Don't ask the same question twice? [How to delete the shortest word from the list using C++? Without an array](https://stackoverflow.com/questions/72437697/how-to-delete-the-shortest-word-from-the-list-using-c-without-an-array) – Goswin von Brederlow May 31 '22 at 15:01

2 Answers2

1

Since this is homework, I won't give a complete answer, but here's an example linked list. "it" is the shortest word. If we draw removing that node, it looks like this:

(head)           (shorter prev)   (shorter)        (shorter next)
┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│  hello   │────>│  world   │────>│    it    │────>│  other   │
└──────────┘     └──────────┘     └──────────┘     └──────────┘

Unlink "it"
┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│  hello   │────>│  world   │───┐ │    it    │ ┌──>│  other   │
└──────────┘     └──────────┘   ↓ └──────────┘ ↑   └──────────┘
                                └──────────────┘
                                
New list
┌──────────┐     ┌──────────┐     ┌──────────┐
│  hello   │────>│  world   │────>│  other   │
└──────────┘     └──────────┘     └──────────┘

Now you can delete shorter.

We can't unlink a node without knowing the address of the previous node. (If the previous node is nullptr we are deleting the head.) So, in findShortestWord(), while walking the list to find the shortest word, keep track of the previous node and use that in del().

Another option is to change the struct to include the a prev member (doubly linked list).

struct Node {
    std::string data;
    Node* prev;
    Node* next;
};

Note: You can unlink a node without any temp variables.

Johnny Mopp
  • 12,641
  • 5
  • 36
  • 62
0

There are some edge cases you miss here. what if the word you delete is the last word in your list? In that case your code will not work properly beacause notice that: temp=shortest->next but shortest->next=NULL and therefore when you will execute the code line shortest->next=temp->next the compiler throw to you exception that temp was nullptr.

DorI
  • 22
  • 6
  • Could you help complete the code? Because I’ve been trying to do it for over two days and have to deliver by tomorrow – Gronila May 31 '22 at 12:08