Here are a few questions to help you clarify your understanding of managing lists of data in C-style arrays.
A list in a C/C++ program is commonly stored in an array type variable. Thankfully, we can make a list of almost any type of information — anything except void. The tricky part is that we must remember to make our list variable large enough to hold all the data we expect the user to have. If we don't, we run the risk of running out of room during the program.
When managing such a variable as a list of data, we must take care of common list tasks for ourselves. These tasks include inserting a new item into the list, removing an item from a list, printing out the list for the user to see, and searching for items' presence within the list.
Show how to declare a variable to hold a list of double values. Assume (for sake of size) that this list will hold scores for students in CSC122 on a particular test. (Tip: How can we keep track of the number of currently used positions in the list?)
constexpr size_t MAX_SCORES{30}; double scores[MAX_SCORES]; size_t scores_entered{0};
Show code to print all of the elements of the list called species_names on the screen. (Hint: What type of data would names likely be?) Be sure to number your list for the user's convenience.
for (size_t p = 0; p != species_names_used; ++p) { cout << p+1 << ") " << species_names[p] << '\n'; }
When the user enters their selection from a list, the list they are referencing (from your screen display — for example — as above) is numbered from 1 (one). However, the list we have stored in our program is considered numbered from 0 (zero). To adjust for this discrepancy, we should subtract one from the user's entry before using it to access part of the list.
Of course, before using any user choice to subscript into a list stored in an array, we should validate it against the list's current used counter (namely that it is less than this). We would normally make sure it is greater than or equal to 0 (zero), as this is the smallest subscript/index that is allowed for an array, but we're using the size_t data type which is unsigned and so we won't have to worry about that.
Show code needed to insert a new long integer (currently stored in the variable popul) into the long integer list called species_populations. Place the new value into the position the user refers to as 5.
bool okay{false}; target--; // decrement the 5 to get array position if ( target < species_populations_used ) { species_pupulations[target] = popul; okay = true; } // okay is true or false depending on success of the 'insertion'
Show code needed to insert a new long integer (currently stored in the variable popul) into the long integer list called species_populations. Place the new value in front of the position the user refers to as 5. (Hint: What happens to those positions that used to be located in 5 and beyond?) (Hint 2: Is there anything special you need to check for before inserting the new item?)
bool okay{species_populations_used != MAX_SPECIES_POPULATIONS}; if ( okay ) { target--; // decrement the 5 to get array position if ( target == species_populations_used ) { species_populations[target] = popul; ++species_populations_used; } else { for ( auto pos{species_populations_used}; pos > target; --pos ) { species_pupulations[pos] = species_pupulations[pos-1]; } species_pupulations[target] = popul; } } // okay is true or false depending on success of the insertion
Show code needed to insert a new long integer (currently stored in the variable popul) into the long integer list called species_populations. Place the new value at the end of the list. (Hint: Is there anything special you need to check for before inserting the new item?)
bool okay{species_populations_used != MAX_SPECIES_POPULATIONS}; if ( okay ) { species_populations[species_populations_used] = popul; ++species_populations_used; } // okay is true or false depending on success of the insertion
Show code needed to insert a new long integer (currently stored in the variable popul) into the long integer list called species_populations. Place the new value in the front of the list. (Hint: What happens to the data currently in your list's positions?) (Hint 2: Is there anything special you need to check for before inserting the new item?)
bool okay{species_populations_used != MAX_SPECIES_POPULATIONS}; if ( okay ) { // target is 0 for front of list, but, just to be safe... if ( target == species_populations_used ) { species_populations[target] = popul; ++species_populations_used; } else { for ( auto pos{species_populations_used}; pos > target; --pos ) { species_pupulations[pos] = species_pupulations[pos-1]; } species_pupulations[target] = popul; } } // okay is true or false depending on success of the insertion
Briefly explain why it is necessary to move data during an insertion operation. For example, if you wanted to insert q in front of the r in the list below, what would need to move? Why need they move?
+-----+-----+-----+-----+-----+-----+-----+ | a | k | m | n | r | t | w | +-----+-----+-----+-----+-----+-----+-----+
r, t, and w would need to move to the right to make room for the q to be inserted. If we don't move them over, we'd overwrite the r and it would be lost.
If the list above was at its maximum capacity, how might you handle the insertion request?
Print a message telling them of the issue and then move on ignoring the request.
Show code to remove an item from the list called research_sites. The user says the item is in position 12. (Hint: Is there anything special you should check before you remove a list item?) (Hint 2: What happens to any elements that once followed position 12?)
// if the user wants to remove 12, then we need to remove 11 -- one off // due to the 1-based shift // assume remove_this is 11 and keep_this is 12 -- one more than the // position 11 that is to be removed size_t count; keep_this = keep_this > research_sites_used ? research_sites_used : keep_this; bool okay{keep_this >= remove_this}; // since keep_this is already // <= research_sites_used, // transitivity will protect // remove_this, too count = keep_this - remove_this; if ( okay && count > 0 ) { for ( auto pos{keep_this}; pos < research_sites_used; ++pos ) { research_sites[pos-count] = research_sites[pos]; } research_sites_used -= count; } // okay is true or false depending on success of the removal
Show code to remove an item from the list called research_sites. The item is at the end of the list. (Hint: Is there anything special you should check before you remove a list item?)
bool okay{research_sites_used > 0}; if ( okay ) { --research_sites_used; } // okay is true or false depending on success of the removal
Show code to remove an item from the list called research_sites. The item is at the head (beginning) of the list. (Hint: Is there anything special you should check before you remove a list item?) (Hint 2: What happens to any elements that once followed this one?)
// assume remove_this is 0 and keep_this is 1 -- one more than the // position 0 that is to be removed size_t count; keep_this = keep_this > research_sites_used ? research_sites_used : keep_this; bool okay{keep_this >= remove_this}; // since keep_this is already // <= research_sites_used, // transitivity will protect // remove_this, too count = keep_this - remove_this; if ( okay && count > 0 ) { for ( auto pos{keep_this}; pos < research_sites_used; ++pos ) { research_sites[pos-count] = research_sites[pos]; } research_sites_used -= count; } // okay is true or false depending on success of the removal
Show code to remove a sequence of items from the list called research_sites. The items are at positions [5..8] in the list (as a programmer would see it). (Hint: Is there anything special you should check before you remove a list item?) (Hint 2: What happens to any elements that once followed these?) (Hint 3: can you make this operation more efficient by knowing you are removing a contiguous sequence?)
// assume remove_this is 5 and keep_this is 9 -- one more than the // position 8 that is to be removed size_t count; keep_this = keep_this > research_sites_used ? research_sites_used : keep_this; bool okay{keep_this >= remove_this}; // since keep_this is already // <= research_sites_used, // transitivity will protect // remove_this, too count = keep_this - remove_this; if ( okay && count > 0 ) { for ( auto pos{keep_this}; pos < research_sites_used; ++pos ) { research_sites[pos-count] = research_sites[pos]; } research_sites_used -= count; } // okay is true or false depending on success of the removal
What do you do if the user wants to remove an item from a list that is already empty?
Print a message telling them of the issue and then move on ignoring the request.