Vector push_back & pop_back - c++

I'm working on an assignment. I have coded the assignment and everything is working as it should, except my output is missing a digit. I also attached the sample output. After inputting a a mathematical expression into a string, for example 35 * 4 - 6 / (9 + 3), a digit is dropped. In normal order, the 3 will be missing. In reverse order, the 9 will be missing. I am not understanding why this happening.
Any help, or I would prefer some guidance, would be appreciated. Am I using the push_back incorrectly? The code is as follows:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<string> split(string);
vector<string> splitback(string);
int main()
{
vector<string> vectorExpression;
string expression;
cout << "Enter an expression :";
getline(cin, expression);
vectorExpression = split(expression);
for (int i = 0; i < vectorExpression.size(); i++)
{
cout << vectorExpression[i] << endl;
}
cout << endl;
vectorExpression = splitback(expression);
for (int i = 0; i < vectorExpression.size(); i++)
{
cout << vectorExpression[i] << endl;
}
system("pause");
return 0;
}
vector<string> split(string expression)
{
vector<string> splitExpression;
string digit = "",
x = "";
for (int i = 0; i < expression.size(); i++)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
digit = digit + expression[i];
}
else if (expression[i] != ' ')
{
x = "";
x = x + expression[i];
splitExpression.push_back(x);
}
else
{
if (digit.size() > 0)
{
splitExpression.push_back(digit);
digit = "";
}
}
}
if (digit.size() > 0)
{
splitExpression.push_back(digit);
}
return splitExpression;
}
vector<string> splitback(string expression)
{
vector<string> splitBackExpression;
string number = "",
x = "";
for (int i = expression.size() - 1; i >= 0; i--)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
number = expression[i] + number;
}
else if (expression[i] != ' ')
{
x = "";
x = x + expression[i];
splitBackExpression.push_back(x);
}
if (number.size() > 0)
{
splitBackExpression.push_back(number);
number = "";
}
}
return splitBackExpression;
}

Your split function is wrong, you forget to add digits, correct one would be
vector<string> split(string expression)
{
vector<string> splitExpression;
string digit = "",
x = "";
for (int i = 0; i < expression.size(); i++)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
digit = digit + expression[i];
}
else
{
// don't forget digit if there was one
if (digit.size() > 0)
{
splitExpression.push_back(digit);
digit = "";
}
// also add what comes next if not a whitespace
if (expression[i] != ' ')
{
x = expression[i];
splitExpression.push_back(x);
}
}
}
if (digit.size() > 0)
{
splitExpression.push_back(digit);
}
return splitExpression;
}

Here is the final answer to my own question, or at least the solution I came up with the help from here.
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<string> split(const string&);
vector<string> splitback(const string&);
int main()
{
vector<string> forwardExpression,
reverseExpression;
string expression;
cout << "Enter an expression :";
getline(cin, expression);
//////////////////////////////////////////////////
// FORWARD DISPLAY OF EXPRESSION //
//////////////////////////////////////////////////
forwardExpression = split(expression);
cout << "'" << expression << "'" << " split into individual entities forwards
yields:" << endl;
cout << endl;
for (int i = 0; i < forwardExpression.size(); i++)
{
cout << forwardExpression[i] << endl;
}
cout << endl;
//////////////////////////////////////////////////
// BACKWARD DISPLAY OF EXPRESSION //
//////////////////////////////////////////////////
reverseExpression = splitback(expression);
cout << "'" << expression << "'" << " split into individual entities
backwards yields:" << endl;
cout << endl;
for (int i = 0; i < reverseExpression.size(); i++)
{
cout << reverseExpression[i] << endl;
}
cout << endl;
system("pause");
return 0;
}
//////////////////////////////////////////////////
// FORWARD FUNCTION OF EXPRESSION //
//////////////////////////////////////////////////
vector<string> split(const string &expression)
{
vector<string> splitExpression;
string digit = "",
x = "";
for (int i = 0; i < expression.size(); i++)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
digit = digit + expression[i];
}
else
{
if (digit.size() > 0)
{
splitExpression.push_back(digit);
digit = "";
}
if (expression[i] != ' ')
{
x = expression[i];
splitExpression.push_back(x);
}
}
}
if (digit.size() > 0)
{
splitExpression.push_back(digit);
}
return splitExpression;
}
//////////////////////////////////////////////////
// BACKWARD FUNCTION OF EXPRESSION //
//////////////////////////////////////////////////
vector<string> splitback(const string &expression)
{
vector<string> splitBackExpression;
string digit = "",
x = "";
for (int i = expression.size() - 1; i >= 0; i--)
{
if (expression[i] >= '0' && expression[i] <= '9')
{
digit = expression[i] + digit;
}
else
{
if (digit.size() > 0)
{
splitBackExpression.push_back(digit);
digit = "";
}
if (expression[i] != ' ')
{
x = expression[i];
splitBackExpression.push_back(x);
}
}
}
if (digit.size() > 0)
{
splitBackExpression.push_back(digit);
}
return splitBackExpression;
}

Related

a+= b faster than a = a+b. The logic behind the two operations

I was working on a leetcode problem to reverse a string such that such that if Input is The boy is mad, the output should be mad is boy The. I solved it but the solution seemed poor as I was running through the string a lot of times. On submitting the code, the time taken to compute all the test cases was ~250ms, and I believed it as I knew this was the worst possible code. I looked up one of the answers and ran that code, it ran in like 4ms. I wrote the same code again, but this time I used a = a + b; instead of a += b;, and the test cases again took around 250ms. So, I want to know what is the difference between these two and why does it take a long time on one when compared to the other.
PS - In my original (poor) code, on changing a = a + b to a += b, the code ran in like 8ms.
Here are the codes:
1. slow code(runtime - ~250 ms)
string reverseWords(string s) {
if(s.length() == 0)
{
return s;
}
int itr = 0;
// Remove white spaces from front
while(s[itr] == ' ')
{
itr++;
}
s = s.substr(itr,s.length()-itr);
if(s.length() == 0)
{
return s;
}
// Remover white spaces from back
for(int i = s.length()-1; i>= 0 ;i--)
{
while(s[i] == ' ')
{
s = s.substr(0,i);
i--;
//cout << s << endl;
}
break;
}
if(s.length() == 0)
{
return s;
}
cout << s << endl;
// Remove more than one space in the middle
for(int i = 0;i<s.length()-1;i++)
{
if(s[i] == ' ' && s[i+1] == ' ')
{
string temp;
temp = s.substr(0,i);
s = s.substr(i+1,s.length());
s = temp + s;
i--;
//cout << s <<endl;
}
}
string res = "";
reverse(s.begin(),s.end());
int start = 0;
for(int i = 0;i <s.length();i++)
{
start = i;
if(s[i] == ' ')
continue;
while(s[i] != ' ' && i < s.length())
{
i++;
// cout << i << " ";
}
// cout << endl;
string temp = s.substr(start,i-start);
reverse(temp.begin(),temp.end());
if(i != s.length())
res = res + temp + " ";
else
res = res + temp;
//cout << temp << endl;
}
return res;
}
Fast code(4ms)
string reverseWords(string s)
{
stack<string> elements;
std::istringstream stream(s);
std::string word;
while (stream >> word)
{
elements.push(word);
}
string strReturn("");
int stackSize = elements.size();
int i = 0;
while( !elements.empty())
{
i++;
strReturn += elements.top();
elements.pop();
if( i != stackSize)
{
strReturn += " ";
}
}
return strReturn;
}
Re written Fast code(250ms)
string reverseWords(string s) {
// Check the first available Accepted solution to see the shitiest solution for the code
stack<string> availableWords;
istringstream stream(s);
string word;
while(stream >> word)
{
availableWords.push(word);
}
int len = availableWords.size();
string res = "";
int i = 0;
while(!availableWords.empty())
{
res += availableWords.top();
availableWords.pop();
i++;
if(i != len)
{
res += " ";
}
}
return res;
}

My Code for Erasing Empty Spaces in a Sentence in C++ has an Issue

I have made this code such that whatever I type in a sentence has the first letter of the first word capitalized; While reducing any number of spaces in a sentence to just one space. However, my sentences are only reducing by one space. For example, if I put 3 spaces in a sentence, the output has spaces reduced by 1 to 2 spaces, but I want the output of words in a sentence to have only one space. I can't quite figure out what is wrong with my code and hence any help would be greatly appreciated. I have attached my code for reference below:
#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
int i = 0; //i for counter
string str;
//String variable
getline(cin, str); //Get string from user
int L = str.length(); //Find length of string
//Display original string
for (int i = 0; i < 100; i++)
{
str[i] = tolower(str[i]);
}
str[0] = toupper(str[0]);
bool space;
for (int j = i + 1; j < L; j++)
{
str[j] = str[j + 1];
L--;
}
cout << str << endl;
return 0;
}
Or doing it in a more modern way using iterators :
#include <iostream>
#include <cctype>
int main() {
std::cout << "This is the string trimming function.\n" <<
"Throw in a string and I will make sure all extra spaces " <<
"will be reduced to single space.\n";
std::string InputString, TrimmedString;
int head = -1;
int tail = -1;
std::cout << "Please enter the input string :\n" << std::endl;
std::getline(std::cin, InputString);
for(std::string::iterator it = InputString.begin(); it <= InputString.end(); it++){
if (*it != ' ' && head < 0 && tail < 0) {
head = std::distance(InputString.begin(), it);
}
else if (head >= 0 && tail < 0 && (*it == ' ' || it == InputString.end())) {
tail = std::distance(InputString.begin(), it);
TrimmedString.append(InputString, head, (tail-head));
TrimmedString.push_back(' ');
head = -1;
tail = -1;
}
}
TrimmedString[0] = toupper(TrimmedString[0]);
std::cout << "\nThe processed string is :\n\n" << TrimmedString << std::endl;
return 0;
}
Try this:
int main()
{
std::string str;
std::getline(cin, str);
//Change case
str[0] = toupper(str[0]);
std::transform(str.begin() + 1, str.end(), str.begin() + 1, ptr_fun<int, int>(tolower));
//Parsing time
for (int i = 0; i <= str.size() - 1; i++)
{
if (str[i] == ' ' && str[i + 1] == ' ') //if present & next are whitespaces, remove next
{
str.erase(str.begin() + i);
i--; // rechecking condition
}
}
std::cout << '\n' << str << '\n';
}
Output:

Parenthesized Expression (Infix and Post fix) Conversion and Evaluation

I have the below code working fine but outputs only 2nd input, not 1st or 3rd.
My code should get fully parenthesized expression from console and convert it to postfix expression and then that postfix expression should be evaluated in modulo 10.Therefore, all results (including intermediate results) are single decimal digits in {0, 1, …, 9}. I need to store only single digits in the stack.
My inputs and outputs are shown in below.I only got 2nd input correctly.
Please advise.
Expression 1: (((2+(5^2))+7)
Answer:
252^+7+
4 in modulo 10
Expression 2: ((((2+5)*7)+((9*3)*2))^2)
Answer:
25+7*93*2*+2^
9 in modulo 10
Expression 3: ((((2*3)*(4*6))*7)+(((7+8)+9)*((2+4)*((7+8)+9))))
Answer:
23*46*7*789++24+78+9+**+
4 in modulo 10
My code:
#include <iostream>
#include <string>
#include<sstream>
using namespace std;
class STACK {
private:
char *s;
int N;
public:
STACK(int maxN) {
s = new char[maxN];
N = 0;
}
int empty() const {
return N == 0;
}
void push(char item) {
s[N++] = item;
}
char pop() {
return s[--N];
}
};
int main() {
string infixExpr;
string postfixExpr = "";
cout << "Enter infix expression:" << endl;
cin >> infixExpr; //converting to postfix read from the input
int N = infixExpr.size(); //strncpy(a, infixExpr.c_str(), N);
STACK ops(N);
char ch;
for (int i = 0; i < N; i++) {
if (infixExpr[i] == ')')
{
ch = ops.pop();
postfixExpr.push_back(ch);
}
if ((infixExpr[i] == '+') || (infixExpr[i] == '*') || (infixExpr[i] == '^'))
ops.push(infixExpr[i]);
if ((infixExpr[i] >= '0') && (infixExpr[i] <= '9'))
{
//cout << infixExpr[i] << " ";
postfixExpr.push_back(infixExpr[i]);
}
}
cout <<"Answer :"<<endl;
cout <<postfixExpr <<endl; //evaluate post fix expression
N = postfixExpr.size();
STACK save(N);
int result;
int num;
int count = 0;
string temp = "";
for (int i = 0; i < N; i++) {
// cout << " Expr[i] " << postfixExpr[i] << endl;
if (postfixExpr[i] == '+')
save.push((save.pop() + save.pop()) % 10);
if (postfixExpr[i] == '*')
save.push((save.pop() * save.pop()) % 10);
if (postfixExpr[i] == '^') {
count = save.pop() - '0';
num = save.pop() - '0'; //cout << result << "- " <<"-" <<count<<endl;
result = 1;
for(int j = 1; j <= count; j++)
{
result = result * num;
result = result % 10;
}
stringstream convert;
convert << result;//add the value of Number to the characters in the stream
temp = convert.str();//set Result to the content of the stream
save.push(temp[0]);
}
if ((postfixExpr[i] >= '0') && (postfixExpr[i] <= '9'))
{
save.push(postfixExpr[i]);
}
}
cout << save.pop() <<" in module 10"<< endl;
return 1;
}

Find character in a string

I cant get the char search to work. The substring function is working but the char search won't provide the right location of the char it is looking for
#include<iostream>
#include <string>
using namespace std;
int charsearch(string searchInto, char ch, int start = 0)
{
int x = 0;
long n = searchInto.length();
for (int i = 1; i < n; i++)
{
cout << ch;
if (searchInto[i] == ch)
{
i = x;
}
else
i++;
}
cout<< x;
return x;
}
int substr(string src, string tosearch, int start = 0)
{
string searchInto = src;
long n = searchInto.size();
long m = tosearch.size();
int ans = -1;
for (int i = start; i < n; ++i)
{
int p = i;
int q = 0;
bool escape = false;
while (p < n && q < m) {
if (searchInto[p] == tosearch[q]) {
if (tosearch[q] == '/' && !escape) {
++q;
} else {
++p; ++q;
}
escape = false;
} else if (!escape && tosearch[q] == '*') {
++q;
while (q < m && p < n && searchInto[p] != tosearch[q]) ++p;
escape = false;
} else if (!escape && tosearch[q] == '?') {
++p; ++q;
escape = false;
} else if (tosearch[q] == '/' && !escape) {
escape = true;
++q;
} else break;
}
if (q == m) {
return i;
}
if (q == m - 1 && tosearch[q] == '*') {
if (q > 0 && tosearch[q - 1] == '/') continue;
else return i;
}
}
return ans;
}
int main()
{
string searchInto, tosearch;
cout<< "Enter string:";
getline(cin, searchInto);
cout << "Looking for :";
getline(cin, tosearch);
if (tosearch.length() < 2)
{
char ch = tosearch.at(0);
cout << "Found at: " <<charsearch(searchInto, ch) << endl;
cout << "Used Char" << endl;
}
else
cout << "Found at: " <<substr(searchInto, tosearch) << endl;
return 0;
}
To find a character in a string, you have two interfaces.
std::string::find will return the position of a character you find:
auto pos = yourStr.find('h');
char myChar = yourStr[pos];
If the character does not exist, then std::string::npos will be returned as the std::size_t returned for position.
stl algorithm std::find, in header algorithm returns an iterator:
auto it = std::find(yourStr.begin(), yourStr.end(), 'h');
char myChar = *it;
If the character does not exist, then it == yourStr.end().
There are some silly mistakes in your CharSearch method. First of all, You have to break the loop when you got your target character. And most importantly you are not assigning x when you are finding the target. Furthermore, there is extra increment of value i inside the loop. I have modified the function. Please check it below
int charsearch(string searchInto, char ch, int start = 0) {
int x = -1;
long n = searchInto.length();
for (int i = start; i < n; i++)
{
cout << ch;
if (searchInto[i] == ch)
{
x = i; // previously written as i = x which is wrong
break; // loop should break when you find the target
}
}
cout<< x;
return x;
}
Please note that,you can either also use find method of string or std::find of algorithm to search in string.
You need to make changes as per this code
int charsearch(string searchInto, char ch, int start = 0)
{
int x = -1; // : change, if return -1, means not found
long n = searchInto.length();
for (int i = start; i < n; i++) // : change
{
cout << ch;
if (searchInto[i] == ch)
{
x = i; // : change
break; // : change
}
}
cout<< x;
return x;
}
Note : This function will return 1st match.

C++: Implementing merge sort from scratch

I was trying to test my self and wanted to write mergesort, without actually looking up any code online, and to do it in a certain time period. I am stuck at this point where I cannot simply understand what I am doing wrong, since merge sort, as much as i remember, is to divide the strings up to the point where string is only 1 character and later on merge them back together. The code I've written below tries to do the exact thing. I was wondering whether I got the concept wrong, or just my implementation?
string merge(string str1, string str2) {
string final = "";
int i = 0, j = 0;
bool fromStr1 = false;
while(true) {
if(str1[i] < str2[j]) {
final += str1[i];
i++;
if(i == str1.size()) {
break;
}
}
else {
final += str2[j];
j++;
if(j == str2.size()) {
break;
fromStr1 = true;
}
}
}
if(fromStr1) {
for(int t = i; t < str1.size(); t++) {
final += str1[t];
}
}
else {
for(int t = j; t < str2.size(); t++) {
final += str2[t];
}
}
return final;
}
string mergeSort(string str1, int start, int end) {
if(end - start == 1)
return str1;
else {
int pivot = (end - start) / 2;
string newStr1 = mergeSort(str1, start, pivot);
string newStr2 = mergeSort(str1, pivot + 1, end);
return merge(newStr1, newStr2);
}
}
Note the changes:
#include <iostream>
#include <string>
using namespace std;
string merge(string str1, string str2) {
string final = "";
int i = 0, j = 0;
bool fromStr1 = false;
while (true) {
if (i >= (int)str1.size()) {
break;
}
if (j >= (int)str2.size()) {
fromStr1 = true; // changed the order of this with break!
break;
}
if (str1[i] < str2[j]) {
final += str1[i];
i++;
}
else {
final += str2[j];
j++;
}
}
if (fromStr1) {
for (int t = i; t < (int)str1.size(); t++) {
final += str1[t];
}
}
else {
for(int t = j; t < (int)str2.size(); t++) {
final += str2[t];
}
}
return final;
}
string mergeSort(string str1) {
int len = str1.size();
if (len <= 1)
return str1;
else {
string newStr1 = mergeSort(str1.substr(0, len / 2));
string newStr2 = mergeSort(str1.substr(len / 2, len - len / 2));
return merge(newStr1, newStr2);
}
}
int main()
{
cout << '"' << mergeSort("") << '"' << endl;
cout << '"' << mergeSort("a") << '"' << endl;
cout << '"' << mergeSort("ba") << '"' << endl;
cout << '"' << mergeSort("132") << '"' << endl;
cout << '"' << mergeSort("4321") << '"' << endl;
cout << '"' << mergeSort("54321") << '"' << endl;
return 0;
}
Output (ideone):
""
"a"
"ab"
"123"
"1234"
"12345"
This doesn't look right:
int pivot = (end - start) / 2;
string newStr1 = mergeSort(str1, start, pivot);
string newStr2 = mergeSort(str1, pivot + 1, end);
Don't you mean pivot=(end+start)/2? Or else mergeSort(str1, start, start+pivot) and mergeSort(str1, start+pivot+1, end)?
EDIT:
And your merge doesn't cope well with empty strings. You should have tested this function before hooking it up to mergeSort.
It's been ages since I used C++, but doesn't break immediately exit the loop? Because fromStr1 = true; is never reached in that case.