• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Arithmethic Parenthesis C++

Status
Not open for further replies.
(NOTE : ignores hierarchy)

Why this code only works if there's no secondary number in the left side of equation and there's only two level of stacks at max?

Working examples :
(2-1)
(8*5)
Other 1 time calculation, if they have ()
((2-1)-1)
((2*4)+4)
Any two tiered calculation if neither side has any value above 9

In other cases, they don't work.

Also, ( (a+b) - (c+d) )) where a,b,c,d are int results in infinite loop.

[IGNORE THE ERROR CHECKS PRIOR TO THE CALCULATION, ALL EQUATION BEING INPUT CONSIDERED PROPERLY SET]

C:
#include <iostream>
#include <stack>
#include <string>
char opr[4] = {'+','-','*','/'};
char num[10] = {'0','1','2','3','4','5','6','7','8','9'};
using namespace std;
void LevelControl(int lvl, int pos)
{
    if (lvl>=0)
        cout << lvl;
    else if (lvl==-1)
        cout << endl << "Invalid Level" << endl;
    else if (lvl==-2)
        cout << endl << "Ending not closed" << endl;
}
bool ArePair(char opening, char closing)
{
    if (opening == '(' && closing == ')') return true;
}
bool ParBalance(string data,bool control)
{
    stack<char> S;
    int level=0,i;
    for (i=0;i<data.length();i++)
    {
        if (data[i]=='(')
        {
            S.push(data[i]);
            level++;
        }
        else if (data[i]==')')
        {
            if(S.empty() || !ArePair(S.top(),data[i]))
            {
                if (control==true)
                    LevelControl(-1,i+1);
                return false;
            }
            else
            {
                level--;
                S.pop();
            }
        }
        if (control==true)
            LevelControl(level,i+1);
    }
    if (S.empty()==false && control==true) LevelControl(-2,i+1);
    return S.empty() ? true:false;
}
void ValReport(int i)
{
    cout << endl << "Error in equation at column " <<i;
}
bool Valid(string data)
{
    for(int i=1;i<data.length();i++)
    {
        for(int j=0;j<4;j++)
        {
            for(int k=0;k<4;k++)
            {
                if (data[i]==opr[j] && (data[i-1]==opr[k] || (i>1 && data[i-2]==opr[k])))
                {
                    ValReport(i);
                    return false;
                }
            }
        }
    }
    return true;
}
int S2I(string s)
{
    int x = 0;
    for (int i=0;i<s.length();i++)
    {
        x = x*10 + ((int) s[i]-'0');
    }
    return x;
}
string I2S(int i)
{
    string s;
    if (i!=0)
    {
        while(i!=0)
        {
            s = (char) ((i%10)+'0') + s;
            i = i/10;
        }
    }
    else
    {
        s = ((char) (i)+'0');
    }
    cout << "Value is : " << s << endl;
    return s;
}
string Computate(string data)
{
    int num1,num2,res,i,j;
    char op;
    bool stnum = false;
    string s;
    for (i=0;i<data.length();i++)
    {
        cout << "2" << endl;
        for(j=0;j<10;j++)
        {
            if (data[i]==num[j])
            {
                cout << "3" << endl;
               s = (char)data[i] + s;
            }
        }
        if (stnum==false)
        {
            num1=S2I(s);
            s.clear();
            stnum = true;
        }
        else
        {
            num2=S2I(s);
        }
        for(j=0;j<4;j++)
        {
            if (data[i]==opr[j])
            {
                op = data[i];
            }
        }
    }
    cout << "4" << endl;
    cout << "Get Num (1,2) : " << num1 << "," << num2 << endl;
    switch (op)
    {
        case '+' : res = num1 + num2;break;
        case '-' : res = num1 - num2;break;
        case '*' : res = num1 * num2;break;
        case '/' : res = num1 / num2;break;
    }
    cout << "Get Res : "<< res << endl;
    cout << "5" << endl;
    s = I2S(res);
    cout << "6" << endl;
    return s;
}
string Loop(string data)
{
    string tempdata;
    stack<char> S;
    int temp;
    for (int i=0;i<=data.length();i++)
    {
        if (data[i]=='(')
        {
            S.push(i);
            cout << "PUSH" << endl;
            if (S.size()>9)
            {
                cout << "Oversize!";
                break;
            }
        }
        else if (data[i]==')')
        {
            tempdata = data.substr(S.top()+1,i-1);
            cout << i << endl;
            tempdata = Computate(tempdata);
            data.replace(S.top(),i,tempdata);
            if (S.size()==1)
            {
                data.erase();
                data = tempdata;
            }
            cout << "Current Data : " <<data << endl;
            S.pop();
            cout << "POP" << endl;
            break;
        }
    }
    if (!S.empty())
        return Loop(data);
    else
        return data;
}
int CountAll(string data)
{
    int temp;
    string last;
    last = Loop(data);
    temp = S2I(last);
    return temp;
}
int main()
{
    char input[70];
    string data;
    cout << "Input : " << endl;
    cin.getline(input, sizeof(input));
    data = input;
    if (ParBalance(data,true))
        cout << endl << "Balanced"<< endl;
    else
        cout << endl << "Not Balanced"<< endl;
    if (Valid(data))
        cout << endl << "Valid"<< endl;
    else
        cout << endl << "Invalid"<< endl;
    cout << "Result is : " << CountAll(data);
    return 0;
}
 
Last edited:
Tried in the debugger. Results :

Active debugger config: GDB/CDB debugger:Default
Building to ensure sources are up-to-date
Selecting target:
Debug
Adding source dir: C:\Users\Daffa Abiyyu\Documents\Struktur Data\Stack 5\
Adding source dir: C:\Users\Daffa Abiyyu\Documents\Struktur Data\Stack 5\
Adding file: C:\Users\Daffa Abiyyu\Documents\Struktur Data\Stack 5\bin\Debug\Stack 5.exe
Changing directory to: C:/Users/DAFFAA~1/DOCUME~1/STRUKT~1/STACK5~1/.
Set variable: PATH=.;C:\Program Files (x86)\CodeBlocks\MinGW\bin;C:\Program Files (x86)\CodeBlocks\MinGW;C:\Python27;C:\Python27\Scripts;C:\Program Files (x86)\Python 2.7;C:\Program Files (x86)\Python 2.7\Scripts;C:\Program Files (x86)\Common Files\Intel\Shared Files\cpp\Bin\Intel64;C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\iCLS Client;C:\Program Files\Intel\iCLS Client;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\GtkSharp\2.12\bin;C:\Program Files\OpenVPN\bin;C:\TDM-GCC-64\bin;C:\Users\Daffa Abiyyu\AppData\Local\Microsoft\WindowsApps
Starting debugger: C:\Program Files (x86)\CodeBlocks\MINGW\bin\gdb.exe -nx -fullname -quiet -args C:/Users/DAFFAA~1/DOCUME~1/STRUKT~1/STACK5~1/bin/Debug/STACK5~1.EXE
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Debugger name and version: GNU gdb (GDB) 7.6.1
Continuing...
Child process PID: 1304
[Inferior 1 (process 1304) exited normally]
Debugger finished with status 0


So, I would say it's not the variables being uninitialized.

Well, I tried to narrow the code problem into these areas :
C:
string I2S(int i)
{
    string s;
    if (i!=0)
    {
        while(i!=0)
        {
            s = (char) ((i%10)+'0') + s;
            i = i/10;
        }
    }
    else
    {
        s = ((char) (i)+'0');
    }
    cout << "Value is : " << s << endl;
    return s;
}

At the very least I uncovered the fact that this conversion fails for negative values completely (and I have no idea how to count negative values).

Also, I wonder how string.replace() actually works. Maybe I should use regex().

How it should work :


INPUT EX :
((2-5)-3)

OUTPUT EX :
-6
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
If you can use C++11 then use "std::to_string" from <string> instead of a custom I2S function. It will handle correct conversion including sign.

You might want to use <locale> to produce the output. This can produce a localized representation of the number, with correct sign placement and delimiters (eg 1,000.00 in UK/US and 1.000,00 in French/German). In theory this is the correct way to output numbers to a user.

If a string version of the number is not needed internally and is only intended for external printing then consider printing it directly to an output stream. Output streams automatically deal with localization and conversion of integers.

Code:
const int num = 42;
cout << num;
 
If you can use C++11 then use "std::to_string" from <string> instead of a custom I2S function. It will handle correct conversion including sign.

You might want to use <locale> to produce the output. This can produce a localized representation of the number, with correct sign placement and delimiters (eg 1,000.00 in UK/US and 1.000,00 in French/German). In theory this is the correct way to output numbers to a user.

If a string version of the number is not needed internally and is only intended for external printing then consider printing it directly to an output stream. Output streams automatically deal with localization and conversion of integers.

Code:
const int num = 42;
cout << num;

Truly appreciate the help. I will take a look in the to_String that you mentioned, Doctor.

stringstream - C++ Reference

Apart from that - no description, no comments. Good job.

Thanks for the link, I will take a look further into it.

Marked about that, sorry. I was too focused on getting it to work that I forgot to properly place comments to help me.
---
I rewrote the code and it seemed to properly working now. Though I see improvements such as the to_String function. Might post the latest code later.
 
Might be useful for those who came across this thread someday. Here's a full code of how I do it. I know there are better ways, but for now, at least IT WORKS.
Code:
#include <iostream>
#include <stack>
#include <string>
#include <string.h>
#include <stdio.h>
char opr[4] = {'+','-','*','/'};
char num[10] = {'0','1','2','3','4','5','6','7','8','9'};
using namespace std;
void LevelControl(int lvl, int pos)
{
    if (lvl>=0)
        cout << lvl;
    else if (lvl==-1)
        cout << endl << "Over-closed Parenthesis at column " << pos << endl;
    else if (lvl==-2)
        cout << endl << "Ending has insufficient parenthesis!" << endl;
}
bool ArePair(char opening, char closing)
{
    if (opening == '(' && closing == ')') return true;
}
bool ParBalance(string data,bool control)
{
    stack<char> S;
    int level=0,i;
    for (i=0;i<data.length();i++)
    {
        if (data[i]=='(')
        {
            S.push(data[i]);
            level++;
        }
        else if (data[i]==')')
        {
            if(S.empty() || !ArePair(S.top(),data[i]))
            {
                if (control==true)
                    LevelControl(-1,i+1);
                return false;
            }
            else
            {
                level--;
                S.pop();
            }
        }
        if (control==true)
            LevelControl(level,i+1);
    }
    if (S.empty()==false && control==true) LevelControl(-2,i+1);
    return S.empty() ? true:false;
}
string ParReBal(string data)
{
    stack<char> S;
    int i;
    for (i=0;i<data.length();i++)
    {
        if (data[i]=='(')
        {
            S.push(data[i]);
        }
        else if (data[i]==')')
        {
            S.pop();
        }
    }
    if (S.empty()==false)
        data.append(")");
    return data;
}
void ValReport(int i)
{
    cout << endl << "Error in equation at column " <<i;
}
bool Valid(string data)
{
    for(int i=1;i<data.length();i++)
    {
        for(int j=0;j<4;j++)
        {
            for(int k=0;k<4;k++)
            {
                if (data[i]==opr[j] && (data[i-1]==opr[k] || (i>1 && data[i-2]==opr[k] && data[i-2]!=opr[1])))
                {
                    ValReport(i);
                    return false;
                }
            }
        }
    }
    return true;
}
string toString(int x)
{
    string s;
    bool neg = false;
    if (x==0)
    {
        s = (char) ((0) + '0');
        return s;
    }
    if (x<0)
    {
        neg = true;
        x*=-1;
    }
    while (x>0)
    {
        s = (char) ((x%10) + '0') + s;
        x/=10;
    }
    if (neg)
    {
        s = '-' + s;
    }
    return s;
}
string CountData(string data)
{
    //cout << "Evaluating : " << data << endl;
    int i,j,alpha=0,beta=0,res=0;
    char op;
    bool isOpFill = false, alphaNeg = false, betaNeg = false;
    for (i=0;i<data.length();i++)
    {
        if (data[i]==opr[1])
        {
            if (alpha==0 && alphaNeg==false)
            {
                alphaNeg = true;
                continue;
            }
            if (beta==0 && isOpFill == true)
            {
                betaNeg = true;
                continue;
            }
        }
        for (j=0;j<10;j++)
        {
            if (data[i]==num[j])
            {
                if (!isOpFill)
                    alpha = alpha*10 + j;
                else
                    beta = beta*10 + j;
            }
        }
        for (j=0;j<4;j++)
        {
            if (data[i]==opr[j])
            {
                op = opr[j];
                //cout << op << endl;
                isOpFill = true;
            }
        }
    }
    if (alphaNeg)
        alpha*=-1;
    if (betaNeg)
        beta*=-1;
    switch (op)
    {
        case '+' : res = alpha + beta;break;
        case '-' : res = alpha - beta;break;
        case '*' : res = alpha * beta;break;
        case '/' : res = alpha / beta;break;
        default : res = alpha + beta;break;
    }
    cout << alpha << op << beta << " = " << res << endl;
    getchar();
    data.erase();
    data = toString(res);
    //cout << data << endl;
    getchar();
    return data;
}
void ShowStack(string datapiece)
{
    int i, x;
    stack <char> S;
    cout << "Current Stack Form : " << endl;
    for (i=0;i<datapiece.length();i++)
    {
        S.push(datapiece[i]);
        cout << "Reading : " << datapiece[i] << endl;
        getchar();
    }
    cout << endl;
}
string FakeStack(string data)
{
    return "(" + data;
}
string CountAll(string data)
{
    int i,istart,iend;
    stack <char> S;
    string tempdata;
    data = ParReBal(data);
    //cout << "Current Form : " << data << endl;
    for (i=0;i<=data.length();i++)
    {
        //cout << "Position : " << i << " " << data[i] << endl;
        if (data[i]=='(')
        {
            S.push(i);
        }
        if (data[i]==')')
        {
            istart = S.top();
            iend = i-S.top();
            //cout << iend << endl;
            tempdata = data.substr(0,iend+istart);
            ShowStack(tempdata);
            cout << "Evaluating : " << tempdata << endl;
            tempdata = data.substr(istart,iend);
            tempdata = CountData(tempdata);
            iend++;
            data.replace(istart,iend,tempdata);
            S.pop();
            break;
        }
    }
    if (!S.empty())
    {
        while (!S.empty())
        {
            S.pop();
        }
        return CountAll(data);
    }
    else
    {
        data = FakeStack(data);
        ShowStack(data);
        cout << "Evaluate : " << data.substr(istart,iend) << endl;
        data = tempdata;
        return data;
    }
}
bool isDataAtZero(string data)
{
    stack<char> S;
    int i;
    for (i=0;i<data.length();i++)
    {
        if (data[i]=='(')
        {
            S.push(i);
            continue;
        }
        else if (data[i]==')')
        {
            S.pop();
            continue;
        }
        if (S.size()==0)
        {
            return true;
        }
    }
    return false;
}
int main()
{
    //char input[70];
    string data, tempdata;
    cout << "Input : " << endl;
    //cin.getline(input, sizeof(input));
    //data = input;
    getline(cin, data);
    if (ParBalance(data,true))
        {
            cout << endl << "Balanced" << endl;
            if (Valid(data))
            {
                cout << "Valid Equation" << endl;
                tempdata = data;
                if (data[0]!='(' || data[data.length()-1]!=')' || isDataAtZero(data))
                {
                    data.insert(0,"(");
                    data.insert(data.length(), ")");
                    cout << "To properly count the equation, the formula has been reformed into : " << data << endl << endl;
                }
                cout << "The final result is : " << CountAll(data);
            }
        }
    else
        cout << "Not Balanced" << endl;
    return 0;
}
 
Status
Not open for further replies.
Top