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.

5
  • std::string has an insert method en.cppreference.com/w/cpp/string/basic_string/insert Commented Mar 14, 2014 at 0:01
  • how will I insert it based on the given? I really don't have an idea how will I implement it. Commented Mar 14, 2014 at 0:02
  • Hint: search for tokenizing and parsing (recursive descent parser, parser generator). Commented Mar 14, 2014 at 0:04
  • Shouldn't it be (((x+y)*z)-a)/b or at the max be ((((x+y)*z)-a)/b), why do you need a pair of parenthesis around x? Commented Mar 14, 2014 at 0:12
  • it can be ((((x+y)*z)-a)/b) . how do I do it? Commented Mar 14, 2014 at 0:38

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

@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.
I can't understand the pointer thingy. can you show me how please?
@jm- Here is a link to an answer that shows you how to reverse a string in place.
thanks. there's a problem though. using your algorithim will give ((((x =x + y)-z)*a)/b);
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;
}

3 Comments

I can't use vectors though
The standard template library is, aptly put, standard. I can see no reason why you cannot. If you must not - then build your own: cs.sfu.ca/CourseCentral/125/tjd/vector_example.html
@jm- also, if this is a homework problem, it is respectful to mark your stackoverflow question accordingly; i.e. add the homework tag.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.