简体   繁体   中英

STL linked list issues

My logic seems to be wrong in my code. The rule states that for every "e" at the end of a 3 or more letter word, the "e" must be removed. So for example "remove" would be changed to "remov" or another example is "ease" would be changed to "eas". I tried using myList.size -1 but i got a compilation error. Can somebody please help?

I will mark down the error spot for convenience.

#include <iostream>
#include <list>
#include <ctype.h>
#include <fstream>

using namespace std;

void printList(const list<char> &myList);
void fillList(list<char> &myList);
void change(list <char> &myList);

void printList(const list<char> &myList)
{
    list<char>::const_iterator itr;
    for (itr = myList.begin(); itr != myList.end(); itr++ )
    {
        cout <<*itr;
    }
    cout << '\n' << endl;
}

void fillList(list<char> &myList)
{
    ifstream file("test.txt");
    string print;
    while(file >> print)
    {
        for (int i = 0; i<=print.length(); i++)
        {
            myList.push_back(print[i]);
        }
        myList.push_back(' ');
    }
}

void change(list <char> &myList)
{
    list<char>::iterator itr;

    //rules are as follows

    //change w with v
    for (itr = myList.begin(); itr != myList.end(); itr++ )
    {
        if (*itr == 'w')
        {
            *itr = 'v';
        }

    }

    //remove e at the end of a 3+ letter word
    //PROBLEM HERE
    for (itr = myList.begin(); itr != myList.end(); itr++ )
    {
        std::list<char>::iterator itr2 = myList.size() - 1;
        if(myList.size() > 3 && itr2 == 'e')
        {
            myList.erase(itr2);
        }
    }
}

int main ()
{
    list<char> myList;
    ifstream file("test.txt");
    const string print;
    fillList(myList);
    printList(myList);
    change(myList);
    printList(myList);

    return 0;
}

You are using the following logic to remove e s.

for (itr = myList.begin(); itr != myList.end(); itr++ )
{
    std::list<char>::iterator itr2 = myList.size() - 1;
    if(myList.size() > 3 && itr2 == 'e')
    {
        myList.erase(itr2);
    }
}

The line

    std::list<char>::iterator itr2 = myList.size() - 1;

leads to compiler error since the RHS of the assignment operator is of type size_t . You cannot use a size_t to initialize an object of type std::list<char>::iterator .

More importantly, you don't seem to have thought through the logic clearly.

To remove an item from the list, it has to meet three criteria.

  1. The item is e .
  2. The item is the last letter of a word.
  3. The word must be of length 3 or greater.

The first check is simple.

if ( *itr == 'e' )

The second check is a little more complex.

auto next = std::next(itr);
if ( *next == '\0' )

The third check is a little bit more complex than either of the first two. Since your list has embedded null characters followed by a space character before the next word starts, you'll need to keep a counter for word length and reset it when you see a space character.

Here's a block of code that implements the above logic:

int wordLength = 1;

// Don't use ++iter in the last clause of the for statement.
// iter is incremented only when the item is not removed.
// It is updated differently when the item is removed.

for (itr = myList.begin(); itr != myList.end(); )
{
   if ( needToRemove(itr, wordLength) )
   {
      // Remove the item.          
      itr = myList.erase(itr);
   }
   else
   {
      ++itr;
      ++wordLength;
   }
   if ( *itr == ' ' )
   {
      // Reset word length. The next character is
      // going to be the start of the next word.
      wordLength = 0;
   }
}

where needToRemove is defined as:

bool needToRemove(list<char>::iterator itr,
                  int wordLength) 
{
   if ( *itr != 'e' || wordLength < 3)
   {
      return false;
   }

   auto next = std::next(itr);
   return (*next == '\0');
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM