Breaking down the requirements:
You are given a list of integers (std::list<'int'>).
The algorithm is required to at least work with std::list<int>
, so we cannot rely on random-access/contiguity.
Iterating over the list only once,
Requires a single-pass algorithm. Single pass algorithms have special rules associated with them, like only accessing the current element once and only moving forward. Your implementation exhibits multi-pass behavior.
std::prev(nmbrs.end())
--i;
delete all elements that give a sum of 10 with the preceding element.
Applying this to a single pass approach, you will need to store the preceding element in a temporary.
A source file should be self-sufficient in providing the definition of every symbol used. Some implementations may include the library for you (<list>
including <iterator>
, but that behavior is neither standard nor portable. std::prev
requires <iterator>
.
bool target_sum(const int i, const int j)
{
return (i+j) == 10;
}
Don't use magic numbers. The target sum for this test is 10, but will it always be 10?
void print(const std::list<int> &nmbrs)
{
for (const int p : nmbrs)
std::cout << p << " ";
std::cout << std::endl;
}
Every line that gets printed prints an extra delimiter at the end of the list. An extra whitespace character might not do anything, but it certainly isn't intended. Strive for correctness in your programs.
Avoid std::endl
. Directly state your intent in code and be aware of what std::endl
does. The following two statements are equivalent (ignoring localization).
std::cout << std::endl;
std::cout << '\n' << std::flush;
Again, be explicit with your intent.
std::cout << std::endl; // Flush intended?
std::cout << '\n'; // Definitely don't flush.
std::cout << '\n' << std::flush; // Definitely flush.
// initialises a list that holds the numbers
std::list<int> nmbrs = {5, 5, 3, 7, 7, 7, 3, 3, 1, 2, 3, 7, 4, 6};
if (nmbrs.size() > 1) //if there are at least 2 numbers
Don't say in comments what can be or is already stated in code.
Vowels do not cost $500. Having a smaller variable name because your abbreviation strips vowels or truncates the end doesn't translate to better code or performance. Abbreviations negatively impacts readability and maintainability, which are two very important aspects in programming.
Factor out common code into functions. Functions promote reuse and limits the scope for errors (making testing easier).
std::list<int>::iterator i = nmbrs.begin();
Use auto
to avoid repetition of type names.
target_sum(*i, *(i++))
C++ has special rules regarding evaluation order. In this case, the ,
of the argument list is not a sequence point because the argument list itself is not an expression. Since the arguments are indeterminately sequenced, modifying the variable and trying to access the variable is undefined behavior.
// print(nmbrs);
Remove dead code rather than commenting.
_getch();
You don't need _getch();
or conio.h
. If you need to pause on input, the standard library already provides such a facility (std::cin.get()
).
Instead of cluttering your program with unnecessary debugging support code, learn about your terminal emulator and how to use it correctly. Some IDE's provide an option to keep the window open after running. Other IDE's offer a full fledged debugging system (MSVC) where you can use breakpoints to externally "pause" the program.
{1, 9, 1}
produce{1}
or{1, 1}
? \$\endgroup\$