I have an assignment that asks me to "Write a recursive function vowels(s,low,high) that returns the number of vowels in an input string s[]." We are also limited by "Do not use the C++ string type. Read the characters into an array one at a time using cin.get()." I think I solved the task at hand, but it doesnt compile so I am unsure. If anyone could assist me and show how to fix my error and any errors I've made towards my solution that would be great.
Here is my error message.
***main.cpp:24:37: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
vowelCount = vowels(s, low, high);**
Here is my code:
#include <iostream>
#include <cstring>
using namespace std;
int vowels(char, int, int);
int main()
{
char s[500];
int high,
vowelCount,
low = 0;
cout << "Enter a string of characters: ";
cin.get(s, 500);
high = strlen(s);
vowelCount = vowels(s, low, high);
cout << "The string contains " << vowelCount << " vowels." << endl;
return 0;
}
int vowels(char s[], int low, int high)
{
if (s[low] == 'a' || 'A' || 'e' || 'E' || 'i' || 'I' || 'o' || 'O' || 'u' || 'U') {
return 1 + vowels(s, low + 1, high - 1);
} else {
return vowels(s, low + 1, high - 1);
}
}
We are talking about a so called XY-Problem here.
The teacher wants to cover recursive functions. The vowel counting is just some noise. Unfortunately the given example is a bad one, because it could be implemented by far better with an iterative approach.
The recursion is just adding unnecessary time and space complexity. So, the performance is worse compared to a simple loop in all cases.
If the teacher wants that you learn about recursion, you may want to first look at this description or that more practical example.
After having read this, you will understand that a loop can be simply converted into a recursive function.
I am not sure, why there is a "low" and a "high" parameter. Maybe because of the usage of C-strings stored in a char array (what is nonsense in C++). I doubt that 2 self calls should be established and the function should walk from the begin and the end of the string to the middle. That would even further reduce the performance. So, let us assume the standard case.
Next to your problem with the comparison. What you have written is wrong. The correct comparison in C++ would be:
if ((s[low] == 'a') || (s[low] == 'A') || (s[low] == 'e') ||
(s[low] == 'E') || (s[low] == 'i') || (s[low] == 'I') ||
(s[low] == 'o') || (s[low] == 'O') || (s[low] == 'u') ||
(s[low] == 'U'))
Of course, nobody would write such a long statement, because you can simply calculate, without any comparison, if an ASCII character is a vowel. You could simply write:
if (std::isalpha(s[low]) && ((0x208222 >> (s[low] & 0x1f)) & 1))
and thats it. If you are interested, I can explain the theory later, but not needed for this example.
Then, next, your recursive function is dangerously wrong, because it does not have an end condition. it will run forever or until the stack overflows.
So, you need to rework that, It could be done like this:
#include <iostream>
#include <cstring>
using namespace std;
int vowels(char[], int, int);
int main()
{
char s[500];
int high,
vowelCount,
low = 0;
cout << "Enter a string of characters: ";
cin.get(s, 500);
high = strlen(s);
vowelCount = vowels(s, low, high);
cout << "The string contains " << vowelCount << " vowels." << endl;
return 0;
}
int vowels(char s[], int low, int high)
{
int sum = 0;
if (low != high) {
if ((s[low] == 'a') || (s[low] == 'A') || (s[low] == 'e') ||
(s[low] == 'E') || (s[low] == 'i') || (s[low] == 'I') ||
(s[low] == 'o') || (s[low] == 'O') || (s[low] == 'u') ||
(s[low] == 'U'))
{
++sum;
}
sum += vowels(s,low+1,high);
}
return sum;
}
If we go a little bit more into the direction of C++ and use meaningful variable names and comments, then we could come up with that:
#include <iostream>
#include <cstring>
// A recursive function to count the vowels in a rang of a text
int countVowelsRecursive(char textToEvaluate[], unsigned int startPositionForEvaluation, unsigned int endPositionOfText)
{
// Here we will store the number of vowels. We will use tail recursion
// So, the overall calculation will be done at the end
unsigned int numberOfVowelsInThisRecursion = 0u;
// Now we are evaluating this character from the text
const char currentChar = textToEvaluate[startPositionForEvaluation];
// Check, for the end of recursion condition
if (startPositionForEvaluation != endPositionOfText) {
// Check, if it is a vowel
if ((currentChar == 'a') || (currentChar == 'A') || (currentChar == 'e') ||
(currentChar == 'E') || (currentChar == 'i') || (currentChar == 'I') ||
(currentChar == 'o') || (currentChar == 'O') || (currentChar == 'u') ||
(currentChar == 'U'))
{
// Vowel found. Increase counter by one
++numberOfVowelsInThisRecursion;
}
// Tail recursion. Self call, starting at next position of the string
numberOfVowelsInThisRecursion +=
countVowelsRecursive(textToEvaluate,startPositionForEvaluation + 1, endPositionOfText);
}
// This will be the final result
return numberOfVowelsInThisRecursion;
}
// We will allow a maximal input text length like this
constexpr unsigned int MaxTextLength = 500u;
// Driver code / test function
int main()
{
// Here we will store the text from the user
char text[MaxTextLength]{};
// Give instructions and get the text
std::cout << "Enter a string of characters: ";
std::cin.get(text, MaxTextLength);
// Set text parameters for the evaluation
unsigned int startOfText = 0u;
unsigned int endOfText = static_cast<unsigned int>(strlen(text));
// Calculate the vowels
unsigned int vowelCount = countVowelsRecursive(text, startOfText, endOfText);
// Show result to user
std::cout << "The string contains " << vowelCount << " vowels." << std::endl;
return 0;
}
And if we would be allowed to use C++ then we would write:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
// Give instructions and get the text
std::cout << "\nEnter a text:\n";
if (std::string text{}; std::getline(std::cin, text))
// Show result to user
std::cout << "\n\nThe string contains "
<< std::count_if(text.begin(), text.end(), [](const char c){ return std::isalpha(c) && ((0x208222 >> (c & 0x1f)) & 1);})
<< " vowels.\n";
return 0;
}
Have fun . . .
Write a C++ program to perform addition of two hexadecimal numerals which are less than 100 digits long. Use arrays to store hexadecimal numerals as arrays of characters.the solution is to add the corresponding digits in the format of hexadecimal directly. From right to left, add one to the digit on the left if the sum of the current digits exceed 16. You should be able to handle the case when two numbers have different digits.
The correct way to get the input is to store as character array. You can either first store in a string and convert to character array, or you can use methods such as cin.getline(), getc(), cin.get() to read in the characters.
I don't know what is wrong with my program and it I don't know how to use the function getline() and eof()
char a[number1],b[number1],c[number2],h;
int m,n,p(0),q(0),k,d[number1],z[number1],s[number2],L,M;
cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";
cin.getline(a,100);
cin.getline(b,100);
int x=strlen(a) ;
int y=strlen(b);
for(int i=0;i<(x/2);i++)
{
m=x-1-i;
h=a[i];
a[i]=a[m];
a[m]=h;
}
for(int j=0;j<(y/2);j++)
{
n=y-1-j;
h=b[j];
b[j]=b[n];
b[n]=h;
}
if(x>y)
{
for(int o=0;o<x;o++)//calculate a add b
{
if(o>=(y-1))
z[o]=0;//let array b(with no character)=0
if(a[o]=='A')
d[o]=10;
else if(a[o]=='B')
d[o]=11;
else if(a[o]=='C')
d[o]=12;
else if(a[o]=='D')
d[o]=13;
else if(a[o]=='E')
d[o]=14;
else if(a[o]=='F')
d[o]=15;
else if(a[o]=='0')
d[o]=0;
else if(a[o]=='1')
d[o]=1;
else if(a[o]=='2')
d[o]=2;
else if(a[o]=='3')
d[o]=3;
else if(a[o]=='4')
d[o]=4;
else if(a[o]=='5')
d[o]=5;
else if(a[o]=='6')
d[o]=6;
else if(a[o]=='7')
d[o]=7;
else if(a[o]=='8')
d[o]=8;
else if(a[o]=='9')
d[o]=9;
if(b[o]=='A')
z[o]=10;
else if(b[o]=='B')
z[o]=11;
else if(b[o]=='C')
z[o]=12;
else if(b[o]=='D')
z[o]=13;
else if(b[o]=='E')
z[o]=14;
else if(b[o]=='F')
z[o]=15;
else if(b[o]=='0')
z[o]=0;
else if(b[o]=='1')
z[o]=1;
else if(b[o]=='2')
z[o]=2;
else if(b[o]=='3')
z[o]=3;
else if(b[o]=='4')
z[o]=4;
else if(b[o]=='5')
z[o]=5;
else if(b[o]=='6')
z[o]=6;
else if(b[o]=='7')
z[o]=7;
else if(b[o]=='8')
z[o]=8;
else if(b[o]=='9')
z[o]=9;
p=d[o]+z[o]+q;
if(p>=16)//p is the remained number
{
q=1;
p=p%16;
}
else
q=0;
if(p==0)
c[o]='0';
else if(p==1)
c[o]='1';
else if(p==2)
c[o]='2';
else if(p==3)
c[o]='3';
else if(p==4)
c[o]='4';
else if(p==5)
c[o]='5';
else if(p==6)
c[o]='6';
else if(p==7)
c[o]='7';
else if(p==8)
c[o]='8';
else if(p==9)
c[o]='9';
else if(p==10)
c[o]='A';
else if(p==11)
c[o]='B';
else if(p==12)
c[o]='C';
else if(p==13)
c[o]='D';
else if(p==14)
c[o]='E';
else if(p==15)
c[o]='F';
}
k=x+1;
if(q==1)//calculate c[k]
{
c[k]='1';
for(int f=0;f<=(k/2);f++)
{
m=k-f;
h=c[f];
c[f]=c[m];
c[m]=h;
}
}
else
{
for(int e=0;e<=(x/2);e++)
{
m=x-e;
h=c[e];
c[e]=c[m];
c[m]=h;
}
}
}
if(x=y)
{
for(int o=0;o<x;o++)//calculate a add b
{
if(a[o]=='A')
d[o]=10;
else if(a[o]=='B')
d[o]=11;
else if(a[o]=='C')
d[o]=12;
else if(a[o]=='D')
d[o]=13;
else if(a[o]=='E')
d[o]=14;
else if(a[o]=='F')
d[o]=15;
else if(a[o]=='0')
d[o]=0;
else if(a[o]=='1')
d[o]=1;
else if(a[o]=='2')
d[o]=2;
else if(a[o]=='3')
d[o]=3;
else if(a[o]=='4')
d[o]=4;
else if(a[o]=='5')
d[o]=5;
else if(a[o]=='6')
d[o]=6;
else if(a[o]=='7')
d[o]=7;
else if(a[o]=='8')
d[o]=8;
else if(a[o]=='9')
d[o]=9;
if(b[o]=='A')
z[o]=10;
else if(b[o]=='B')
z[o]=11;
else if(b[o]=='C')
z[o]=12;
else if(b[o]=='D')
z[o]=13;
else if(b[o]=='E')
z[o]=14;
else if(b[o]=='F')
z[o]=15;
else if(b[o]=='0')
z[o]=0;
else if(b[o]=='1')
z[o]=1;
else if(b[o]=='2')
z[o]=2;
else if(b[o]=='3')
z[o]=3;
else if(b[o]=='4')
z[o]=4;
else if(b[o]=='5')
z[o]=5;
else if(b[o]=='6')
z[o]=6;
else if(b[o]=='7')
z[o]=7;
else if(b[o]=='8')
z[o]=8;
else if(b[o]=='9')
z[o]=9;
p=d[o]+z[o]+q;
M=p;
if(p>=16)
{
q=1;
p=p%16;
}
else
q=0;
s[o]=p;
if(p==0)
c[o]='0';
else if(p==1)
c[o]='1';
else if(p==2)
c[o]='2';
else if(p==3)
c[o]='3';
else if(p==4)
c[o]='4';
else if(p==5)
c[o]='5';
else if(p==6)
c[o]='6';
else if(p==7)
c[o]='7';
else if(p==8)
c[o]='8';
else if(p==9)
c[o]='9';
else if(p==10)
c[o]='A';
else if(p==11)
c[o]='B';
else if(p==12)
c[o]='C';
else if(p==13)
c[o]='D';
else if(p==14)
c[o]='E';
else if(p==15)
c[o]='F';
}
k=x+1;
if(q==1)
{
c[k]='1';
for(int f=0;f<=(k/2);f++)
{
m=k-f;
h=c[f];
c[f]=c[m];
c[m]=h;
}
}
else
{
for(int e=0;e<=(x/2);e++)
{
m=x-e;
h=c[e];
c[e]=c[m];
c[m]=h;
}
}
}
Lets look at what cin.getline does:
Extracts characters from stream until end of line. After constructing
and checking the sentry object, extracts characters from *this and
stores them in successive locations of the array whose first element
is pointed to by s, until any of the following occurs (tested in the
order shown):
end of file condition occurs in the input sequence (in which case setstate(eofbit) is executed)
the next available character c is the delimiter, as determined by Traits::eq(c, delim). The delimiter is extracted (unlike basic_istream::get()) and counted towards gcount(), but is not stored.
count-1 characters have been extracted (in which case setstate(failbit) is executed).
If the function extracts no characters (e.g. if count < 1), setstate(failbit)
is executed. In any case, if count>0, it then stores a null character
CharT() into the next successive location of the array and updates
gcount().
The result of that is in all cases, s now points to a null terminated string, of at most count-1 characters.
In your usage, you have up to 99 digits, and can use strlen to count exactly how many. eof is not a character, nor it is a member function of char.
You then reverse in place the inputs, and go about your overly repetitious conversions.
However, it's much simpler to use functions, both those you write yourself and those provided by the standard.
// translate from '0' - '9', 'A' - 'F', 'a' - 'f' to 0 - 15
static std::map<char, int> hexToDec { { '0', 0 }, { '1', 1 }, ... { 'f', 15 }, { 'F', 15 } };
// translate from 0 - 15 to '0' - '9', 'A' - 'F'
static std::map<int, char> decToHex { { 0, '0' }, { 1, '1' }, ... { 15, 'F' } };
std::pair<char, bool> hex_add(char left, char right, bool carry)
{
// translate each hex "digit" and add them
int sum = hexToDec[left] + hexToDec[right];
// we have a carry from the previous sum
if (carry) { ++sum; }
// translate back to hex, and check if carry
return std::make_pair(decToHex[sum % 16], sum >= 16);
}
int main()
{
std::cout << "Input two hexadecimal numerals(both of them within 100 digits):\n";
// read two strings
std::string first, second;
std::cin >> first >> second;
// reserve enough for final carry
std::string reverse_result(std::max(first.size(), second.size()) + 1, '\0');
// traverse the strings in reverse
std::string::const_reverse_iterator fit = first.rbegin();
std::string::const_reverse_iterator sit = second.rbegin();
std::string::iterator rit = reverse_result.begin();
bool carry = false;
// while there are letters in both inputs, add (with carry) from both
for (; (fit != first.rend()) && (sit != second.rend()); ++fit, ++sit, ++rit)
{
std::tie(*rit, carry) = hex_add(*fit, *sit, carry);
}
// now add the remaining digits of first (will do nothing if second is longer)
for (; (fit != first.rend()); ++fit)
{
// we need to account for a carry in the last place
// potentially all the way up if we are adding e.g. "FFFF" to "1"
std::tie(*rit, carry) = hex_add(*fit, *rit++, carry);
}
// or add the remaining digits of second
for (; (sit != second.rend()); ++sit)
{
// we need to account for a carry in the last place
// potentially all the way up if we are adding e.g. "FFFF" to "1"
std::tie(*rit, carry) = hex_add(*sit, *rit++, carry);
}
// result has been assembled in reverse, so output it reversed
std::cout << reverse_result.reverse();
}
Regarding the text of your problem: “add one to the digit on the left if the sum of the current digits exceed 16” is wrong; it should be 15, not 16.
Regarding your code: I did not have the patience to read all your code, however:
I have noticed one long if/else. Use a switch (but you do not need one).
To find out if a character is a hex digit use isxdigit (#include <cctype>).
The user might input uppercase and lowercase characters: convert them to the same case using toupper/tolower.
To convert a hex digit to an integer:
if the digit is between ‘0’ and ‘9’ simply subtract ‘0’. This works because the codes for ‘0’, ‘1’… are 0x30, 0x31... (google ASCII codes).
if the digit is between ‘A’ and ‘F’, subtract ‘A’ and add 10.
Solving the problem:
“less than 100 digits long” This is a clear indication regarding how your data must be stored: a simple 100 long array, no std::string, no std::vector:
#define MAX_DIGITS 100
typedef int long_hex_t[MAX_DIGITS];
In other words your numbers are 100 digits wide, at most.
Decide how you store the number: least significant digit first or last? I would chose to store the least significant first. 123 is stored as {3,2,1,0,…0}
Use functions to simplify your code. You will need three functions: read, print and add:
int main()
{
long_hex_t a;
read( a );
long_hex_t b;
read( b );
long_hex_t c;
add( c, a, b );
print( c );
return 0;
}
The easiest function to write is add followed by print and read.
For read use get and putback to analyze the input stream: get extracts the next character from stream and putback is inserting it back in stream (if we do not know how to handle it).
Here it is a full solution (try it):
#include <iostream>
#include <cctype>
#define MAX_DIGITS 100
typedef int long_hex_t[MAX_DIGITS];
void add( long_hex_t c, long_hex_t a, long_hex_t b )
{
int carry = 0;
for ( int i = 0; i < MAX_DIGITS; ++i )
{
int t = a[i] + b[i] + carry;
c[i] = t % 16;
carry = t / 16;
}
}
void print( long_hex_t h )
{
//
int i;
// skip leading zeros
for ( i = MAX_DIGITS - 1; i >= 0 && h[i] == 0; --i )
;
// all zero
if ( i < 0 )
{
std::cout << '0';
return;
}
// print remaining digits
for ( i; i >= 0; --i )
std::cout << char( h[i] < 10 ? h[i] + '0' : h[i] - 10 + 'A' );
}
void read( long_hex_t h )
{
// skip ws
std::ws( std::cin );
// skip zeros
{
char c;
while ( std::cin.get( c ) && c == '0' )
;
std::cin.putback( c );
}
//
int count;
{
int i;
for ( i = 0; i < MAX_DIGITS; ++i )
{
char c;
if ( !std::cin.get( c ) )
break;
if ( !std::isxdigit( c ) )
{
std::cin.putback( c );
break;
}
c = std::toupper( c );
h[i] = c <= '9'
? ( c - '0' )
: ( c - 'A' + 10 );
}
count = i;
}
// reverse
for ( int i = 0, ri = count - 1; i < count / 2; ++i, --ri )
{
int t = h[i];
h[i] = h[ri];
h[ri] = t;
}
// fill the rest with zero
for ( int i = count; i < MAX_DIGITS; ++i )
h[i] = 0;
}
int main()
{
long_hex_t a;
read( a );
long_hex_t b;
read( b );
long_hex_t c;
add( c, a, b );
print( c );
return 0;
}
This is a long answer. Because you have much bug in your code. Your using of getline is ok. But your are calling a eof() like e.eof() which is wrong. If you have looked at your compilation error, you would see that it was complaining about calling eof() on the variable e because it is of non-class type. Simple meaning it is not an object of some class. You cannot put the dot operator . on primitive types like that. I think what you are wanting to do, is to terminate the loop when you have reached the end of line. So that index1 and index2 can get the length of the string input. If I were you, I would just use C++ builtin strlen() function for that. And in the first place, you should use C++ class string to handle strings. Also strings have a null - terminating character '\0' at the end of them. If you don't know about it, I suggest you take some time to read about strings.
Secondly, you have many bugs and errors in your code. The way you are reversing your string is not correct. Ask yourself, what are the contents of the arrays a and b at position which have higher index than the length of the string? You should use reverse() for reversing strings and arrays.
You have errors on adding loop also. Note, you are changing the arrays value when they are A, B, C, D, and so on for hexadecimal values with the corresponding decimal values 10,11,12,13 and so on. But you should change the values for the character '0' - '9' also. Because when the array holds '0' it is not integer 0. But is is ASCII '0' which has integer value of 48. And the character '1' has integer value of 49 and so on. You want to replace this values with corresponding integer values also. When you are also storing the result values in c, you are only handling only those values which are above 9 and replacing them with corresponding characters. You should also replace the integers 0 - 9 with there corresponding ASCII characters. Also don't forget to put a null terminating character at the end of the result.
Also, when p is getting larger than 15, you are only changing your carry, but you should also change p accordingly.
I believe you can reverse the result array c in a much more elegant way. By only reversing when the calculation has been performed totally. You can simple call reverse() for that.
I believe you can think hard a little bit more, and write the code in the right way. I have a few suggestions for you, don't use variable names like a,b,c,o. Try to name variables with what are they really doing. Also, you can improve your algorithm and shorten your code and headache with one simple change in the algorithm. First find the length of a and then find the length of b. If there lengths are unequal, find out which has lesser length. Then add 0s in front of it to make both lengths equal. Now, you can simply start from the back, and perform the addition. Also, you should use builtin methods like reverse() , swap() and also string class to make your life easier ;)
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main(){
string firstVal,secondVal;
cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";
cin >> firstVal >> secondVal;
//Adjust the length.
if(firstVal.size() < secondVal.size()){
//Find out the number of leading zeroes needed
int leading_zeroes = secondVal.size() - firstVal.size();
for(int i = 0; i < leading_zeroes; i++){
firstVal = '0' + firstVal;
}
}
else if(firstVal.size() > secondVal.size()){
int leading_zeroes = firstVal.size() - secondVal.size();
for(int i = 0; i < leading_zeroes; i++){
secondVal = '0' + secondVal;
}
}
// Now, perform addition.
string result;
int digit_a,digit_b,carry=0;
for(int i = firstVal.size()-1; i >= 0; i--){
if(firstVal[i] >= '0' && firstVal[i] <= '9') digit_a = firstVal[i] - '0';
else digit_a = firstVal[i] - 'A' + 10;
if(secondVal[i] >= '0' && secondVal[i] <= '9') digit_b = secondVal[i] - '0';
else digit_b = secondVal[i] - 'A' + 10;
int sum = digit_a + digit_b + carry;
if(sum > 15){
carry = 1;
sum = sum % 16;
}
else{
carry = 0;
}
// Convert sum to char.
char char_sum;
if(sum >= 0 && sum <= 9) char_sum = sum + '0';
else char_sum = sum - 10 + 'A';
//Append to result.
result = result + char_sum;
}
if(carry > 0) result = result + (char)(carry + '0');
//Result is in reverse order.
reverse(result.begin(),result.end());
cout << result << endl;
}
So I am working on a program that takes an infix expression and converts it to a postfix expression. Meaning when I input a+b, the output will be ab+, And i cant figure out a way to print it out correctly because I cannot think of a way to sort the letters, like how can i translate the input a+b-c to ab+c- instead of abc+-? Source code is still in progress.
#include <iostream>
#include <stack>
using namespace std;
int prec(char in)
{
switch(in) {
case '(': return 0;
case '+':
case '-': return 1;
case '*':
case '/': return 2;
default : return 3;
}
}
int main()
{
stack <char> ops;
//stack <char> high-ops;
char next_character ;
while(!cin.eof()) {
cin >> next_character;
if(next_character =='(' )
ops.push('(');
else if(next_character == ')') {
while(!ops.empty() && ops.top() != '(') {
cout << ops.top();
ops.pop();
}
if(!ops.empty())
ops.pop();
else
cout << "Error/n";
}
if((next_character >= 'a' && next_character <= 'z') || (next_character >= 'A' && next_character <= 'Z') || (next_character >= '0' && next_character <= '9'))
if(next_character == '*' || next_character == '/' || next_character == '+' || next_character == '-') {
if(ops.empty())
ops.push(next_character);
if(prec(next_character) > prec(ops.top()))
ops.push(next_character);
if(prec(ops.top()) > prec(next_character)) {
cout << ops.top();
ops.pop();
if( prec(ops.top()) == prec(next_character)){
ops.push(next_character);
cout << ops.top();
ops.pop();
}
}
}
//if(!ops.empty())
//ops.push(next_character);
}
while(!ops.empty()){
cout << ops.top();
ops.pop();
}
}
You need recursive parsing, not a stack based one.
In psuedo code, it would look like this:
func reorder(expression)
if whole_expression_is_wrapped_with_parentheses
return reorder(expression without wrapping parentheses)
if exists_operator(expression)
oi = operator_index = find_operator(expression)
before = expression.substring(0 to oi-1, including)
operator = expression.charAt(oi)
after = expression.substring(oi + 1 to end of string)
return reorder(before) + reorder(after) + oi
return expression
func exists_operator(expression)
Simply check if any operator is in the expression out of parentheses.
func find_operator(expression)
Return the id of the first operator found out of parentheses.
To implement precedence, ignore lower precedence operators until making sure no higher precedence operators are in the expression
The two helper functions should be implemented with a stack-based parentheses counter, to make sure you search only out of any parentheses.
I want to calculate (x^2^2^2^2+x^2^2^2) result should be [x^256+x^16]..but i am unable to do this completely..i also have written a code which is working for first half(before '+') but in other half it fails to do it...
#include<iostream>
#include<string>
#include <algorithm>
#include<sstream>
using namespace std;
int main()
{
string a;
cin >> a;
string s1 = "^";
string::size_type foud;
foud = a.find(s1);
int i = foud;
int flag = 0;
i++;
while (foud != std::string::npos)
{
flag = 0;
cout << i <<"I"<< endl;
while (flag != 1 && i < a.length())
{
if (a[i] == '(' || a[i] == '+' || a[i] == '-' || a[i] == ')')
{
flag++;
cout << "terminator" << endl;
}
else if (a[i] == '^')
{
/*int j = (int)(a[i - 1]);
j = j - 48;
int k = (int)(a[i + 1]);
k = k - 48;
i = k + 1;
int power =0;
power = pow(j, k);
;*/
int j = i;
int k = i;
k--;
j++;
string bcknumber;
while (a[k] != '^' && a[k] != '(' && a[k] != '+' && a[k] != '-' && a[k] != ')')
{
bcknumber = bcknumber + a[k];
k--;
}
cout << bcknumber << endl;
reverse(bcknumber.begin(), bcknumber.end());
cout << bcknumber << endl;
int BK;
BK = stoi(bcknumber);
int FD;
string frdnum;
while (a[j] != '^'&&a[j] != '\0' && a[j] != '(' && a[j] != '+' && a[j] != '-' && a[j] != ')')
{
frdnum = frdnum + a[j];
j++;
}
FD = stoi(frdnum);
int resil = pow(BK, FD);
frdnum.clear();
stringstream s;
string res;
s << resil;
res = s.str();
if (i == 15)
{
a.replace(14, 15, res);
}
else
{
a.replace(i - bcknumber.length(), i + frdnum.length(), res);
}
i--;
bcknumber.clear();
}
else
i++;
}
foud = a.find("^", foud + 1);
i = foud;
i++;
}
cout << a << endl;
system("pause");
}
This is not a trivial problem. You want to build an infix calculator (a + b). A prefix calculator (+ a b) or a postfix calculator (a b +) are simpler, since there are no ambiguities at all. An infix calculator can have a lot of them, depending on the degree of freedom you want the user to have.
In the problem you're exposing, one is tempted to say: well, if there is an operator next to the second operand, then I have to accumulate the last result and operate with that and the next operation. However, there are problems like precedence which will not be deal with with that approach.
I would start creating a prefix calculator. It is a lot easier:
calculate():
opr = match operator
op1 = match operand
if op1 is operator:
back
op1 = calculate
op2 = match operand
if op2 is operator:
back
op2 = calculate
return calc(opr, op1, op2)
Once you have mastered that, then there is the possibility to start with an infix calculator.
One thing to do in the last algorithm would be to change it to avoid recursion, for example.
This is a good exercise, enjoy it. Hope this helps.
This smells like homework/assignment so I will not provide code...
As I see it you want just string parser to string replacing the power part. I am assuming You still do not understand the power math or are wrongly writing/interpreting representation of the string. For example:
x^2^2^2^2 =
(((x^2)^2)^2)^2 =
(((x.x)^2)^2)^2 =
((x.x).(x.x))^2)^2 =
((x.x.x.x))^2)^2 =
((x.x.x.x).(x.x.x.x))^2 =
(x.x.x.x.x.x.x.x)^2 =
(x.x.x.x.x.x.x.x).(x.x.x.x.x.x.x.x) =
(x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x) =
x^16
And not yours x^256. You can not add parenteses where you want they must be placed according to order of math operations otherwise the resulting equation will not match the input string !!!. In case you got defined different parse rules for your parser then in standard math then you need to define them in the Question.
Now how to approach this:
read string
I would start with constant hard-coded string instead of typing it all the time while programing/debugin over and over (as many students do ... I saw few times people typing 5x5 matrix on each build :) ... which is insane)
When the program works only then use the cin reading... as you already do
detect which part of the string is power exponent
exponent=1
Search the string for first ^ and remember the start position i0 if not found goto #4.
Now depending on what follows:
If number multiply exponent by it.
If ^ skip it and goto to #2
if neither stop
Of coarse if you should support parentes then it will be much much more complicated and you need to decode the whole thing which is not trivial which you should also mention in the Question.
replace original exponent string with computed string (if computable)
so the computed string will be "^"<<exponent or "^"+exponent depends on what kind of string arithmetics you using ....
output string
with cout or whatever as you already do
I'm sure this has been asked a few times but the other questions I looked at didn't really help me much. Alright so here goes: I've got three functions one that converts an infix expression to a postfix, one that's a preprocessor and one that evaluates the postfix expression. What I'm having trouble with is evaluating a unary negative expression. If I put in my entire code it'll be super long so I'm only going to post up the parts that deal with the negative/minus case:
here's my output:
input: -3
after preprocess: 3
postfix = -3
then a segmentation fault when it should output " total = -3 "
#include "postfix.h"
#include "stack.h"
#include <cstdlib>
#include <cmath>
#include <cstdio>
void eval_postfix(char* postfix){
Stack<double> stack;
char fchar[100];
int j=0;
double a, b, convert, total = 0.0;
for(int i=0; postfix[i] != '\0'; i++){
switch(postfix[i]){
case '-':
a = stack.top();
stack.pop();
b = stack.top();
stack.pop();
total = b-a;
stack.push(total);
break;
I'm pretty sure the error is in that part of the function, I've been trying different things but nothing has been working, more times than not I get a segmentation fault or a zero. I originally tried to apply what I did in the infix2postfix expression (which obviously didn't work) But here's the rest of my code for the negative/minus case...
void infix2postfix(char* infix, char* postfix){
Stack<char> stack;
stack.push('\0');
int pc = 0;
bool c;
for(unsigned int i = 0; infix[i] != '\0'; i++){
//use the switch method to define what to do for each of the operators
switch(infix[i]){
case '-':
c = 0;
//unary negative
if(i==0){
postfix[pc++] = infix[i];
c = 1;
}
else if((infix[i-1] == '*' ||
infix[i-1] == '^' ||
infix[i-1] == '*' ||
infix[i-1] == '/' ||
infix[i-1] == '+' ||
infix[i-1] == '-')&&
i>0){
postfix[pc++]= infix[i];
c=1;
}
else{
if(stack.top() == '*' || stack.top() == '/' || stack.top() == '^'){
while(stack.top() != '\0' && stack.top() != '('){
postfix[pc++] = stack.top();
postfix[pc++] = ' ';
stack.pop();
}
}
}
if (c==0)
stack.push('-');
break;
void preprocessor(char* input){
char output[100];
int oc = 0;
for(unsigned int i=0; input[i] != '\0'; i++){
if((input[i] == '-' && (input[i-1] == '*' || input[i-1] == '^' || input[i-1] == '*'
|| input[i-1] == '/' || input[i-1] == '+' || input[i-1] == '-')
&& i>0)){
//output[oc++] = '0';
output[oc++] = input[i];
}
I'm almost certain that whatever error it is I made (or whatever edit I need to do) is probably something really simple that I just can't see (cause that's usually the case with me) but any nudge in the right direction would be highly appreciated!
**Note: the formatting of my code may not be accurate cause I only copied and pasted the parts I felt were relevant.
It seems to me like what is happening is that your code that evaluates the postfix expression, when it sees a minus sign, treats it as a subtraction. In particular, probably you push 3 onto the stack, and then encounter a minus sign: this triggers the code in the first block you posted, which tries to pop two elements off of the stack and subtract them. However there is only one element on the stack, namely the 3.