Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums

Go Back   Code Forums > Application and Web Development > Standard C, C++

Reply
 
LinkBack Thread Tools Display Modes
Old 10-23-2004, 12:14 PM   #1 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Reversing a string and palindromes.

I will present two forms:
- the STL way.
- the traditional way.

the STL way
Code:
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

//Optional functions: depends on IDE.
void wait_for_enter();

int main()
{
   string sOriginal("123321");
   string sReversed(sOriginal);

   reverse(sReversed.begin(), sReversed.end());
   cout<<sOriginal<<endl;
   cout<<sReversed<<endl;
   
   if(sOriginal == sReversed)
   {
      cout<<"Palindrome detected!"<<endl;
   }
   
   wait_for_enter();
   return 0;
}

//---------------------------------------------------

void wait_for_enter()
{
  cout << "press <enter> to continue...";
  // Reset failstate, just in case.
  cin.clear();
  string line;
  getline( cin, line);
}
the traditional way
Code:
#include <iostream>
#include <string>

using namespace std;

//Optional functions: depends on IDE.
void wait_for_enter();

int main()
{
   string sOriginal("123321");
   string sReversed;
   
   unsigned size = sOriginal.size();
   for(unsigned i=0; i < size; ++i)
   {
      //Traverse from sOriginal[5] to sOriginal[0] *IF* sOriginal.size() == 6.
      sReversed += sOriginal[size-i-1];
   }
   
   cout<<sOriginal<<endl;
   cout<<sReversed<<endl;
   
   if(sOriginal == sReversed)
   {
      cout<<"Palindrome detected!"<<endl;
   }
   
   wait_for_enter();
   return 0;
}

//---------------------------------------------------

void wait_for_enter()
{
  cout << "press <enter> to continue...";
  // Reset failstate, just in case.
  cin.clear();
  string line;
  getline( cin, line);
}
__________________
Valmont is offline   Reply With Quote
Old 10-23-2004, 12:31 PM   #2 (permalink)
Androto
Mac Os X User(I hate win)
 
Join Date: Oct 2004
Posts: 138
Androto is on a distinguished road
what about this. shouldn't this work? i got the idea from the last program we had to do.
Code:
#include <iostream>
#include <cstdlib>
#include <string>

string reverse(word);
void verify(string reversed, word);
////////////////// int main //////////////////////////////
int main (int argc, char * const argv[]) 
{
	string word, reversed;
	cout << "Please enter a word" << endl;
	cin >> word;
	reversed = reverse(word);
	verify(string reversed, word)
	return 0;
}
//////////////////// reverse the word ////////////////////////////
string reverse(word)
{
	string word;
	string wordr;
	int i, j;
	i = 0;
	cout << "Please enter a word." << endl;
	cin >> word;
	j = word.size;
	while (i <= j)
	{
		wordr[i] = word[j];
		i++;
		j--;
	}
return wordr;
}
/////////////////// check reversed word /////////////////////////////
void verify(string reversed, word)
{
	string wordr;
	string word;
	if (word == wordr)
	{
		cout << "This word is a pallendrome" << endl;
	}
	else
	{
		cout << "This word is not a pallendrom" << endl;
	}
}
if this could work, what did i do wrong?
Androto is offline   Reply With Quote
Old 10-23-2004, 01:54 PM   #3 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
There are a lot of serious mistakes in your code, but first things first.

the core
The core of the application is to reverse letters in a std::string.
Now suppose I do this:
Code:
string sTheWord("Hello");
string sReversedWord;
The question is: would the code below work?
Code:
sReversedWord[0]=sTheWord[0];
The anwer is NO. Why?
Because C++ did NOT allocate any space for sReversedWord. So sReversedWord[0] is not defined yet (does not exist), since this is the first element of that word. But there IS NO element at all yet.
We can solve this problem by allocating some space for sReversedWord:
Code:
//Watch the space in the initialization!
sReversedWord(" ");
AHA! Now there exists a sReversedWord[0]! So this works now:
Code:
sReversedWord[0]=sTheWord[0];
cout<<sReversedWord<<endl;
//OUTPUT: t
But what if we need to copy more letters to sReversedWord? sReservedWord[1]..[n] does NOT exist! So do you want to allocate the number of spaces to sReservedWord, according to the number of elements in sTheWord? Offcourse not. That's why we need a better method: by using the operator+= (for example, see below for another way) :
Code:
string sTheWord("hi");
string sReversedWord; //Just a name for us, but not using space yet!

sReversedWord += sTheWord[1]; //AHA, now sReversedWord[0] is added on the spot!
sReversedWord += sTheWord[0]; //AHA, now sReversedWord[1] is added on the spot!
cout<<sReversedWord<<endl;
//OUTPUT: ih
Each time I add a letter to the whole std::string, C++ will allocate more memory for that extra element.

