Question about Iterators

Started by
2 comments, last by Twisol 15 years, 1 month ago
Hey fellows, I'm back xD. Well I made a program that reports the length of the longest and shortest string of a set of words which the user writes. I used iterators but I don't know very well how they work. I tried to make something like itr += 2, so that it could pass 2 positions from the beginning, but this didn't work. I had to use a double ++itr but it looks really nasty. Take a look at my code:

// Program to report the length of the longest and shortest string
// introduced by the user
#include <iostream>
#include <string>
#include <list>

using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::list;

int main()
{
	// ask the user for a set of strings
	cout << "Please introduce a phrase or any kind of words (at least 2 words)." << endl
		 << "Do it, followed by an eof (ctrl + z):" << endl;

	// list and strings where the longest and shortest
	// word will be stored
	list<string> words;
	string word, long_w, short_w;

	// read the words until you find an eof
	// invariant: words contains all word readed so far
	while(cin >> word)
		words.push_back(word);
	
	// create an iterator, itr, pointing to the first element in words list
    // and a duplicate, jtr, positioned in the second element
	typedef list<string>::iterator list_itr;
	list_itr itr = words.begin();
	list_itr jtr = itr;
	++jtr;

	// we compare the first two elements.
	// The longest is stored into long_w,
	// the shortest into short_w.
	long_w = *itr;
	short_w = *jtr;
	string::size_type l_size = long_w.size();
	string::size_type sh_size = short_w.size();
	if(sh_size > l_size){
		long_w = *jtr;
		short_w = *itr;
		l_size = long_w.size();
		sh_size = short_w.size();
	}
	// I don't know why I can't make something like
	// itr += 2;
	// Pls explain me how can I do this better,
	// a double ++itr looks very ugly.
	++itr; ++itr;

	// compare the size of the rest of the words
	// invariant: itr elements compared so far
	for(; itr != words.end(); ++itr){
		string aux_w = *itr;
		if(aux_w.size() > l_size){
			long_w = aux_w;
			l_size = long_w.size();
		}else{
			if(aux_w.size() < sh_size){
				short_w = aux_w;
				sh_size = short_w.size();
			}
		}
	}

	// output the results
	cout << "The longest word is: " << long_w << endl
		 << "The shortest word is: " << short_w << endl;

	return 0;
}

Also, I'll like to here what do you think of my code. Is it a good implementation? or, how would you do it? Greetings, gL ^^ [Edited by - BroL1 on March 14, 2009 6:44:13 AM]
Advertisement
In this case I'd just use a vector. A (linked) list is just objects in memory pointing to the next one in the list, meaning you can easily remove, insert, and generally re-order them. The problem is that you're not doing any of these things, except pushing onto the end of the list, and the vector handles that just fine.

The reason itr += 2 doesn't work is because list iterators don't support random access. You have to move through each element in the list and follow its pointer to the next one, one at a time. Vectors are contiguous, and each element takes up the same amount of space, so it can just take itr + 2 and move forward in memory 2 times the amount of memory each element takes up. Lists, on the other hand, allow elements being scattered all over memory (even in a different order from how you actually follow the list), because each element points to the next one on its own.

Quote:Original post by BroL1
Also, I'll like to here what do you think of my code. Is it a good implementation? or, how would you do it?


Personally, I'd keep two strings and not bother with a vector, and every time you get a new word in, you compare the lengths and see if it's larger than the largest or smaller than the smallest. Like so:

std::string smallest = "";std::string largest  = "";// get in the first word just to get it startedcin >> smallest;smallest = largest; // true if we have only one word!std::string temp;while (cin >> temp){    if (temp.size() > largest.size())        largest = temp;    if (temp.size() < smallest.size()        smallest = temp;}


~Jonathan


EDIT: Also... I realized that I had told you tags were what you wanted, in your last thread. I typo'd; I meant [ source] [lol]. [ code] is better for short snippets.
Thx Twisol, now I know a bit more about containers :D

Quote:Original post by Twisol
Personally, I'd keep two strings and not bother with a vector, and every time you get a new word in, you compare the lengths and see if it's larger than the largest or smaller than the smallest.

I really had this idea in mind before making the program, but I got confused while implementing it. So I decided to move on with a list. It seems I walked the harder path :P

Here's the code with a better implementation. Thx to twisol ;)
// Program to report the length of the longest and shortest string// introduced by the user#include <iostream>#include <string>using std::cout;using std::cin;using std::endl;using std::string;int main(){	// ask the user for a set of strings	cout << "Please introduce a phrase or any kind of words (at least 2 words)." << endl		 << "Do it, followed by an eof (ctrl + z):" << endl;	// list and strings where the longest and shortest	// word will be stored	string short_w, long_w, word;	// read the first word introduced and save it	// in the long_w and short_w variables.	// This is because if just one word is introduced,	// the longest and shortest string will be the same.	cin >> short_w;	long_w = short_w;	// read the rest of the words until you find an eof	while(cin >> word){		if(word.size() > long_w.size())			long_w = word;		if(word.size() < short_w.size())			short_w = word;	}	// output the results	cout << "The longest word is: " << long_w << endl		 << "The shortest word is: " << short_w << endl;	return 0;}


I have a question 'bout you Twisol, I don't know if you can answer me, it's cause I like to ask about the experience of people I met :). I'm just wondering what do you do for living? are you a game developer? and, how did you start in this gaming thing?

I hope it doesn't take you too much to answer, I don't want all details. I just like to here fellow's stories, 'cause one day I'm going to be a game developer and I want to get all the experience I can.

Greetings, Eric.

gL

[Edited by - BroL1 on March 15, 2009 7:34:58 AM]
I'll PM ya. [smile]

~Jonathan

This topic is closed to new replies.

Advertisement