如何在括号中重复一个字符串“()”括号前的数字 [英] How can I repeat a string in parenthesis "()" by the number before the parenthesis

查看:99
本文介绍了如何在括号中重复一个字符串“()”括号前的数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想解决这个问题,但我相信我已经错误地想到了如何获得正确的结果。



最初我计划在试图做这样的事情:



I am trying to figure this out but I believe I have went about it with the wrong idea of how to get the right result.

Initially I planned on trying to do something like this:

std::string patterns::xPlode(std::string sOrig, int endsOrig){
	std::string holder = "";
	std::string finishedXplode = "";
	int origEnds = endsOrig;
	std::string Orig = sOrig;
	std::string holder2 = "";
	int paren1num = 0;
	int paren2num = 0;
	int paren3num = 0;
	std::string paren1 = "";
	bool paren1closed = false;
	std::string paren2 = "";
	bool paren2closed = false;
	std::string paren3 = "";
	bool paren3closed = false;
	static std::regex reg1("[0-9]+");
	std::string cOrig = Orig.c_str();
	int repeatsComplete = 0;
	int numSci = 0;

	for (int i = 0; i < ((origEnds / cOrig.size()) + 1); i++){
		holder += Orig;
	}

	for (int i = 0; i < holder.length(); ++i){
		if (isdigit(holder.at(i))){
			if (!paren1closed){
				if (paren1num > 0){
					if ((0 <= holder.at(i)) && (holder.at(i) >= ((_MAX_INT_DIG - 9) / 10))) {
						paren1num = (paren1num * 10) + holder.at(i);
						break;
					}
					else{
						puts("ERROR _ OVERFLOW!!! err:1001");
						break;
					}
				}
				else{
					paren1num = (int)holder.at(i);
					break;
					}
				}
			}
			else if (!paren2closed){
				if (paren2num > 0){
					if ((0 <= holder.at(i)) && (holder.at(i) >= ((_MAX_INT_DIG - 9) / 10))) {
						paren2num = (paren2num * 10) + holder.at(i);
						break;
					}
					else{
						puts("ERROR _ OVERFLOW!!! err:1002");
						break;
					}
				}
				else{
					paren2num = (int)holder.at(i);
					break;
				}
			}
			else if (!paren3closed){
				if (paren3num > 0){
					if ((0 <= holder.at(i)) && (holder.at(i) >= ((_MAX_INT_DIG - 9) / 10))) {
						paren3num = (paren3num * 10) + holder.at(i);
						break;
					}
					else{
						puts("ERROR _ OVERFLOW!!! err:1003");
						break;
					}
				}
				else{
					paren3num = (int)holder.at(i);
					break;
				}
		}
		else if (holder.at(i) == *"("){//if open parens
			if (!paren1closed){
				paren1closed = !paren1closed;

				break;
			}
			else if (!paren2closed){
				paren2closed = !paren2closed;
				break;
			}
			else if (!paren3closed){
				paren3closed = !paren3closed;
				break;
			}
		} 
		else if (holder.at(i) == *")"){ //if closed paren
			if (paren3closed){
				paren3closed = !paren3closed;

				break;
			}
			else if (paren2closed){
				paren2closed = !paren2closed;
				break;
			}
			else if (paren1closed){
				paren1closed = !paren1closed;
				break;
			}
		}

		// end WIP

	}


	cOrig = holder.c_str();
	for (int i = 0; i < origEnds; ++i){
		finishedXplode = finishedXplode + cOrig[i];
	}

	finishedPat = finishedXplode;
	return finishedXplode;
}





此处的代码尚未完成,因为我对我的逻辑有了第二个想法。我们的想法是遍历每个角色,并决定它是一个数字,还是打开或关闭括号,并将该信息保存到字符串中,使用数字重复括号中的内容。并且如果另一个陈述在括号内,则允许迭代。



例如:

2(ab)16(cd) 3(a4(bc)d)



等同于:

ABABCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDABCBCBCBCDABCBCBCBCDABCBCBCBCD



我知道代码很邋and,我对你们可以给我的每一个建议持开放态度,以帮助我们更好地学习C ++。



The code here is unfinished because I had second thoughts about my logic. The idea was to walk through each character and decide if it was a number, or open or close parenthesis and save that information into a string, using the number to repeat what is in the parenthesis. and alowing for iteration in the event that another statement is inside the parenthesis.

For example :
2(ab)16(cd)3(a4(bc)d)

would equate to :
ABABCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDABCBCBCBCDABCBCBCBCDABCBCBCBCD

I know the code is very sloppy, and I am open to every suggestion you guys can give me to help get better at C++.

推荐答案

我是编写递归下降解析器而不是基于正则表达式的东西。不可否认,正则表达式样式语法是描述问题部分的一种方便方法。



