-
Notifications
You must be signed in to change notification settings - Fork 1
CfgStringRandomizer
CfgStringRandomizer is a string randomizer based on context free grammar. If you need a simpler randomizer, check StringRandomizer
To begin, you have to include
#include "tcrand/string.hpp"
This will enable StringRandomizer and CfgStringRandomizer class. Next, you can create your randomizer object as follow:
tcrand::CfgStringRandomizer cfg_rand;
In CfgStringRandomizer, you have to define your grammar by calling method rule
above.
C is a char
that defines your left-hand production variable. P is a string or StringRandomizer that will replace C. Note that C will be a non-terminal symbol, i.e. C won't appear in your resulting string unless you define a nonterminal production rule with StringRandomizer (see below).
Suppose you need to set a grammar rule
A -> XY
You can call cfg_rand.rule('A', "XY");
Additionally, you can set P as a StringRandomizer. By doing this, C will be replaced by a random string generated from P. This string is terminal, even if the resulting string may contain any replaceable character. You can see an example of this in the example section.
Next, you also need to define your starting string S. GrammarRandomizer will start from S and randomly replace any symbol that has been defined before.
This method is optional, but useful if you want to set the length of your resulting string to be as close as possible, but always less or equal to L. This is specifically useful if your grammar contains recursions.
Suppose that you want to create a string that constists of '()' where they make a valid bracket sequence, i.e. as in [this problem] (http://amrita2016.cloudcontest.org/public/problem.php?id=33)
You can achieve that by doing:
CfgStringRandomizer brackets;
brackets.rule('S' , "SS");
brackets.rule('S' , "(S)");
brackets.rule('S' , "");
brackets.start_with("S");
cout<<brackets.max_length(10).next()<<endl;
cout<<brackets.max_length(14).next()<<endl;
cout<<brackets.max_length(18).next()<<endl;
cout<<brackets.max_length(30).next()<<endl;
This will produce an output:
(()(()))
(()())(()())
()((()(())))(())
(()())(()())(())(()())()(())
A more complex example that generates valid math equation:
StringRandomizer number_str, operator_str;
number_str.charset("[0-9]").first_charset("[1-9]").length(1, 6);
operator_str.charset("[+*-]").length(1);
CfgStringRandomizer math_grammar;
math_grammar.rule('N' , "(N O N)");
math_grammar.rule('N' , number_str);
math_grammar.rule('O' , operator_str);
math_grammar.start_with("N");
math_grammar.max_length(100);
cout<<math_grammar.next()<<endl;
cout<<math_grammar.next()<<endl;
cout<<math_grammar.next()<<endl;
cout<<math_grammar.next()<<endl;
This will produce:
((((381 - 90) + 762242) - (3 * (((96328 + 48678) * (467 * 1618)) * 4))) - ((81 - 52) * 535))
(((((31 * 5) + (1520 - 14)) + 45) - (((((8 * 422827) - 14) * (3 * 938)) + 80184) - 2086)) * 13740)
((((34423 - 56405) + 3) * 3484) * ((90198 + ((4 * 6787) + 8052)) - (((81 + 6) - 26) - 103985)))
((91 * 2732) * (((9 + (733 + 9184)) + (70 - 6077)) * (646808 - (((8 + 458) + 22233) + 29412))))