Trap of strings - remember incorrect understanding of string size comparison


This paper records a small experience of the author who was pitted by string in the process of doing the title (actually his own dish, a blog by the way). I hope to help a little white like me understand some aspect of string better.

root of all evils

Xiao Ming decided to apply for a new QQ number. The system randomly generated several numbers for him to choose from. Xiao Ming's principle of numbering is:

  1. Select the number whose sum is the largest of all numbers.
  2. If more than one number has the same sum of digits, choose the number with the highest value.
    Please write a program to help Xiao Ming select a QQ number.

Enter a description     
The input data consists of two lines, the first line with an integer n denoting n numbers to be selected (0<n<100) and the second line with n positive integers denoting each number to be selected, each of which is no longer than 9 digits in length. Each number is separated by a space, and each number is different.

Output description     
Output the number selected according to the smart number selection principle.

sample input     
5
10000 11111 22222 333 1234

sample output     
2222

Description of the problem:

First, my idea is to use pair to store the sum of the digits of a number and the number itself, then sort it with sort and take the last element. You can think about what's wrong with this. (Tip, the second requirement for a title is the number with the highest number)

This is the comparison function that I wrote (and sort itself compares as well)

bool cmp(pair<int, string>a, pair<int, string>b) {
if (a.first != b.first)
return a.first < b.first;
else
return a.second < b.second;
}

Reason analysis:

Did you see the problem?

If you can see it at a glance, you already know the concept of dictionary order and the comparison of string.

In else, we compare string s using the less than sign, which is similar to the strcmp function in c. It starts with the first letter, then compares each character backwards (ascii), and returns a value whenever something is different (refer to baidu specifically).

For example, 98455987 and 676692496, 98455987 have a larger dictionary order, but they are actually smaller in value.

Thus, the greater than sign less than sign in a string does not necessarily reflect a true comparison of values (as I knew before, but didn't notice=-=)

Solution:

Did you notice that "not necessarily"? In fact, dictionary order can also reflect the value size under some conditions.

That's when the two strings are the same length.

So length is a key quantity, where numbers are either long or short, so you can't compare the size of strings, so we can think that for strings of different lengths, their lengths should be compared first. Long length, many digits, the value is naturally larger.

So we can override the comparison function like this

bool cmp(pair<int, string>a, pair<int, string>b) {
if (a.first != b.first)
return a.first < b.first;
else if (a.second.length() != b.second.length())
return a.second.length() < b.second.length();
else
return a.second < b.second;
}

summary

Length must be considered unless the length of two string s (pure numbers) is the same.

Code attached

#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
using namespace std;

bool cmp(pair<int, string>a, pair<int, string>b) {
	if (a.first != b.first)
		return a.first < b.first;
	else if (a.second.length() != b.second.length())
		return a.second.length() < b.second.length();
	else
		return a.second < b.second;
}

int main() {
	pair<int, string> s[1000];
	int n;
	cin >> n;

	for (int i = 0; i < n; i++) {
		cin >> s[i].second;
		int sum = 0, ans = 0;
		for (int j = 0; j < s[i].second.length(); j++) {
			sum += (s[i].second[j] - '0');
		}
		s[i].first = sum;
	}
	sort(s, s + n, cmp);
//	for (int i = 0; i < n; i++)
//		cout << s[i].second << endl;
	cout << s[n - 1].second;
	return 0;
}
//Tapping
#include <iostream>
#include <ctime>
using namespace std;

//Returns an integer between L and R
int gr(int L, int R) {
	return rand() * rand() % (R - L + 1) + L;
}

int main() {
	//Initialize random seeds
	srand(time(0));
	int a, b;
	//Generate a set of random data
	a = gr(1, 100);
	cout << a << endl;
	for (int i = 0; i < a; i++)
		cout << gr(1, 1000000000) << " ";
	return 0;
}

​

Keywords: string

Added by mrjam on Sun, 31 Oct 2021 18:45:05 +0200