Experience in debugging C++ Primer Exercise 3.26

Originally, this was a question of judging whether it is legal (English Version Page 113). I originally thought that the cause of the error was that beg + end exceeded the range of vector. After compilation, I found that the error was actually that the operation + was not defined at all. This embodies the importance of hand-coded programs.
My definition of dichotomous median is not the same as in the book. The book is actually the median or the right of the two medians. I have trouble defining it as the median value or the left side of the two median values ​​(because I prefer the left side). As a result, it caused troublesome discussions on lines 34-49 of the program (just wrong, I don’t want to change the definition of mid).

#include <iostream>
#include <vector>
#include <algorithm>
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
using std::sort;

int main()
{
    
    
	vector<int> vint;
	int i;
	int seek;
	cout << "Please input the number you seek:" << endl;
	cin >> seek;
	cout << "Please input numbers from where you want to seek a certain number:" << endl;
	while (cin >> i)
		vint.push_back(i);
	sort(vint.begin(),vint.end());
	// The next three lines are used for test in terms of the numbers after sorting.
	cout << endl;
	for (auto c : vint) cout << c << " "; // show the contents of 'vint'
	cout << endl;
	auto beg = vint.cbegin();
	auto end = vint.cend(); // Remember that 'end' is one off the end.
	auto mid = beg + (end - beg + 1) / 2 - 1; // 'mid' is at the middle or the first (left) one of the two middle ones.
	cout << beg - vint.cbegin() << " " << mid - vint.cbegin() << " " << end - vint.cbegin() << endl;
	cout << "*mid= " << *mid << endl;
	while (mid != end && *mid != seek)
	{
    
    
		// This 'if' aims to move 'mid' to the next place as when there are only 2 elements, 'mid' remains still.
		if (end - mid != 2)
		{
    
    
			if (seek < *mid) end = mid;
		    else beg = mid + 1;
			mid = beg + (end - beg + 1) / 2 - 1;
		}
		else
		{
    
    
			if (*(mid + 1) == seek) // move 'mid' to the next place
				mid += 1;
			else
			{
    
    
    			cerr << "Sorry, there is no " << seek << "." << endl; // to indicate there's no that number
    			return -1;
			}
		}
		// The next two lines are used for test in terms of the current place and value of 'mid'.
		cout << beg - vint.cbegin() << " " << mid - vint.cbegin() << " " << end - vint.cbegin() << endl;
		cout << "*mid= " << *mid << endl;
	}
	// Check whether the one we find is the first of all. If not, move to the number to its left.
	while (*(mid - 1) == seek && (mid - vint.cbegin()) != 0)
		mid -= 1;
	// The next line is used for test in terms of the final place and value of 'mid'.
	cout << "*mid, &mid= " << *mid << "," << mid - vint.begin() << '\n' << endl;
	// The place needs to plus one as the place in vector begins at 0, while we need it at 1.
	cout << "The number " << seek << " is in No." << mid - vint.cbegin() + 1 << " place." << endl;
	return 0;
}

Here are a few wrong experiences:

I forgot to redefine mid on line 38

This is actually the problem of inconsistent thinking. When entering the second round of the while loop, beg, mid, and end should all be prepared. (A question of literacy)

II Lines 33-49 forget to classify and discuss

There is still a problem with the program, so I listed the situation on the draft paper and found that when locked within two values, mid will remain in the same position and no longer move (stay still), so sometimes it will fall into bad death during the experiment. cycle. So patched with an if statement.
However, there are still problems with the program! ! !

III Incorrect use of ++ in line 42

The discovery of this problem benefited from the intermediate test outputting the intermediate conclusion, and then in one test it was found that the beg, mid and end positions jumped directly from 6 6 8 to 6 8 8. It’s strange, it’s obvious that mid+=1, so how come you get two places all at once?
Test
After inspection, it was found that ++ was used incorrectly in the if statement (this makes a mistake and impressive). Although it was a judgment statement, the mid was indeed changed.
(Actually , there is a more detailed explanation in C++ Primer 4.5 Increment and Decrement Operators .)

IV Wrong use of line 55--

Similarly,--also works in mid.

V line 60 output forgets +1

This is also a very serious problem. The reason is that the vector position starts at 0, but we start counting from 1, so the position counted by mid-vint.begin() will be 1 worse, causing the result to be wrong. (I also found problems from the experimental intermediate data)

Conclusion

1. It is beneficial to think more. Although it took some time to find bugs, it was also a process of improvement.
2. Logical literacy is very important. The structure should be clear, not disordered, or what is in your mind is not reflected in the program.
3. Make full use of the intermediate conclusion output. This is a good error message that allows us to prescribe the right medicine to deal with the phenomenon that a certain parameter is different from what we expected. At the same time, several sets of experiments allow us to sum up the rules, which can point to errors.
4. The concept should be clear. The book C++ Primer still has a lot of analysis of concepts. A full understanding and memory of this will help you not make fatal mistakes that the compiler cannot detect (such as ++ and--here).


See also

Teddy van Jerry's navigation page
[C++ Primer(5th Edition) Exercise] Exercise program-Chapter3 (Chapter 3)

Guess you like

Origin blog.csdn.net/weixin_50012998/article/details/108146684