CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Feb 2010
    Posts
    21

    eliminating an entry from a vector without changing the order

    THE FIRST PART OF THIS IS BACKGROUND INFO ABOUT THE PROGRAM
    I'm trying to write a program that inputs names from a file into a vector. The user will enter a number greater than 0 to be the "goose". The goose will be removed from the list, and then a new goose will be selected by counting to the goose number again, starting counting with the next person in the list.

    When ran completely through it would look something like this:
    Enter the position of the GOOSE: 2
    Tom Jan Eddy Bill
    Tom Eddy Bill
    Tom Eddy
    Tom
    ----------------------------------------------------------------------------------------------------------------

    I need to remove the name from the list without changing the order, so I was going to do a series of interchanges until the "goose" was moved to the last spot in the vector, and then just pop it off the vector. I was going to send the location of the goose to my interchange function, and swap names[entry] with names[entry+1] until it was at the end of the vector. However that will not work if the user enters a number greater than the number of names in the vector. If someone enters 8, and there are only 3 names in the vector, it needs to keep looping until it finds the 8th name (which would be the 2nd name in the list of 3).

    Really I'm open to all around any logic that may help with this problem. How would I deal with the problem of having to do a roll over effect if the user enters a number greater than names.size() and how I could go about interchanging until the "goose" is the last entry in the vector.

    It doesn't help that I just learned how to use vectors either. Below is my code at the moment, the wackGoose function was supposed to be doing the eliminating but its empty.

    Code:
    #include <iostream>
    #include <string>
    #include <iomanip>
    #include <vector>
    #include <fstream>
    
    using namespace std;
    
    //CONSTANTS AND PROTOTYPES SECTION
    
    void introduction();
    //Introduce program and programmer
    void getNames(vector<string> names);
    //fills the vector with names
    void getGoose(int&goose);
    //gets the gooseth entry from the user
    void wackGoose(vector<string> names, int goose);
    //eliminates the gooseth entry over and over
    template <class myType>
    void interchange(myType&a, myType&b);
    //interchanges two names
    
    
    int main()
    {
    	introduction();
    	cout << endl << endl;
    
    	vector<string> names;
    	int goose;
    
    	getNames(names);
    	getGoose(goose);
    	wackGoose(names, goose);
    
    
    	cin.ignore();
    	cin.get();
    	return 0;
    }
    
    
    //DEFINITIONS SECTION
    
    void getNames(vector<string> names)
    //fills the vector with names
    {
    	string name;
    	ifstream fin;
    	fin.open("C:/Users/Josh/Desktop/goosey.txt");
    
    	int count =0;
    	while(fin >> name)
    	{
    		names.push_back(name);
    		cout << names[count] << "  ";
    		++count;
    	}
    
    	cout << endl;
    }
    
    
    void getGoose(int&goose)
    //gets the gooseth entry from the user
    {
    	do{
    	cout << "Enter the position of the GOOSE: ";
    	cin >> goose;
    	}while(goose<1);
    }
    
    
    void wackGoose(vector<string> names, int goose)
    //eliminates the gooseth entry over and over
    {
    	int entry;
    	entry = goose-1;
    
    	
    
    
    }
    
    template <class myType>
    void interchange(myType&a, myType&b)
    //interchanges two names
    {
    	myType temp = a;
    	a=b;
    	b=temp;
    }

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: eliminating an entry from a vector without changing the order

    Quote Originally Posted by jopeters View Post
    When ran completely through it would look something like this:
    Enter the position of the GOOSE: 2
    Tom Jan Eddy Bill
    Tom Eddy Bill
    Tom Eddy
    Tom
    First things first: decide right now whether this number is going to be 1-based or 0-based. You seem to be making it 1-based above (otherwise Eddy would be name #2, not Jan), but vectors are 0-based, so that's going to add a slight complication the program. It's manageable if that's what you really want, just be consistent.

    I need to remove the name from the list without changing the order, so I was going to do a series of interchanges until the "goose" was moved to the last spot in the vector, and then just pop it off the vector.
    That will work, but in practice it's probably just as easy to do v.erase(v.begin()+i). If your compiler supports C++0x move semantics and an STL implementation supporting them, this will be even more efficient than your proposed method. If not (likely at this point, unfortunately), it will be less efficient....but for this sort of program you probably shouldn't care. The difference will be milliseconds. (EDIT: I was assuming you were using std::string::swap() for exchanging. Given that I now see you aren't, this will definitely be more efficient than your current method.)

    However that will not work if the user enters a number greater than the number of names in the vector. If someone enters 8, and there are only 3 names in the vector, it needs to keep looping until it finds the 8th name (which would be the 2nd name in the list of 3).
    Use the mathematical concept of modulus. Remember when you learned division in terms of remainders, eg, 8/3 = 2 remainder 2? Modulus gives you just the remainder, and in C++ is represented by the &#37; sign. So 8 % 3 == 2.

    However, note that mod n will return a value in the range[0,n-1]----a 0-based index. If you want a 1-based index, you'll need to subtract 1 prior to the mod and add 1 to the result. Again, be consistent.

    Code:
    void getNames(vector<string> names);
    //fills the vector with names
    void wackGoose(vector<string> names, int goose);
    //eliminates the gooseth entry over and over
    You'll want to pass those vectors by reference, or else the code won't do what you want. In general, nontrivial-sized objects (like vectors) should always be passed by reference or const reference, to avoid making unnecessary copies.

    Code:
    template <class myType>
    void interchange(myType&a, myType&b);
    //interchanges two names
    Two things. First, I would suggest just using the std::swap() function rather than writing your own if you need this functionality. (If you use the vector's erase() method as above, you won't need it at all.) Second, std::string has a swap() method which is more efficient than how you're doing it right now. (std::swap() is smart enough to use it when it's available.)

    Code:
    	int count =0;
    	while(fin >> name)
    	{
    		names.push_back(name);
    		cout << names[count] << "  ";
    		++count;
    	}
    While this is a perfectly good loop, I would point out that you can simply output names.back() rather than keeping a separate count variable around.
    Last edited by Lindley; April 24th, 2010 at 01:11 PM.

  3. #3
    Join Date
    Feb 2010
    Posts
    21

    Re: eliminating an entry from a vector without changing the order

    thanks a ton that info will definitely be helpful. Unfortunately I cannot use the std::swap() function for this assignment due to restrictions from my professor. At this point I am less concerned with efficiency and more concerned with getting it to work.

    This might sound very newbie but could you explain the difference between passing those vectors by reference and what I did? I thought I did pass them by reference but I guess not. I just learned about vectors a week ago so some things I haven't completely figured out yet.

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: eliminating an entry from a vector without changing the order

    Quote Originally Posted by jopeters View Post
    thanks a ton that info will definitely be helpful. Unfortunately I cannot use the std::swap() function for this assignment due to restrictions from my professor.
    Well, if you use the vector::erase() member method, there's no need to swap or interchange anything anyway.

    This might sound very newbie but could you explain the difference between passing those vectors by reference and what I did? I thought I did pass them by reference but I guess not. I just learned about vectors a week ago so some things I haven't completely figured out yet.
    Pass by reference is unrelated to vectors; they're completely different concepts. You clearly understand how to pass an int by reference, since you're doing it in a few places. The key is the & in the parameter list. Since there isn't an & for the vector parameters, they're being passed by value.

  5. #5
    Join Date
    Feb 2010
    Posts
    21

    Re: eliminating an entry from a vector without changing the order

    I thought you meant to pass them as follows:

    Code:
    void wackGoose(const vector<string>&names, int goose);
    But when I do that I get the following compiler errors.

    Error 1 error LNK2001: unresolved external symbol "void __cdecl wackGoose(class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > const &,int)" (?wackGoose@@YAXABV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@H@Z) project4.obj project4

    Error 2 fatal error LNK1120: 1 unresolved externals C:\Temp\project4\Debug\project4.exe project4

  6. #6
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: eliminating an entry from a vector without changing the order

    Just make sure that your function's forward-declaration matches its definition. That error frequently arises from a mismatch between the two.

  7. #7
    Join Date
    Feb 2010
    Posts
    21

    Re: eliminating an entry from a vector without changing the order

    you were right, it will compile but it crashes when the main calls the wackGoose function.

    Code:
    void wackGoose(const vector<string>&names, int goose)
    //eliminates the gooseth entry over and over
    {
    	int entry;
    
    	entry = goose&#37;names.size();
    	cout << entry;
    
    }
    I wrote that real quick just to test if I could get it produce the correct number for the "goose". But when the function is called it crashes and says project4.exe has stopped working.

  8. #8
    Join Date
    Feb 2010
    Posts
    21

    Re: eliminating an entry from a vector without changing the order

    solved the previous problem! thanks for all your help lindley you are the man.

  9. #9
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: eliminating an entry from a vector without changing the order

    Well, there's nothing wrong with that function. It's possible you've managed to corrupt the vector's memory somewhere, in which case size() might have failed.

    Now's the time to break out your debugger so you can at least figure out which specific statement is causing problems; that won't necessarily point you at the issue, but it will give you a place to start looking.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured