This program should help you understand the use of (char-mixed) input and list management.
Some students (as early as junior high or even as late as college) find reading assignment lists difficult. They see the teacher say something like 4-10 and do problem 4 and problem 10 — but not the other 5 assigned problems!
To help these poor lost souls, we'll write a program that can take in the (possibly) hyphenated assignment list and print back out a list of all problems assigned. Just in case, we'll also make sure our list is sorted (non-decreasing order) and contains no duplicates. (Yes, you must write your own sort function. You may NOT use the sort function from the algorithm standard library! Which of the sorts we learned in Chapter 6 is most appropriate for these circumstances?)
Here are some examples:
User Types In... | We Display... |
---|---|
L1 | Do problem 1 of L. |
L1-3 | Do problems 1, 2, and 3 of L. |
L1,2,5 | Do problems 1, 2, and 5 of L. |
L1-3,5 | Do problems 1, 2, 3, and 5 of L. |
L1-3,5-7 | Do problems 1, 2, 3, 5, 6, and 7 of L. |
L1-1,3-3,5-8 | Do problems 1, 3, 5, 6, 7, and 8 of L. |
L4-5,1-3,7-10 | Do problems 1, 2, 3, 4, 5, 7, 8, 9, and 10 of L. |
L4-5,1-3,7-10,8-12 | Do problems 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, and 12 of L. |
Let the problem set name be either a single character, a single word, or a quoted, space-containing string. The problem set name will always be entered first. If the user uses a quoted problem set name, allow them to use either a single quote (tick-mark) or double quote — but the open and close can be assumed to match. Spaces around the input should be optional (so "L1-3" should result in the same answer as "L 1 - 3"). All items/hyphenated groups are to be comma separated (so "L1,2,5" is okay but "L1 2 5" and "L125" are not). We'll assume that all problems are to be done for simplicity. (See the option below about evens vs. odds for more fun.) If the display of the problem list is longer than a line, wrap it gracefully — don't let the terminal window wrap it for you (or the printer will chop it off!).
In what data type can you store something like the problem set name that might be anything from one character to a whole bunch of text?
How can you detect that the problem set name is a quoted string? How can you read in the whole thing to a single variable? (Don't worry that the user has missed a close quote.)
If the user's problem set name is a quoted string, how can you remove the quotes from it? (Just like C++ won't leave your quotes on a string when it prints it, you shouldn't leave the user's quotes on their string. They are just there to separate the problem set name from the problem list.)
When placing items (say problem numbers?) into a list, how can you keep those items sorted from the beginning?
How can you avoid placing a duplicate item into a list? (Note: not how can you remove duplicates from a list — avoid having any duplicates in the list in the first place!)
If the problem list is long (like in math or physics), how can you wrap the long output line to multiple lines without too much difficulty? (Hint: The output line can be around 70-75 chars long, we saw in 121 how to tell how many digits long an integer is, we know we are outputting a comma and space between the problem numbers, and we know how many chars we are adding before the list and after the list. Just don't forget the 'and' before the last element. So, knowing all that, especially that you need to drop to a new line after every 70-ish chars you've output, how do you tell if total chars printed is 70*n?)
This assignment is (Level 4).
Add (Level 1.5) to allow a hyphenated range to be appended with 'odds', 'evens', or 'all' (if nothing is appended, assume 'all'). (If they say evens and have one/both ends odd, increment the odd start and/or decrement the odd end. Do similarly for 'odds' and even ends.)
How can you detect that there is a range-type appended or not? (Hint: What follows a range group whether labeled or not?) There are at least two ways to code this...
How can you detect that a number is even? (Hint: Recall that all even numbers are of the form 2*n for some whole number n.)
If something isn't even, what do we call it? (*grin*)
How can you skip the odd items in an 'evens' list (and vice-versa)? (Hint: For an 'all' list, you are going to each and every number — one right after the other. But in an 'evens' or 'odds' list, you are going to every other number — skipping from one to the one after the next.)
Add (Level 1) to additionally allow 'alt odds' or 'alt evens' to be appended as a range-type to a hyphenated group. (These mean 'alternating odds' and 'alternating evens' respectively, btw.) So, a group stated as "5-17 alt odds" would mean "5, 9, 13, 17". (If you are alternating and don't hit the end specified but rather pass it, simply stop anyway — don't worry that the end was left missing. So "5-19 alt odds" would have the same effect as the previous example — the 19 would be missed as we went from 17 to 21 and so we'd just stop — adding neither 19 nor 21 to the list.)
(Note: Since it says "to additionally allow", this option assumes you've already done the first option about 'evens' vs. 'odds'. So the hinting questions above should either already be clear or help here, too.)
Add (Level 1) to change the original assumption that a range was all problems between the end-points to reflect the ends of the range — assume 'evens' if both ends are even, 'odds' if both ends are odd, or 'all' if the ends are odd/even (or vice-versa). (Hint: The even detection question and the skipping question on the first option are helpful here, too...maybe you should answer them here if you skipped that option.)
Add (Level 1) to make a menu with an option so the user can set an assumption type for non-labeled ranges: 'all', 'odds', 'evens', or 'detect'. (Note: This option effectively includes the third option above — so you get its level, too. Also, this option has much in common with the first option and you might want to just finish that out for that level. But, at the very least, you can learn from reading it and answering the questions.) Oh, the other menu options would be 'enter problem set to list' and 'quit' or something similar.
Add (Level 2) to make a menu with options so the user can choose to go from a (possibly) hyphenated list to a plain list or vice-versa. In 'vice-versa', assume 'all' for ranges. (Don't forget a 'quit' option.)
When going 'vice-versa', how can you detect that a range is occurring in your list and compress it to a pair of hyphen-separated end-points? (Hint: What's the gap between numbers in an 'all' range?)
Add (Level 2) to not just locate 'all' ranges in the 'vice-versa' option above, but also 'evens' and 'odds' ranges. Be sure to label all ranges appropriately!
When going 'vice-versa', how can you detect that a range occurring in your list is 'evens' or 'odds'? (Hint: What's the gap between numbers in these types of ranges?)
How can you detect that an end of such a range is even? (Hint: Recall that all even numbers are of the form 2*n for some whole number n.)
If something isn't even, what do we call it? (*grin*)
(You needn't answer this question again if you did the first option.)
Add (Level 1) to additionally locate ranges of the 'alt evens' and 'alt odds' types when going 'vice-versa'. Of course, label these ranges appropriately, too. (Note that this option assumes you've done the previous option of detecting 'evens' and 'odds' type ranges.)