语法规则......



number = [0-9] +

literal = [AZ] +

expression = [literal | number'('expression')'] +



I'd write a recursive descent parser instead of something based on regular expressions. Admittedly, regex style syntax is a handy way to describe parts of the problem.

Grammar rules ...

number = [0-9]+
literal = [A-Z]+
expression = [ literal | number '(' expression ')' ]+

#include <string>

// I'll leave the scanner class to your imagination.

class Scanner
{
   // TODO
public:
    Scanner(const char *text);

    // Each of these functions returns true 
    // if a pattern is found. Matched input is 
    // "consumed" (index or cursor into the buffer 
    // advances). If the function returns false, 
    // nothing happens.

    // look for [0-9]+
    bool parseNumber(int &number);

    // look for [A-Z]+
    bool parseLiteral(std::string &literal);

    // look for single character eg. '(' or ')'
    bool parseMatch(char text);

    // returns true of no more text to consume.
    bool empty() const;
};







#include <string>
#include <stdio.h>
#include "Scanner.h"

// recursive descent parser
static bool parseExpression(Scanner &buffer, std::string &output)
{
    int number = 0;
    while ( !buffer.empty() )
    {
        std::string nested;
        if ( buffer.parseLiteral(nested) )
        {
           output.push_back(nested);
        }
        else if ( buffer.parseNumber(number)
        {
            if ( buffer.parseMatch('(') && 
                parseExpression(buffer, nested) && // recursive
                buffer.parseMatch(')')
            {
                while (number > 0)
                {
                    output.push_back(nested);
                    number--;
                }
            }
            else
            {
                return false;
            }
        }
        else 
            return false;
    }
    return true;
}

// unit test
int main(int argc, char *argv[])
{
    for (int i = 1; i < argc; i++)
    {
        Scanner buffer(argv[i]);
        std::string result;
        if ( parseExpression(buffer, result) )
            printf("Result: %s\n", result.c_str());
        else
            printf("Error parsing %s\n". argv[i]);
    }
    return 0;
}


我认为这里的关键是递归。

解决语法的嵌套部分(处理重复,和大写的小细节,留下了一个练习;-)),我们可以写的


I think the key here is recursion.
Addressing the nested part of your grammar (handling repetition, and minor details like uppercase, is left has an exercise ;-) ),
we can write:
expr :=   num '(' left expr right ')' 
        | empty;



其中 num 是一个(一个或多个)数字的序列,而是(零个或多个)字母的序列。



我们可以写下面的代码:




where num is a sequence of (one or more) digits while left and right are sequences of (zero or more) letters.

We may write something like the following code:

// expr = num '(' left expr right ')' | empty

#include <iostream>
using namespace std;

struct Exc
{
  string msg;
  size_t pos;
};


bool get_num( const string & input, size_t & pos, size_t & num )
{
  num = 0;
  bool result = false;
  while ( pos < input.length() && input[pos] >= '0' && input[pos] <= '9')
  {
    result = true;
    num = num * 10 + (input[pos] - '0');
    ++pos;
  }
  return result;
}

bool get_lbrace( const string & input, size_t & pos )
{
  if ( pos >= input.length() || input[pos] != '(') return false;
  ++pos;
  return true;
}

bool get_rbrace( const string & input, size_t & pos )
{
  if ( pos >= input.length() || input[pos] != ')') return false;
  ++pos;
  return true;
}

bool get_alpha( const string & input, size_t & pos, string & alpha)
{
  bool result = false;
  alpha = "";
  while ( pos < input.length() && input[pos] >='a' && input[pos] <='z')
  {
    result = true;
    alpha += input[pos];
    ++pos;
  }
  return result;
}

void expr( string & input, size_t & pos)
{
  size_t num;
  string left = "";
  string right = "";
  if ( ! get_num( input, pos, num )) return;
  size_t bkpos = pos;
  for (size_t n=0; n<num; ++n)
  {
    pos = bkpos;
    if ( ! get_lbrace( input, pos ))
    {
      Exc exc = {"missing left brace", pos};
      throw exc;
    }
    get_alpha( input, pos, left );
    cout << left;
    expr(input, pos);
    get_alpha(input, pos, right);
    cout << right;
    if ( ! get_rbrace( input, pos))
    {
      Exc exc = {"missing right brace", pos};
      throw exc;
    }
  }
}


int main()
{
  string myexpr = "12(a3(b2(ywz))c)";
  size_t pos = 0;
  try
  {
    expr( myexpr, pos);
  }
  catch( Exc exc )
  {
    cerr << endl << exc.msg << " at " << exc.pos <<  endl;
  }
  cout << endl;
}


这篇关于如何在括号中重复一个字符串“()”括号前的数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