@CollinsLainzo,
I empathize with beginners. What @JLBorges presented is a modern C++ implementation, but it isn't actually complicated. There can be more familiar ways of doing this to beginners, but what you'll learn as you progress forward is that code like that presented by @JLBorges is actually more compact and less complicated than using simpler approaches which actually require more code.
To be clear, it is likely best to use arrays or some form of container like them (vectors come to mind).
@JLBorges took the interesting step of including links to documentation. There's a message for all students in this choice, and it's important. You are going to have to become accustomed to referencing the documentation on the language features, in any language, for as a long as write software. I've done this for over 40 years, and largely because of the evolution of these languages, and because new languages emerge, I may have at any one moment over 20 tabs in browsers on pages of the documentation. Especially when a new version is released (which is every 2 years now with C++).
That said, a walk through and interpretation of what's shown would likely suffice for what you require.
Note the NDIGITS = 15. This is constexpr, which is modern C++, but you could use
const unsigned int NDIGITS = 15;
It would have a similar effect, and would work on older compilers. It establishes a constant value defining the limit of the number of digits you've prescribed.
Skip is_valid for a moment, I'll get back to it.
Move to main.
Main should start out familiar. The user can enter a string of digits.
@JLBorges uses is_valid to be sure the digits string is valid for the computation. One thing not shown here is how to loop to ask again if the input is invalid, and the option of an exit. That's a detail you can easily skip for many student programs, unless, of course, that is required for the assignment (and I see assignments often do).
So, let's focus on the meat of the work, the computed_checksum function. That's what you've requested, a type of checksum. The very formula you show (all those 3's and 7's) is a simple kind of checksum.
You'll notice the "is_valid" is used again here, and that may be redundant.
Now we come to the multipliers array. This is your list of 3's and 7's. In what is the modern style, it is declared where it is to be used (the subjects are related, so this is a good idea). It is declared constexpr, which is modern C++, but you may be more familiar with declaring this as a global int array, outside of a function. This works similarly (and you can exclude the constexpr if it is confusing for now).
This is the only array of integers used. The other 'array' is the string provided by the user. That comes up soon.
If you aren't sure about static_assert, for a student program you may skip this line. It simply tests at compile time that the length of the multipliers array is as expected. You may benefit from reading the documentation at those links.
Now, the for loop. This is the modern (C++11) means of looping through a standard container. 'str', being a string, is looped from beginning to end (automatically checking the end of the string in this form).
for( char &c : str ) c -= '0';
In this form, the for loop will create a reference for every character in the string, one at a time.
Now, what @JLBorges does, here, is a typical, old fashioned quick way of taking the
character of a digit and turning into the number itself. It takes the character code '0' in the character set, and subtracts that from the value from the string. Now, '0' in the character set looks like a integer of 48, so this "c -= '0'" clause reduces 48 to zero, converting the ascii code for the digit into a number.
@JLBorges now treats the string as if it were an array of numbers. They're char's, so they're limited to a range of -127 to 127, but that's enough for your requirement (since you really only need 0 to 9).
This is now fed into a stl algorithm, which you might find foreign.
It does what you'd do more manually with:
1 2 3 4 5 6 7 8 9 10 11
|
int source_array[ NDIGITS ];
int multipliers[ NDIGITS ];
// whatever gets the user's entry into source_array, and declares the multipliers goes here
int csum = 0;
for( int i = 0; i < NDIGITS; ++i )
{
csum += ( source_array[ i ] * multipliers[ i ] );
}
| |
Now, this does, basically and simplistically, what "std::inner_product" is doing.
It is the heart of what you're asking. All those "+" in your example formula is handled by csum += ....
Each "i" in the array is the "ABCD...." in your list.
In @JLBorges version, those "ABCD..." entries from the user are in the string "str", converted into a kind of really short integer array.
Now, we look back at "is_valid".
@JLBorges uses two tests. First, if the size of the string is not NDIGITS, the return will be false and no need to look further. There must be NDIGITS in the user's input.
Second, @JLBorges uses the algorithm "all_of" to loop through each digit int the string that came from the user to be sure they are all digits.
You might do this in a much simpler way like this:
1 2 3 4 5 6
|
bool is_good = true;
for( int i = 0; i < str.length(); ++i )
{
if ( str[ i ] < '0' || str[ i ] > '9' ) is_good = false;
}
| |
This is an old style, almost C approach that uses the kind of things new student programmers may recognize. This loops through each character in the string. The start of the code assumes this will all be good (set to true)...if any one of the characters is not a digit, "is_good" is made false, and the whole thing fails validation.
This is beginner level form. Each character must be between 0-9 inclusive...or, put the way it reads, it fails if the tested character is less than '0' or greater than '9'.
This could be done with std::isdigit( str[ i ] ) in that loop.
@JLBorges uses a modern C++ approach. First, the "all_of" algorithm will "process" all characters in the string string "str"....that's what this part does....
std::all_of( str.begin(), str.end().....
This sets up "all_of" to run from the beginning to the end of the string. The "std::all_of" function requires a function object of some kind. This is what "all_of" will do with each characters. It's as if you are required to give "all_of" a function it should call for every character, and the return value checked such that every function call returns true (or the whole thing returns false).
That's like the test I illustrate above....assume true, but any false makes the whole thing false.
...but what is the function to call?
In this case, @JLBorges uses a lambda expression - it's an "unnamed function written inline"....
It starts with "[]" - think of it as "lambda starts here"...
Next, is the same thing you see in a function declaration - it's the parameters the function takes. In this case, it's a character from the string.
Then, the function itself, which is just a call to "isdigit"....
Now, if you think about this walk through, you might take the more primitive versions I've put in this post, along with the modern C++ design @JLBorges posted, and probably come up with what you asked for....that "simpler" solution, that, really, isn't simpler...just more familiar to what you've covered in class.