This code is supposed to convert a given postfix expression to a prefix expression,i was experimenting with the string object in c++ but I don't have enough experience to figure out the problem
I think there's an issue in the push() function
Note:I haven't used the stack header file and implemented the stack using array
here's the code
#include <bits/stdc++.h>
#include <iostream>
#define MAX 5
using namespace std;
class stack1
{
private:
int stackTop,expTop;
string stack[MAX],expression;
public:
stack1()
{
stackTop = -1;
for (int i = 0; i < MAX; i++)
{
stack[i] = " ";
}
getexp();
check(expression);
display();
}
string pop();
void push(string expr);
void display();
bool isempty();
bool isfull();
string combo(string optr1,string optr2,string opr);
void getexp();
void check(string expre);
bool isOperator(string ch);
};
//-----------Gets Expression From User------------------------------------------
void stack1::getexp()
{
cout<<"Enter the Postfix Expression"<<endl;
cin>>expression;
expTop=expression.length()-1;
}
void stack1::check(string expre)
{
string ch;
int i=0;
while(expre[i]!=(expre.length()-1))
{
ch=expre[i];
if(isOperator(ch))
{
push(combo(pop(),ch,pop()));
}
else
{
push(ch);
}
}
}
/*
-------------------------------------------------------------------
Inputs:
takes 2 values from the stack which will be operands
either as single characters or whole strings,these
values will be passed as optr1 and opttr2,it will
also take operators such as +,-,* etc.. as char.
these will be passed in place of opr.
working:
combines all the passed values into a single string
into the following format
( optr1 opr optr2 )
and finaly returns this string
----------------------------------------------------------------------
*/
string stack1::combo(string optr1, string optr2, string opr)
{
string expr;
expr="("+optr1+opr+optr2+")";
return expr;
}
/*
------------------------------------------------------------------------
Working:
pops the top value from the stack
and returns it.
decrements the top pointer
and initializes the poped element to " "
-------------------------------------------------------------------------
*/
string stack1 ::pop()
{
string x;
if (isempty())
{
cout << endl
<< "The stack1 is empty" << endl;
}
x=stack [stackTop];
stack [stackTop] = " ";
stackTop--;
return x;
}
void stack1 ::push(string expr)
{
stackTop++;
stack [stackTop] = expr;
}
bool stack1 ::isempty()
{
if (stackTop == -1)
return true;
else
return false;
}
bool stack1 ::isfull()
{
if (stackTop == MAX - 1)
return true;
else
return false;
}
bool stack1::isOperator(string ch)
{
if (ch[0] == '*' || ch[0] == '/' || ch[0] == '+' || ch[0] == '-' || ch[0] == '^')
return true;
else return false;
}
void stack1::display()
{
cout<<"Infix:\t"<<stack[0]<<endl;
}
int main()
{
stack1 obj;
return 0;
}
Besided the obvious hard bug with #include <bits/stdc++.h> which is not part of C++ (and does not even compile on my machine), you have 2 semantic bugs in your code, which lead to a problem.
Additionally you have a design problem leading to an only partially solution.
And, maybe a misunderstanding of the terms and meaning of "string" and "character"
Example: The string "hello" consists of 5 characters: 'h', 'e', 'l', 'l', 'o'
If you use a std::string and initialize it with "hello" (which is of type const char[6]), the the constructor of the std::string will convert your character array to a std::string, containing the following characters at indices:
index character
0 'h'
1 'e'
2 'l'
3 'l'
4 'o'
5 '\0'
In your "check" function in line while(expre[i]!=(expre.length()-1)) you access expre[i] which is a character (for example an 'a') and compare it to the length of the std::string "expre". This can of course not work.
The while loop will never terminate. "i" is always the same and you will push always the first character of the input string onto the stack, unti it is full and you get an exception. You should add an overflow-check in your push function.
Additionally, you use a wrong parameter sequence in/with your "combo" function.
If you modify the while loop like the below, then at least this part will work.
string ch;
int i = 0;
//while (expre[i] != (expre.length() - 1))
while (i != (expre.length()))
{
ch = expre[i];
if (isOperator(ch))
{
push(combo(pop(), pop(),ch));
}
else
{
push(ch);
}
++i;
}
Now you can successfully convert "abcd+^" to "(a^(b(c+d)))".
But still, it will not work fully.
Additionally:
You should use your constructor only to initialize your class.
Please use characters where appropriate and not full std::strings
The whole design needs to be reworked.
Because: basically you are creating an infix and not a prefix expression.
Hence, for learning purposes look at here
So the Problem was given a String Which is a Name like Sam Harris you have to output it's abbreviation what i did was find the space in the string and then taking a string otp which will add str[0] first letter of name str[pos+1] letter after position and also added a . in between but the return statement is returning some random value.Which is not expected.
#include
std::string abbrev(std::string str)
{
int pos{0};
for(int i=0;i<str.length();++i)
{
if(str[i]==' ')
{
pos=i;
break;
}
}
std::string otp=str[0]+"."+str[pos+1];
return otp;
}
int main()
{
std::string str="Sam Harris";
std::cout<<abbrev(str)<<"\n";
return 0;
}
The problem is that this here:
str[0]+"."+str[pos+1];
Isn't constructing a string. It's adding a char* to some chars, effectively performing some invalid pointer arithmetic. Fix it like this:
std::string otp = str[0] + std::string(".") + str[pos + 1];
Now std::string(".") correctly makes a std::string and appends those chars as intended using std::string's operator+.
str[0] and str[pos+1] returns a character at that position with type char. You cannot added a char variable to a constant string "." (double quoted). Overall I think it added up the constant string memory address with char values of each position and assign it to otp. For example, looking at your case, assume constant string "." have an address value 1000. The str[0] will return 'S' with ascii value 83 and str[pos+1] is expected to return 'H' with ascii value 72. Then opt will assigned with a memory address 1155 (83+1000+72), which will be an unknown program memory with junk value, which will be returned by the function. Use stringstream to concatnate string as following:
std::string abbrev(std::string str)
{
int pos{0};
for(int i=0;i<str.length();++i)
{
if(str[i]==' ')
{
pos=i;
break;
}
}
std::stringstream otp;
otp << str[0] << "." << str[pos+1];
return otp.str();
}
So you want the first letter, presumably capitalized, for each separate word in the string? Something like this should work.
std::string input = "Sam Harris";
std::string output = "";
auto n = input.find(" ");
while (n++ != input.npos)
{
output += std::to_upper(input[0]);
input = input.substr(n, input.size() - n);
n = input.find(" ");
}
Not a c++ guy, but I can give this a shot. I suspect, you're getting random stuff because you're overflowing the bounds of arrays for some inputs. Fixing that may fix your bug (example below, assuming your syntax is correct).
std::string abbrev(std::string str) {
for(int i=0;i<str.length()-1;++i) {
if(str[i]==' ') {
return str[0] + '.' + str[i +1];
}
return '';
}
Obviously you'll have to generalize for arbitrary number of spaces.
I have an assignment I am working on that uses recursion. I'm still having a little trouble understanding recursion, or at least how it all works, but I think I'm starting to grasp it, even though I'm not all that sure why anything works.
My assignment has two parts, but for the moment, I just need a little help with the first part. Here's what I have to do:
Write a recursive function that will return the position of the first occurence of a >character within a C String
This is what I have so far...
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;
int test(string s, char x);
int main ()
{
test("lets test for the letter s", "s" );
}
int test(string s, char x)
{
if(s.length() == 0)
return 0;
else if (s[0] == x)
return 1 + test(s.substr(1, s.length()), x);
else
return test(s.substr(1, s.length()), x);
}
So i think this should work, but I'm a little confused as to how to get the function to test anything. I'm pretty sure I have the string part done correctly in my function call in main, but I can't get the char to accept a value. The way I understand it, i should enter the text I want to scan, and then the character I want to look for. Can anyone tell me what I am doing wrong, or even I'm even close with the recursive function?
You should do something like the following:
int main ()
{
test("lets test for the letter s", 's');
//should pass char constant
//not string literal for second parameter
}
int test(string s, char x)
{
if(s.length() == 0)
return 0;
else if (s[0] == x)
return 1 + test(s.substr(1, s.length()-1), x);
//^^^second parameter of substring is length
else
return test(s.substr(1, s.length()), x);
}
Character constants go in single quotes. To test your function write something like:
cout << test("lets test for the letter s", 's') << endl;
As for your recursive function, you're close. The if statements have the right tests, you just need to adjust the return statements a bit.
if (s.length() == 0)
return -1;
If the string is empty the character isn't found. I suggest returning -1 rather than 0 because a return value of 0 suggests (to me) that the character was found at position 0. -1 is the traditional return code from functions like these when a character isn't found.
else if (s[0] == x)
return 0;
Do you see why this is return 0? You found the character x at index 0, so that's what you should return: 0!
else
return 1 + test(s.substr(1, s.length() - 1), x);
The last test is the only one that needs to be recursive. Here's where you put the 1 +. And you also need to reduce length() by 1.
"s" will be treated as a char array or a string. To represent a single char you should use 's'
int main ()
{
cout << "location = " << test("lets test for the letter s", 's' );
^^^^
}
I have a question regarding C++. This is my current function:
string clarifyWord(string str) {
//Remove all spaces before string
unsigned long i = 0;
int currentASCII = 0;
while (i < str.length()) {
currentASCII = int(str[i]);
if (currentASCII == 32) {
str.erase(i);
i++;
continue;
} else {
break;
}
}
//Remove all spaces after string
i = str.length();
while (i > -1) {
currentASCII = int(str[i]);
if (currentASCII == 32) {
str.erase(i);
i--;
continue;
} else {
break;
}
}
return str;
}
Just to get the basic and obvious things out of the way, I have #include <string> and using namespace std; so I do have access to the string functions.
The thing is though that the loop is quitting and sometimes skipping the second loop. I am passing in the str to be " Cheese " and it should remove all the spaces before the string and after the string.
In the main function, I am also assigning a variable to clarifyWord(str) where str is above. It doesn't seem to print that out either using cout << str;.
Is there something I am missing with printing out strings or looping with strings? Also ASCII code 32 is Space.
Okay so the erase function you are calling looks like this:
string& erase ( size_t pos = 0, size_t n = npos );
The n parameter is the number of items to delete. The npos means, delete everything up until the end of the string, so set the second parameter to 1.
str.erase(i,1)
[EDIT]
You could change the first loop to this:
while (str.length() > 0 && str[0] == ' ')
{
str.erase(0,1);
}
and the second loop to this:
while (str.length() > 0 && str[str.length() - 1] == ' ')
{
str.erase(str.length() - 1, 1);
}
In your second loop, you can't initialize i to str.length().
str[str.length()] is going to be after the end of your string, and so is unlikely to be a space (thus triggering the break out of the second loop).
You're using erase (modifying the string) while you're in a loop checking its size. This is a dangerous way of processing the string. As you return a new string, I would recommend you first to search for the first occurrence in the string of the non-space character, and then the last one, and then returning a substring. Something along the lines of (not tested):
size_t init = str.find_first_not_of(' ');
if (init == std::string::npos)
return "";
size_t fini = std.find_last_not_of(' ');
return str.substr(init, fini - init + 1);
You see, no loops, erases, etc.
unsigned long i ... while (i > -1) Well, that's not right, is it? How would you expect that to work? The compiler will in fact convert both operands to the same type: while (i > static_cast<unsigned long>(-1)). And that's just another way to write ULONG-MAX, i.e. while (i > ULONG_MAX). In other words, while(false).
You're using erase incorrectly. It'll erase from pos to npos.
i.e. string& erase ( size_t pos = 0, size_t n = npos );
See: http://www.cplusplus.com/reference/string/string/erase/
A better way to do this is to note the position of the first non space and where the spaces occur at the end of the string. Then use either substr or erase twice.
You also don't need to go to the trouble of doing this:
currentASCII = int(str[i]);
if (currentASCII == 32) {
Instead do this:
if (str[i] == ' ') {
Which I think you'll agree is a lot easier to read.
So, you can shorten it somewhat with something like: (not tested but it shouldn't be far
off)
string clarifyWord(string str) {
int start = 0, end = str.length();
while (str[start++] == ' ');
while (str[end--] == ' ');
return str.substr(start, end);
}
I've been reading the book C++ For Everyone and one of the exercises said to write a function string reverse(string str) where the return value is the reverse of str.
Can somebody write some basic code and explain it to me? I've been staring at this question since yesterday and can't figure it out. The furthest I've gotten is having the function return the first letter of str (Which I still don't know how it happened)
This is as far as I got (An hour after posting this question):
string reverse(string str)
{
string word = "";
if (str.length() <= 1)
{
return str;
}
else
{
string str_copy = str;
int n = str_copy.length() - 1;
string last_letter = str_copy.substr(n, 1);
str_copy = str_copy.substr(0, n);
word += reverse(str_copy);
return str_copy;
}
return word;
}
If I enter "Wolf", it returns Wol. Somebody help me out here
If I return word instead of return str_copy then I get a w
If I return last_letter then I get an l
I'll instead explain the recursive algorithm itself. Take the example "input" which should produce "tupni". You can reverse the string recursively by
If the string is empty or a single character, return it unchanged.
Otherwise,
Remove the first character.
Reverse the remaining string.
Add the first character above to the reversed string.
Return the new string.
Try this one
string reverse(string &s)
{
if( s.length() == 0 ) // end condtion to stop recursion
return "";
string last(1,s[s.length()-1]); // create string with last character
string reversed = reverse(s.substr(0,s.length()-1));
return last+reversed; // Make he last character first
}
A recursive function must have the following properties
It must call itself again
It must have a condition when the recursion ends. Otherwise you have a function which
will cause a stack overflow.
This recursive function does basically create a string of the last character and then call itself again with the rest of the string excluding the last character. The real switching happens at the last line where last+reversed is returned. If it would be the other way around nothing would happen.
It is very inefficient but it works to show the concept.
Just to suggest a better way of handling recursion:
String reversal using recursion in C++:
#include <iostream>
#include <string>
using namespace std;
string reverseStringRecursively(string str){
if (str.length() == 1) {
return str;
}else{
return reverseStringRecursively(str.substr(1,str.length())) + str.at(0);
}
}
int main()
{
string str;
cout<<"Enter the string to reverse : ";
cin>>str;
cout<<"The reversed string is : "<<reverseStringRecursively(str);
return 0;
}
I won't write a full-blown algorithm for you, but here's a hint:
How about swapping the two outermost characters, and then apply the same to the characters in the middle?
Oh, and if that book really proposed string reverse(string str) as an appropriate function signature for this, throw it away and buy a good book instead.
Here is my version of a recursive function that reverses the input string:
void reverse(char *s, size_t len)
{
if ( len <= 1 || !s )
{
return;
}
std::swap(s[0], s[len-1]);// swap first and last simbols
s++; // move pointer to the following char
reverse(s, len-2); // shorten len of string
}
Shortest and easiest
class Solution {
public:
string reverseString(string s) {
string str;
if(s != "\0"){
str = reverseString(s.substr(1, s.length()));
str += s.substr(0,1);
}
return str;
}
};
1-line recursive solution:
string RecursiveReverse(string str, string prev = "") {
return (str.length() == 0 ? prev : RecursiveReverse(str.substr(0, str.length()-1), prev += str[str.length()-1]));
}
You call it like this:
cout << RecursiveReverse("String to Reverse");
I know I shouldn't give a solution, but since no one mentioned this easy solution I though I should share it. I think the code literally is the algorithm so there is no need for a pseudo-code.
void c_plusplus_recursive_swap_reverse(std::string::iterator start,
std::string::iterator end)
{
if(start >= end) {
return;
}
std::iter_swap(start, end);
c_plusplus_recursive_swap_reverse(++start, --end);
}
To call it use:
c_plusplus_recursive_swap_reverse(temp.begin(), temp.end());
All existing solutions had way too much code that didn't really do anything, so, here's my take at it:
#include <iostream>
#include <string>
std::string
r(std::string s)
{
if (s.empty())
return s;
return r(s.substr(1)) + s[0];
}
int
main()
{
std::cout << r("testing") << std::endl;
}
P.S. I stumbled upon this question trying to find a C++ way for std::string of what s+1 for a char * in C is; without going the whole route of s.substr(1, s.length()-1), which looks too ugly. Turns out, there's std::string::npos, which means until the end of the string, and it's already the default value for the second argument, so, s.substr(1) is enough (plus, it also looks more efficient and on par with the simple s + 1 in C).
Note, however, that recursion in general doesn't scale as the input grows larger, unless the compiler is able to do what is known as tail-recursion optimisation. (Recursion is rarely relied upon in imperative languages.)
However, in order for the tail recursion optimisation to get activated, it is generally required that, (0), the recursion only happens within the return statement, and that, (1), no further operations are performed with the result of the recursive call back in the parent function.
E.g., in the case above, the + s[0] is logically done by the parent after the child call completes (and it probably would be so even if you go the more uglier s[s.length()-1] + route), so, it might as well prevent most compilers from doing a tail-recursion-optimisation, thus making the function very inefficient on large inputs (if not outright broken due to heap exhaustion).
(For what it's worth, I've tried writing a more tail-recursion-friendly solution (making sure to grow the return result through an argument to the function itself), but disassembly of the resulting binary seems to suggest that it's more involved than that in the imperative languages like C++, see gcc: is there no tail recursion if I return std::string in C++?.)
you can implement your own reverse similar to std::reverse.
template <typename BidirIt>
void reverse(BidirIt first, BidirIt last)
{
if((first == last) || (first == --last))
return;
std::iter_swap(first, last);
reverse(++first, last);
}
I did something like this, it did the reversal in place. I took two variables that traverse the string from two extreme end to the centre of the string and when they overlap or equal to each other then reversal terminates.
Take an example: input string str = "abcd" and call the function as
ReverseString(str,0,str.length()-1);
and increment/decrement the variable pointers recursively.
First the pointers points to 'a' and 'd' and swap them, then they point to 'b' and 'c' and swap them. Eventually i >= j which calls for the base case to be true and hence the recursion terminates. The main take away for this question is to pass input string as reference.
string ReverseString(string& str,int i,int j){
if(str.length() < 1 || str == "" || i >= j){
return "";
}
else{
char temp = str[i];
str[i] = str[j];
str[j] = temp;
ReverseString(str,i+1,j-1);
}
return str;
}
String can be reversed in-place. If we start from smallest possible string i.e. one character string, we don't need to do anything. This is where we stop or return from our recursive call and it becomes our base case.
Next, we have to think of a generic way to swap the smallest string i.e. two characters or more. Simplest logic is to swap the current character str[current_index] with character on the opposite side str[str_length-1 - current_index].
In the end, call the reverse function again for next index.
#include <iostream>
using namespace std;
void reverse_string(std::string& str, int index, int length) {
// Base case: if its a single element, no need to swap
// stop swapping as soon as we reach the mid, hence index*2
// otherwise we will reverse the already reversed string
if( (length - index*2) <= 1 ) {
return;
}
// Reverse logic and recursion:
// swap current and opposite index
std::swap(str[index], str[length-1 - index]);
// do the same for next character (index+1)
reverse_string(str, index+1, length);
}
int main() {
std::string s = "World";
reverse_string(s, 0, s.length());
std::cout << s << endl;
}
There are already some good answer but I want to add my approach with full working Recursive reversing string.
#include <iostream>
#include <string>
using namespace std;
char * reverse_s(char *, char*, int,int);
int main(int argc, char** argv) {
if(argc != 2) {
cout << "\n ERROR! Input String";
cout << "\n\t " << argv[0] << "STRING" << endl;
return 1;
}
char* str = new char[strlen(argv[1])+1];
strcpy(str,argv[1]);
char* rev_str = new char[strlen(str)+1];
cout<<"\n\nFinal Reverse of '" << str << "' is --> "<< reverse_s(str, rev_str, 0, strlen(str)) << endl;
cin.ignore();
delete rev_str, str;
return 0;
}
char* reverse_s(char* str, char* rev_str, int str_index, int rev_index ) {
if(strlen(str) == 1)
return str;
if(str[str_index] == '\0' ) {
rev_str[str_index] = '\0';
return rev_str;
}
str_index += 1;
rev_index -=1;
rev_str = reverse_s(str, rev_str, str_index, rev_index);
if(rev_index >= 0) {
cout << "\n Now the str value is " << str[str_index-1] << " -- Index " << str_in
dex << " Rev Index: " << rev_index;
rev_str[rev_index] = str[str_index-1];
cout << "\nReversed Value: " << rev_str << endl;
}
return rev_str;
}
void reverse(string &s, int &m) {
if (m == s.size()-1)
return;
int going_to = s.size() - 1 - m;
string leader = s.substr(1,going_to);
string rest = s.substr(going_to+1,s.size());
s = leader + s.substr(0,1) + rest;
reverse(s,++m);
}
int main ()
{
string y = "oprah";
int sz = 0;
reverse(y,sz);
cout << y << endl;
return 0;
}
void ClassName::strgRevese(char *str)
{
if (*str=='\0')
return;
else
strgRevese(str+1);
cout <<*str;
}
here is my 3 line string revers
std::string stringRevers(std::string s)
{
if(s.length()<=1)return s;
string word=s.at(s.length()-1)+stringRevers(s.substr(0,s.length()-1));//copy the last one at the beginning and do the same with the rest
return word;
}
The question is to write a recursive function. Here is one approach. Not a neat code, but does what is required.
/* string reversal through recursion */
#include <stdio.h>
#include <string.h>
#define size 1000
char rev(char []);
char new_line[size];
int j = 0;
int i =0;
int main ()
{
char string[]="Game On";
rev(string);
printf("Reversed rev string is %s\n",new_line);
return 0;
}
char rev(char line[])
{
while(line[i]!='\0')
{
i++;
rev(line);
i--;
new_line[j] = line[i];
j++;
return line[i];
}
return line[i];
}
It will reverse Original string recursively
void swap(string &str1, string &str2)
{
string temp = str1;
str1 = str2;
str2 = str1;
}
void ReverseOriginalString(string &str, int p, int sizeOfStr)
{
static int i = 0;
if (p == sizeOfStr)
return;
ReverseOriginalString(str, s + 1, sizeOfStr);
if (i <= p)
swap(&str[i++], &str[p])
}
int main()
{
string st = "Rizwan Haider";
ReverseOriginalString(st, 0, st.length());
std::cout << "Original String is Reversed: " << st << std::endl;
return 0;
}