function handling
Your function handling is wrong. Look at this:
Code:
#include <iostream>
#include <cstdlib>
#include <string>

string reverse(word);
You are (forward) declaring a function. Good. But...
"word" has no type!
This is correct: string reverse(string word);
See? now the function knows what type the word is. Here is a little optimization though:
string reverse(const string& word);
If you don't know what this is then nevermind for now. Later we could chat about it huh?

function handling part 2
This is wrong what you did:
Code:
j = word.size;
it should be: j = word.size();
See the "()"?

communication
Coding is communication I say. Make sure your variables and your function names clearly tell strangers what you're up to. The difference between "word" and "wordr" is hard to spot, for example.

Take your time sir. Perhaps you won't be able to finish all your homework because you work neat, but really, Rambo's and C++ is not a good match. You'll find out soon enough when you move on with this.

the final program
Below is ANOTHER way to do the reversing. That makes three possibilities to reverse a std::string. In fact, you may think of 3 more ways. Or 4, or 5... :)
Code:
#include <iostream>
#include <string>

using namespace std;

//Optional functions: depends on IDE.
void wait_for_enter();
void reset_istream();

//Core
string reverse_stdString(const string&);
bool compare_stdStrings(const string&, const string&);

////////////////// int main //////////////////////////////
int main (int argc, char * const argv[])
{
  string sWord, sReversedWord;
   
   cout<<"Enter a word please: ";
   //Robustness omitted for clarity.
   cin>>sWord;
  
  sReversedWord = reverse_stdString(sWord);
   if( compare_stdStrings(sWord, sReversedWord) == true )
   {
      cout<<"Palindrome!"<<endl;
   }
   else
   {
      cout<<"Not a palindrome."<<endl;
   }
  
  reset_istream();
  wait_for_enter();
  return 0;
}
//////////////////// reverse the word ////////////////////////////

string reverse_stdString(const string& s)
{
   string reversed;
   int len = s.length();
   while (len != 0)
   {
      //Remember, an array starts with index 0 and therefore ends with n-1 !!
      reversed += s.substr(len-1, 1);
      --len;
   }
   return reversed;
}

/////////check reversed word  for equality with original word ///////

bool compare_stdStrings(const string& cmp1, const string& cmp2)
{
   if(cmp1 == cmp2)
      {
         return true;
      }
   else
      {
         return false;
      }
}

//---------------------------------------------------

void reset_istream()
{
   if(cin.eof())
   {
      cin.clear();
   }
   else
   {
      cin.clear();
      cin.ignore(numeric_limits<streamsize>::max(), '\n');
   }
}

//---------------------------------------------------

void wait_for_enter()
{
  cout << "press <enter> to continue...";
  // Reset failstate, just in case.
  cin.clear();
  string line;
  getline( cin, line);
}
If you don't know what const and & is then nevermind. You can remove these two things. Program will still work. Basically I am optimizing transfer speed (and memory usage!) and I am preventing my passed values to be modified.

substr(start, charcount) does this:
test = myString.substr(0, 1); //copy ONE character starting at location 0 to test.
test = myString.substr(5, 3); //copy THREE characters starting at location 5 to test.
Remember, arrays start with index 0 and end with size()-1!!!

a word on using do/while/for loops
In this reverse() function, and yours and many others, we used a while loop. I don't like it in this case. Why?
Remember I said programming is communicating?
Well, in this very while-loop, we guarantee the loop to finish if an index (len in our case) has reached a certain value. That value is guaranteed to be decreased to 0, if the machine doesn't break down or something. And it is also guaranteed that the Len value is decreased by 1, on every iteration. So since we have a guaranteed loop with a FIXED number of iterations, we should make it explicit by using a for-loop.

Why do you bother Val?
Well, a while-loop tells me:
"Hey, a while-loop, so it exits on a special condition. I do NOT know how many iterations are needed for this while-loop in advance, before this condition is met."
But that's wrong. We DO know when it ends. It ends when Len==0. And there is no special condition: Len is decreased by 1 on every iteration. This all makes me believe that the while-loop should be made explicit: use a for-loop.

your final job
Modify my reverse_stdSTring() function so it works with a for-loop instead of a while-loop.

Good luck!
__________________

Last edited by Valmont; 10-23-2004 at 02:32 PM.
Valmont is offline   Reply With Quote
Old 10-23-2004, 02:31 PM   #4 (permalink)
Androto
Mac Os X User(I hate win)
 
Join Date: Oct 2004
Posts: 138
Androto is on a distinguished road
ok. txh for all your hard work, but i really want to use my onw code, and i can barely recognize my own code in there. i fixed up my own code as much as i could, but i can't figure out what the following error means:

decleration of 'word' shadows parameters

