Skip to content

CfgStringRandomizer

afaji edited this page Mar 20, 2017 · 1 revision

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;

Defining your grammar

rule(C , P)

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.

start_with(S)

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.

max_length(L)

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.

Example

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))))
Clone this wiki locally