A set is a sequence of comma separated elements enclosed in square brackets.
An element for a set can be an alpha-numeral or another set. Furthermore, the elements can be of different types. White space is ignored.
Examples of a few sets are as follows:
{1,2,3}
{a,b,c}
{{1,2},{3}}
{{}}
{{1,2,3}}
{1,a,{2,b}}
My current objective is to have a program that takes some input and reports to output whether that input produces a set.
The grammar for a set is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
Set:
"{" Sequence "}"
Sequence:
<Empty>
List
List:
Element
Element "," List
Element:
Alpha-numeral
Set
*/
The code is as follows: (Scroll to the bottom and start with set())
bool set(std::istream& in = std::cin);
bool element(std::istream& in = std::cin) {
//an element is a letter, number, or set
char ch;
in >> ch;
if(isalpha(ch)) {
returntrue;
}
if(ch == '.' || isdigit(ch)) {
//ch is a number, go ahead and read the entire number
in.unget();
double val;
in >> val;
returntrue;
}
//not a number or letter, hopefully this element is a set
in.unget();
return set(in);
}
bool list(std::istream& in = std::cin) {
//a list is an element or an element "," list
if(!element(in)) {
returnfalse;
}
char ch;
in >> ch;
if(ch == ',') { //does the list continue?
return list(in);
}
//no comma, either the only or last element in the list
in.unget();
returntrue;
}
bool sequence(std::istream& in = std::cin) {
//a sequence is either the empty set or a list
char ch;
in >> ch;
if(ch == '}') {
//empty set found
in.unget();
returntrue;
}
in.unget();
return list(in);
}
bool set(std::istream& in) {
//a set is formatted as "{" Sequence "}"
char ch;
in >> ch;
//every set must begin with a "{"
if(ch == '{' && sequence(in)) {
in >> ch;
return ch == '}';
}
returnfalse;
}
My current dilemma is that input such as...
{{}}}
{{}}}}}
{1,2,3}a
is considered a set. That is, even if there are characters trailing a proper set the program still recognizes the entire input as a set.
An element for a set can be an alpha-numeral or another set ... objective is to have a program that takes some input
Since the program determines how input is read into it you can set up a std::deque<std::deque<std::string>> and read into it as shown in the following program, using comma-separated braces as set element delimiters. If you want to proceed with using this program I'd suggest:
(a) breaking up the code into smaller functions and de-cluttering main(),
(b) as errors might happen during entering set elements adding a pop_back to the mySet container as part of the menu
(c) input validation at std::cin level
(d) if you further want to use the data particularly the numeric data then consider converting them into int/double etc from std::string
1. Enter set element 2. Quit
1
a. Enter sub element b. Element complete, quit
a
Set sub element argument
1
a. Enter sub element b. Element complete, quit
b
1. Enter set element 2. Quit
1
a. Enter sub element b. Element complete, quit
a
Set sub element argument
2
a. Enter sub element b. Element complete, quit
a
Set sub element argument
b
a. Enter sub element b. Element complete, quit
b
1. Enter set element 2. Quit
2
{{1},{2,b}}
Process returned 0 (0x0) execution time : 27.748 s
Press any key to continue.
OP: you could also have a struct Element for each element of the set with a ctor overload that'd query the size of each element and read data directly into the corresponding std::vector<std::string>.
Here's an outline: