I am trying to create an input operator for a Polynomial class. However, my input operator is not reading my first coefficients and everything after the first exponent. It is basically reading the first term without coefficients. Here is my code:
std::istream & operator>> (std::istream & in,
Polynomial & aPoly)
{
double tempCoefficient; // temporary storage for coefficient
char ch; // variable that contains results from peek()
char dum; // removes useless symbols like '+' and 'x'
int tempExponent; // contains current exponent for coefficient
bool moreTerms = true; // variable that tells when the terms run out
bool negativeCoefficient = false; // tells when coefficient is negative
aPoly.coefficients.resize(0); // Clears aPoly before inserting user input
in >> ch ;
if (ch == '-')
{
negativeCoefficient = true;
ch = in.peek();
}
else
{
in.putback(ch);
}
if (ch >= '0' && ch <= '9')
{
in >> tempCoefficient;
if (negativeCoefficient)
{
tempCoefficient *= -1;
negativeCoefficient = false;
}
ch = in.peek();
}
if (ch == 'x')
{
tempCoefficient = 1.0;
in >> dum;
if (in.peek() == '^')
{
in >> dum;
in >> tempExponent;
}
else
{
tempExponent = 1;
}
}
else
{
tempExponent = 0;
moreTerms = false;
}
aPoly.coefficients.resize(tempExponent + 1);
aPoly.coefficients[tempExponent] = tempCoefficient;
if ((in.peek() != '+') || (in.peek() != '-'))
{
moreTerms = false;
}
while (moreTerms)
{
ch = in.peek();
if (ch == '+')
{
in >> dum; // '+'
}
else
{
negativeCoefficient = true;
in >> dum; // '-'
}
ch = in.peek();
if ( (ch >= '0') && (ch <= '9') )
{
in >> tempCoefficient;
if (negativeCoefficient)
{
tempCoefficient *= -1;
negativeCoefficient = false;
}
ch = in.peek();
}
else
{
if (negativeCoefficient)
{
tempCoefficient = -1.0;
negativeCoefficient = false;
}
else
{
tempCoefficient = 1.0;
}
}
if (ch == 'x')
{
in >> dum;
if (in.peek() == '^')
{
in >> dum;
in >> tempExponent;
}
else
{
tempExponent = 1;
}
}
else
{
tempExponent = 0;
moreTerms = false;
}
if ((in.peek() != '+') && (in.peek() != '-'))
{
moreTerms = false;
}
aPoly.coefficients[tempExponent] = tempCoefficient;
}
return in;
}
You have a problem here
if ((in.peek() != '+') || (in.peek() != '-'))
where the condition is always true.
Further down in the code you use && which works better.
Related
Been scratching my head for hours already and I have no clue what my mistake is. I'm following my professor's derived algorithm step by step and I don't know why it isn't working properly.
Here's the derived Algorithm:
Here's the code that I tried to make:
#include <iostream>
#include "ecpe202.h"
#define Max 100
using namespace std;
int getICP(char x){
if (x == ')'){
return 0;
}
else if (x == '^'){
return 4;
}
else if (x == '*' || x == '/'){
return 2;
}
else if (x == '+' || x == '-'){
return 1;
}
else if (x == '('){
return 4;
}
}
int getISP(char x){
if (x == ')'){
return 0;
}
else if (x == '^'){
return 3;
}
else if (x == '*' || x == '/'){
return 2;
}
else if (x == '+' || x == '-'){
return 1;
}
else if (x == '('){
return 0;
}
}
bool isOperator(char ch){
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == '*' || ch == '(' || ch == ')'){
return (true);
}
else{
return (false);
}
}
int main(){
char infix[Max];
char ch;
int length;
myQueue que;
myStack stk;
createQ(que);
createS(stk);
cout << "Enter an infix Expression: ";
cin >> infix;
cout << endl << endl;
cout << "The postfix Expression: ";
length = strlen(infix);
for (int i = 0; i < length; i++){
addQ(que, infix[i]);
}
while (!isEmptyQ(que)){
ch = retrieveQ(que);
//start of infix to postfix algo
//1. push
if (ch == '('){
pushS(stk, ch);
}
//2. if scanned is operand
if (!isOperator(ch)){
cout << ch;
}
else{
//2.1 push if...
if (isEmptyS(stk) || getICP(ch) > getISP(topS(stk)) || topS(stk) == '('){
pushS(stk, ch);
}
//2.2. pop all operators
else{
while(!isEmptyS(stk) && getISP(topS(stk)) >= getICP(ch) || topS(stk) == '('){
cout << popS(stk);
}
}
pushS(stk, ch);
}
//3. If scanned ')'
bool loop = true;
if (ch == ')'){
do{
if (ch == '('){
loop = false;
}
else{
cout << popS(stk);
}
}while(loop == true);
}
//repeat 1-3
}
cout << endl;
}
For the ecpe202.h:
#include<dos.h>
#include<windows.h>
#define FOREVER true
#define MAXSTACK 100
#define MAXQUEUE 100
using namespace std;
struct myStack{
int tos;
char s[MAXSTACK];
};
struct myQueue{
int head, tail, q[MAXQUEUE];
};
//STACK
void createS(myStack &S){
S.tos=-1;
}
void pushS(myStack &S, char item){
S.s[++S.tos] = item;
}
char popS(myStack &S){
return(S.s[S.tos--]);
}
char topS(myStack S){
return (S.s[S.tos]);
}
bool isFullS(myStack S){
if(S.tos == MAXSTACK - 1)
return true;
return false;
}
bool isEmptyS(myStack S){
if (S.tos == -1)
return true;
return false;
}
//QUEUE
void createQ(myQueue &Q){
Q.head = 0;
Q.tail = 0;
}
void addQ(myQueue &Q, char item){
Q.q[Q.tail++] = item;
Q.tail %= MAXQUEUE;
}
char retrieveQ(myQueue &Q){
char temp;
temp = Q.q[Q.head++];
Q.head %= MAXQUEUE;
return temp;
}
bool isFullQ(myQueue Q){
if (Q.tail == MAXQUEUE)
return true;
return false;
}
bool isEmptyQ(myQueue Q){
if (Q.tail == Q.head)
return true;
return false;
}
//GOTOXY
void gotoxy(int x, int y){
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void clrscr(){
system("CLS");
}
The output that my code:
What seems to be wrong in my program? tried re-reading it a couple of times and I still can't fix it.
I am writing a C++ program that will show you how to pronounce a Hawaiian word.
Rules:
p, k, h, l, m, n (Pronounced like the english versions.)
w -start of word (Either pronounced as a w or a v sound. We shall pronounce it as a w sound.)
w -after the letter ‘a’ (Either pronounced as a w or a v sound. We shall pronounce it as a w sound.)
w -after ‘i’ or ‘e’ (Pronounced as a v sound.)
w -after ‘u’ or o (Pronounced as a w sound.)
My progress: My program works, but there's a couple of bugs.
When I type "iwa", the pronunciation must be "ee-vah" but I'm
getting "ee-wah".
My code is not ignoring whitespaces. So when I type "e komo mai", I want "eh koh-moh meye" but instead, I get "e komo mai is pronounced eh-eh-koh-moh-oh-meye".
Here is my code:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
string convertToHawaiian(string input);
bool vowelGroup(char first, char next, string& replacement);
bool consonantGroup(char prevchar, char currchar, string& replacement);
bool singleVowel(char current, string& replacement);
int main() {
// Declare my variables
string userInput;
string replacement;
//cout << "Enter a hawaiian word to pronounce ==>";
getline(cin,userInput);
// For loop that will call my Consonant function
// Call my Hawaiian function and put it
// into pronunciation
replacement = convertToHawaiian(userInput);
// if My initial input has a capital, the replacement
// will keep the capital letter at the beginning
if (isupper(userInput.at(0))) {
replacement.at(0) = toupper(replacement.at(0));
}
// Get rid of the '-' character at the end of the string
if (replacement.at(replacement.size() - 1) == '-') {
replacement.pop_back();
}
cout << userInput << " is pronounced " << replacement << endl;
return 0;
}
// My main function that will convert my input
// into the hawaiian pronunciation
string convertToHawaiian(string input) {
char nextChar;
string replacement = "";
string result = "";
// Iterate through my string to check for vowels,
// vowelgroups and consonants.
for (unsigned int i = 0; i < input.size(); i++) {
char character = input.at(i);
character = tolower(character);
if (i != input.size() - 1) {
nextChar = input.at(i + 1);
nextChar = tolower(nextChar);
}
if ((i != input.size() - 1) && (vowelGroup(character, nextChar, replacement))) {
i++;
result = result + replacement;
}
else if (singleVowel(character, replacement)) {
result = result + replacement;
}
else {
consonantGroup(character, nextChar, replacement);
result = result + replacement;
}
}
return result;
}
bool vowelGroup (char first, char nextChar, string& result) {
bool isVowel = true;
if (first == 'a') {
nextChar = tolower(nextChar);
if ((nextChar == 'i') || (nextChar == 'e')) {
result = "eye-";
}
else if ((nextChar == 'o') || (nextChar == 'u')) {
result = "ow-";
}
else {
return false;
}
}
else if (first == 'e') {
nextChar = tolower(nextChar);
if (nextChar == 'i') {
result = "ay-";
}
else if (nextChar == 'u') {
result = "eh-oo-";
}
else {
return false;
}
}
else if (first == 'i') {
nextChar = tolower(nextChar);
if (nextChar == 'u') {
result = "ew-";
}
else {
return false;
}
}
else if (first == 'o') {
nextChar = tolower(nextChar);
if (nextChar == 'i') {
result = "oy-";
}
else if (nextChar == 'u') {
result = "ow-";
}
else {
return false;
}
}
else if (first == 'u') {
nextChar = tolower(nextChar);
if (nextChar == 'i') {
result = "ooey-";
}
else {
return false;
}
}
else {
isVowel = false;
return isVowel;
}
return isVowel;
}
// Check to verify consonants
bool consonantGroup(char character, char nextChar, string& replacement) {
bool isConson = true;
if ((character == 'p') || (character == 'k') || (character == 'h') || (character == 'l') || (character == 'm') || (character == 'n')){
replacement = character;
return isConson;
}
if ((character == 'w') && (nextChar == 'a')) {
replacement = 'w';
return isConson;
}
else if (((character == 'u') || (character == 'o')) && (nextChar == 'w')) {
replacement = 'w';
cout << "Not replacing w" << endl;
return isConson;
}
else if (((character == 'i') || (character == 'e')) && (nextChar == 'w')) {
replacement = 'v';
return isConson;
}
else {
isConson = false;
return isConson;
}
}
bool singleVowel(char current, string& result) {
bool isVowel = true;
if (current == 'a') {
result = "ah-";
return isVowel;
}
else if (current == 'e') {
result = "eh-";
return isVowel;
}
else if (current == 'i') {
result = "ee-";
return isVowel;
}
else if (current == 'o') {
result = "oh-";
return isVowel;
}
else if (current == 'u') {
result = "oo-";
return isVowel;
}
else {
isVowel = false;
return isVowel;
}
}
One of the more common sources of bugs is shared mutable state.
In your case, it is state shared between loop iterations.
The whitespace case is handled here:
else {
consonantGroup(character, nextChar, replacement);
result = result + replacement;
}
and in that case, replacement will be string "spilled over" from the previous iteration.
The remedy is very simple: declare replacement inside the loop instead.
You can solve the "iwa" problem if you stare at these lines until you spot the bug:
if ((character == 'w') && (nextChar == 'a')) {
replacement = 'w';
I have implemented Shunting yard algorithm using stack in c++.
Well it is working quite well on inputs from SPOJ example inputs but when I input:
1
(((a+b) * (c+r)^(t+b)-n)^(c-(d * e))-b)+(c+(e-(d^r)))
I get a runtime error.
Note: I only get a runtime error when I call infixToPostfix() and use the above input and not when I comment it out.
Submission to SPOJ and running on ideone(with input above) results in a runtime error.
I really can't understand this behaviour of my program, so any help is welcomed.
I have tried some random inputs and it seems to work fine on them.
Even though they had spaces around operators.
#include<iostream>
#include<vector>
#include<math.h>
#include<stack>
#include<strings.h>
using namespace std;
void infixToPostfix(string st);
int pr(char s);
int main() {
int t;
scanf("%d",&t);
cin.ignore();
string st; // input string
while(t--)
{
getline(cin,st);
cin.sync();
cout<<st<<endl;
infixToPostfix(st);
}
return 0;
}
int pr(char s) // to check precedence
{
if(s == '^')
{
return 4;
}
else if(s == '*')
{
return 3;
}
else if(s == '/')
{
return 3;
}
else if(s == '+')
{
return 2;
}
else if(s == '-')
{
return 2;
}
else {
return 0;
}
}
void infixToPostfix(string st)
{
stack<char>op; //stack to hold operators and bracket
st += 'n';
int l = st.size();
op.push('0');
string fst; //final string
for(int x = 0;x<l;x++)
{
if(st[x] == '(')
{
op.push(st[x]);
}
else if(st[x] == ')')
{
while(op.top() != '(' && !op.empty())
{
fst +=op.top();
op.pop();
}
op.pop();
}
else if(st[x] == '+' || st[x] == '-' || st[x] == '*' ||st[x] == '/' ||st[x] == '^')
{
if(pr(st[x]) <= pr(op.top()))
{
fst += op.top();
op.pop();
op.push(st[x]);
}
else{
op.push(st[x]);
}
}
else if(st[x] == 'n'){
while(op.size() != 0)
{
if(op.top() != '0')
{fst += op.top();}
op.pop();
}
}
else if((st[x] >= 'a' || st[x] <= 'z' )&& st[x] != ' ')
{
fst += st[x];
}
}
printf("%s\n",fst.c_str());
}
So I am working on some homework for my uni and need to convert a string to a float. For whatever reason g++ is complaining that the 'stof' function doesn't exist. Although I have included the required header. Here is my code, the error is on the line that says
holder = stof(x.substr(0, end_of_num));
#include <iostream>
#include <string>
#include <list>
using namespace std;
float process_func(string x);
bool isPartOfNum(char x);
int main() {
string x;
while (true) {
cout << "input a string" << endl;
getline(cin, x);
cout << process_func(x);
}
return 0;
}
float process_func(string x) {
int end_of_num =0;// used to find last index from num
int negMult = 1; //used to multiply value at end if there was a negative
bool onNum = false; //used to
list <float> numList;
list <char> operList;
if ((x.at(0) < 48 || x.at(0) > 57) && x.at(0) != '-') //check if start of string doesnt have a number or negative symbol
return -1;
if (x.at(0) != '-')
negMult = -1;
float holder;// temp holder for floats
int i = 0;
while (i<x.length()) {
if (isPartOfNum(x.at(i))) {
end_of_num++;
onNum = true;
}
else if (onNum) {
holder = stof(x.substr(0, end_of_num));
numList.push_back(holder); //adds num as float to list
x.erase(0, end_of_num + 1); //+1 removes the space after the number before the operator
end_of_num = 0;
onNum = false;
}
if (x.at(i) == '+' || x.at(i) == '-' || x.at(i) == '*' || x.at(i) == '/') {
operList.push_back(x.at(i));
}
} //at this point both lists should be full of all needed pieces of info
int answer = 0;
int temp;
bool firstOper=true; // used to hold first operation
while (numList.size() >=2) { //requires at least 2 entries for last operation
while (!operList.empty()) {
temp = numList.front();
numList.pop_front();
if (operList.front() == '+') {
if (firstOper) {
answer = temp + numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer += temp;
}
}
else if (operList.front() == '-') {
if (firstOper) {
answer = temp - numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer -= temp;
}
}
else if (operList.front() == '*') {
if (firstOper) {
answer = temp * numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer *= temp;
}
}
else if (operList.front() == '/') {
if (firstOper) {
answer = temp / numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer /= temp;
}
}
operList.pop_front();
}
}
return answer;
}
bool isPartOfNum(char x) {
if ((x >= 48 && x <= 57) || (x == '-' || x == '.'))
return true;
return false;
}
Solved by compiling using c++ 11
I am a beginner using the stack so I been trying to do different exercises on it. I'm trying to convert infix->postfix. The xcode debugger says "Use of class template 'stack'requires template arguments'. Here is my code.
#include<iostream>
#include<stack>
#include<string>
using namespace std;
bool IsOperand(char ch)
{
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
return true;
}
return false;
}
bool IsOperator(char C)
{
if (C == '+' || C == '-' || C == '*' || C == '/' || C == '^') {
return true;
}
return false;
}
bool IsLeftParenthesis(char ch)
{
if (ch == '(') {
return true;
}
return false;
}
bool IsRightParenthesis(char ch)
{
if (ch == ')') {
return true;
}
return false;
}
bool Flag(char ch)
{
if (!IsOperand(ch) || !IsOperator(ch) || !IsLeftParenthesis(ch) || !IsRightParenthesis(ch)) {
return false;
}
return true;
}
int IsRightAssociative(char op)
{
if (op == '^') {
return true;
}
return false;
}
int GetOperatorWeight(char op)
{
int weight = -1;
switch (op) {
case '+':
case '-':
weight = 1;
break;
case '*':
case '/':
weight = 2;
break;
case '^':
weight = 3;
break;
}
return weight;
}
bool HasHigherPrecedence(char op1, char op2)
{
int op1Weight = GetOperatorWeight(op1);
int op2Weight = GetOperatorWeight(op2);
// If operators have equal precedence, return true if they are left associative.
// BUT REMEMBER...return false, if right associative.
// if operator is left-associative, left one should be given priority.
if (op1Weight == op2Weight) {
if (IsRightAssociative(op1)) {
return false;
}
else {
return true;
}
}
return op1Weight > op2Weight ? true : false;
}
string InfixToPostfix(string expression)
{
stack S;
string postfix = "";
for (auto& elem : expression) {
if (Flag(elem)) {
continue;
}
// If character is operator, pop two elements from stack, perform operation and push the result back.
else if (IsOperator(elem)) {
while (!S.empty() && S.top() != '(' && HasHigherPrecedence(S.top(), elem)) {
postfix += S.top();
S.pop();
}
S.push(elem);
}
else if (IsOperand(elem)) {
postfix += elem;
}
else if (elem == '(') {
S.push(elem);
}
else if (elem == ')') {
while (!S.empty() && S.top() != '(') {
postfix += S.top();
S.pop();
}
S.pop();
}
}
while (!S.empty()) {
postfix += S.top();
S.pop();
}
return postfix;
}
int main()
{
// std::string expression = "54/(5^2)+(6^2^3)";
std::string expression = "A+(BC-(D/E^F)G)H";
std::string postfix = InfixToPostfix(expression);
std::cout << "Output = " << postfix << "\n";
}
Here specificially where the error is happening.
string InfixToPostfix(string expression)
{
stack S;
It says
Stack S -> Use of class template 'stack'requires template arguments'
Stack is a container, you need to specify the type of the container like:
stack <int> S;
or in you case it is stack of char:
stack <char> S;