and

parse error before ','


how could i fix that? here's the code with all of my corrections. i used some of the tips you gave me.
Code:
#include <iostream>
#include <cstdlib>
#include <string>

string reverse(string word);
void verify(string reversed, string word);
////////////////// int main //////////////////////////////
int main (int argc, char * const argv[]) 
{
	string word, reversed;
	cout << "Please enter a word" << endl;
	cin >> word;
	reversed = reverse(word);
	verify(string reversed, string word);
	return 0;
}
//////////////////// reverse the word ////////////////////////////
string reverse(string word)
{
	string wordin;
	string wordr;
	int i, j;
	i = 0;
	cout << "Please enter a word." << endl;
	cin >> wordin;
	j = wordin.size();
	while (i <= j)
	{
		wordr[i] = wordin[j];
		i++;
		j--;
	}
return wordr;
}
/////////////////// check reversed word /////////////////////////////
void verify(string reversed, string word)
{
	string wordr;
	string wordin;
	if (wordin == wordr)
	{
		cout << "This word is a palindrome" << endl;
	}
	else
	{
		cout << "This word is not a palindrom" << endl;
	}
}
Androto is offline   Reply With Quote
Old 10-23-2004, 02:32 PM   #5 (permalink)
Androto
Mac Os X User(I hate win)
 
Join Date: Oct 2004
Posts: 138
Androto is on a distinguished road
by the way, when i compile it, the only error i get is the second error i wanted to know about.

parse error before ','
Androto is offline   Reply With Quote
Old 10-23-2004, 02:37 PM   #6 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
I didn't even bother to look closely at your code.
Code:
wordr[i] = word[j];
I've explained why this doesn't work in your case.

"Shadowing" means that you redeclared a variable in a function, whilst that variable name already exists in as a parameter in that function.

Read my my post again, thorough.
In total I gave three possible solutions by the way.
This I really do NOT appreciate! It is saturday evening an I could think of much cooler things to do right now.
Most dissapointing.


Now this (although right now you don't deserve it):
Code:
void verify(string reversed, string word)
{
	string wordr;
	string wordin;
	if (wordin == wordr)
	{
		cout << "This word is a palindrome" << endl;
	}
	else
	{
		cout << "This word is not a palindrom" << endl;
	}
}
I didn't look at this code closely either so I don't know if it works. But one thing is sure:
You call it "verify" yet it is also responsible for output (cout<<..). Make your mind up. What does it do. Name it like that. For what it is worth (I suspect nothing), cout doesn't belong there. Let it check only.

I'm gone.
__________________
Valmont is offline   Reply With Quote
Old 10-23-2004, 06:32 PM   #7 (permalink)
Androto
Mac Os X User(I hate win)
 
Join Date: Oct 2004
Posts: 138
Androto is on a distinguished road
Quote:
Originally posted by Valmont
The question is: would the code below work?
Code:
sReversedWord[0]=sTheWord[0];
The anwer is NO. Why?
Because C++ did NOT allocate any space for sReversedWord. So sReversedWord[0] is not defined yet (does not exist), since this is the first element of that word. But there IS NO element at all yet.
We can solve this problem by allocating some space for sReversedWord:
Code:
//Watch the space in the initialization!
sReversedWord(" ");
AHA! Now there exists a sReversedWord[0]! So this works now:
Code:
sReversedWord[0]=sTheWord[0];
cout<<sReversedWord<<endl;
//OUTPUT: t
i don't understand what you mean by allocating space. are you saying that i have to make the compiler think that the sReversedWord string is an array before i can flip it around? i have no idea what is meant by this.

also, if i use this to flip around the word, would i still be able to use the rest of my own code?

one more thing. the error that i got before (parse error before ',' ) what exactly does that mean. my latest code is still the same as last time and still posted on the site.
Androto is offline   Reply With Quote
Old 10-23-2004, 06:54 PM   #8 (permalink)
gamehead200
Code Monkey
 
gamehead200's Avatar
 
Join Date: Oct 2004
Posts: 57
gamehead200 is an unknown quantity at this point
Thanks for your input, Valmont... However, why did you have to go and write out the whole program?? All I needed was the part to reverse the word...

In any other case, thank you very much! Your work is very much appreciated

BTW, Andrew, if you don't know what he's talking about, why don't you use Google to find out? Asking questions that can easily be answered using Google isn't always a good thing to do.
gamehead200 is offline   Reply With Quote
Old 10-23-2004, 07:02 PM   #9 (permalink)
Androto
Mac Os X User(I hate win)
 
Join Date: Oct 2004
Posts: 138
Androto is on a distinguished road
Quote:
Originally posted by gamehead200
Thanks for your input, Valmont... However, why did you have to go and write out the whole program?? All I needed was the part to reverse the word...

In any other case, thank you very much! Your work is very much appreciated

BTW, Andrew, if you don't know what he's talking about, why don't you use Google to find out? Asking questions that can easily be answered using Google isn't always a good thing to do.
by the way michael, he used my code and changed it, so you better not hand that in!
Androto is offline   Reply With Quote
Old 10-23-2004, 07:08 PM   #10 (permalink)
gamehead200
Code Monkey
 
gamehead200's Avatar
 
Join Date: Oct 2004
Posts: 57
gamehead200 is an unknown quantity at this point
I don't want to start an argument or anything, but the only part of the program that I was missing was the function where it would reverse the string... The rest of the program is completely different from yours and I wasn't planning on handing it in because I don't like to copy other people's work word for word...
gamehead200 is offline   Reply With Quote
Old 10-23-2004, 07:10 PM   #11 (permalink)
Androto
Mac Os X User(I hate win)
 
Join Date: Oct 2004
Posts: 138
Androto is on a distinguished road
Quote:
Originally posted by gamehead200
The rest of the program is completely different from yours and I wasn't planning on handing it in because I don't like to copy other people's work word for word... [/b]
ok. but atleast change the names of the strings.
Androto is offline   Reply With Quote
Old 10-23-2004, 07:16 PM   #12 (permalink)
gamehead200
Code Monkey
 
gamehead200's Avatar
 
Join Date: Oct 2004
Posts: 57
gamehead200 is an unknown quantity at this point
Quote:
Originally posted by Androto
ok. but atleast change the names of the strings.
Wow... I'm not THAT stupid...
gamehead200 is offline   Reply With Quote
Old 10-23-2004, 07:22 PM   #13 (permalink)
Androto
Mac Os X User(I hate win)
 
Join Date: Oct 2004
Posts: 138
Androto is on a distinguished road
Quote:
Originally posted by gamehead200
Wow... I'm not THAT stupid...
no comment (but i bet you can think of what i was going to say)
Androto is offline   Reply With Quote
Old 10-23-2004, 07:42 PM   #14 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Quote:
by the way michael, he used my code and changed it,
What are you talking about? Who is "he". I hope you don't mean me. I don't need "your" code. Conceptual my code is completely different from what you showed us here.

Quote:
Valmont... However, why did you have to go and write out the whole program??
Because I received some input form "somewhere else". So I decided to post the whole code. Only a few minutes of work.
Besides, I was in the mood to show various approaches. I posted 3. You can make a 4th (do-loop) and a 5th (while loop) and a 6th (using a char* with STL, very tricky)...
Anyway, if you understand the concept then you know enough.

Quote:
don't understand what you mean by allocating space. are you saying that i have to make the compiler think that the sReversedWord string is an array...
A std::string IS a container (sort of a luxury "array").
However, if you do this:
Code:
string sMyString;
Then sMyString is only a name for us humans. In the computer, there is no sMyString yet.
But each time you add something to that string, std::string will allocate memory for it, and then it does exist.

Example:
Suppose you do this:
Code:
string sMyString;
sMyString[0] = 'X';
Then the std::string will think:
"Hey, Androto is telling me that sMyString[0] truly exists. Therefore he did something that created sMyString[0]. Now he is trying to replace sMyString[0] with 'X'."
But that is not true yet. You didn't initialize the string with anything yet, so it doesn't exist. You're trying to fool td::string. You can't replace sMyString[0]. There is no [0] yet.

But if you do this:
Code:
string sMyString = "belly";
Then sMyString[0] does exist. And [1] too. And [2] and [3], [4] too! Because you assigned sMyString letters (a word in this case), std::string will create the spots where all the elements fit in.
And now you can replace the EXISTING elements indeed like:
Code:
string sMyString; //ONLY a name for humans: [0]...[etc] does NOT exist yet!
sMyString = "hello"; //NOW std::string makes sure [0]...[4] exist!
for(unsigned i=0; i < sMyString.size(); ++i)
{
   sMyString[i] = 'i';
}
cout<<sMyString<<endl;
//output: 01234
And that's why your approach won't work.

Quote:
one more thing. the error that i got before (parse error before ',' )
- You need to add: using namespace std;
- You need to change the call to verify like this: verify( reversed, word);
__________________
Valmont is offline   Reply With Quote
Old 10-23-2004, 07:48 PM   #15 (permalink)
gamehead200
Code Monkey
 
gamehead200's Avatar
 
Join Date: Oct 2004
Posts: 57
gamehead200 is an unknown quantity at this point
Valmont, I prefer your STL approach... Its easy, and best of all, I understand it... Its very short (which is a good thing) and easy to explain with a little research (which I have done)...

Thanks once again, Valmont!
gamehead200 is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -8. The time now is 09:42 AM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8





Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting