2

I have this part of code:

char statement[255];
string result = ""; //or you can use result[299] too 
cin.getline(statement,255);
/*
I don't know the code to be inserted here
*/
cout<<statement<<endl;
/*or cout<<result<<endl;*/

now, what I want to do is this:

if user inputted x = x + y * z - a / b ;, I want the output to be x = ((((( x ) + y ) * z ) - a ) / b) ;

how can I insert those parentheses into the original input? thanks. by the way, I really need to store it in a new array or a string. I just don't know how to insert those parentheses.

Wanna Coffee
  • 2,742
  • 7
  • 40
  • 66
jm-
  • 50
  • 1
  • 5

2 Answers2

2

Rather than inserting new items into the original input, you could write into a different array starting from the back.

  • When you see a semicolon or an operator, add a closing parentheses after it
  • Every time you insert a closing parentheses, increment count variable by one
  • Otherwise, copy the character into the output
  • Once you reach the = sign, insert count opening parentheses before it
  • Produce the final output by reversing the string

If you follow this algorithm, the intermediate output will look like this:

;)b/)a-)z*)y+)x(((((=x

This data goes into a separate char array or in an std::string.

When you reverse it, the output becomes what you want:

x=((((x)+y)*z)-a)/b);

You can write the reversed data back into the original buffer if you wish.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • @jm- Make two indexes (or pointers if you prefer), one pointing at the beginning of the target buffer, and another pointing at the end of the source buffer. Move the indexes (pointers) in a single loop in the opposite directions, copying characters from the source to the target. – Sergey Kalinichenko Mar 14 '14 at 01:06
  • I can't understand the pointer thingy. can you show me how please? – jm- Mar 14 '14 at 01:19
  • @jm- Here is a [link to an answer](http://stackoverflow.com/a/199891/335858) that shows you how to reverse a string in place. – Sergey Kalinichenko Mar 14 '14 at 01:22
  • thanks. there's a problem though. using your algorithim will give ((((x =x + y)-z)*a)/b); – jm- Mar 14 '14 at 02:24
0

Sometimes I get carried away. I'm not sure how this code is helpful, but it'll wrap in the manner you demonstrate.

string PopNextField(string& input)
{
  // skip whitesapce
  while (input.length() > 0)
  {
    if (!::isspace(input.front()))
      break;

    input = input.substr(1);
  }

  string result = "";

  // read to end
  while (input.length() > 0)
  {
    if (::isspace(input.front()))
      break;

    // type switch
    if (
         result.length() != 0 && 
         (::isalnum(input.front()) != ::isalnum(result.front()))
       )
      break;

    result += input.front();
    input = input.substr(1);
  }

  return result;
}

bool FieldIsOperator(string field, const vector<string>& ops)
{
  for (auto it = ops.begin(); it != ops.end(); it++)
    if (*it == field)
      return true;

  return false;
}

bool FieldIsEnd(string field)
{
  return field == ";";
}

vector<string> ParseFields(string& input)
{
  vector<string> fields;

  while (input.length() > 0)
  {
    string field = PopNextField(input);
    if (field.length() > 0)
      fields.push_back(field);
  }

  return fields;
}

string AddParens(string input, const vector<string>& opprec)
{
  vector<string> fields = ParseFields(input);
  string result = "";

  // if field size is one, don't wrap
  if (fields.size() == 1)
  {
    return fields.front();
  }

  for (auto it = fields.begin(); it != fields.end(); it++)
  {
    string next = *it;

    if (FieldIsOperator(next, opprec))
    {
      result += " " + next;
    }
    else if (FieldIsEnd(next))
    {
      result += next;
    }
    else
    {
      result = "(" + result + next + ")";
    }
  }

  return result;
}

int main()
{
  vector<string> opprec;
  opprec.push_back("(");
  opprec.push_back(")");
  opprec.push_back("*");
  opprec.push_back("/");
  opprec.push_back("+");
  opprec.push_back("-");

  string input = "x = x + y * z - a / b ;";
  string result = "";

  string remainingInput = input;
  // split assignments
  while (remainingInput.length() > 0)
  {
    auto nextAssignmentIndex = remainingInput.find("=");
    string nextInput = remainingInput.substr(0, nextAssignmentIndex);


    result += AddParens(nextInput, opprec);
    if (nextAssignmentIndex != string::npos)
    {
      result += "=";
      remainingInput = remainingInput.substr(nextAssignmentIndex + 1);
    }
    else
    {
      break;
    }
  }

  cout << "Input: " << input << endl;
  cout << "Result: " << result << endl;

  cin.get();

  return 0;
}
payo
  • 4,501
  • 1
  • 24
  • 32
  • I can't use vectors though – jm- Mar 14 '14 at 01:03
  • The standard template library is, aptly put, standard. I can see no reason why you cannot. If you must not - then build your own: http://www.cs.sfu.ca/CourseCentral/125/tjd/vector_example.html – payo Mar 14 '14 at 03:05
  • @jm- also, if this is a homework problem, it is respectful to mark your stackoverflow question accordingly; i.e. add the `homework` tag. – payo Mar 14 '14 at 03:13