如何在括号中重复一个字符串“()”括号前的数字 [英] How can I repeat a string in parenthesis "()" by the number before the parenthesis
问题描述
我想解决这个问题,但我相信我已经错误地想到了如何获得正确的结果。
最初我计划在试图做这样的事情:
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屋!