Confusing result of std::sort (stable_sort) compare function return value
up vote
0
down vote
favorite
I have the following simple program. In test1
and test2
I tried to sort 2 strings "2" and "1", and in the example below, the function compare
will always return false.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cassert>
static inline bool compare(const std::string& a, const std::string& b)
if (isdigit(b[0]))
return false;
assert(isdigit(a[0]));
return true;
static inline void test1()
std::cout << "test1:n";
std::vector<std::string> arr =
"2", "1"
;
std::stable_sort(arr.begin(), arr.end(), compare);
for (auto e: arr)
std::cout << e << std::endl;
static inline void test2()
std::cout << "test2:n";
std::vector<std::string> arr =
"1", "2"
;
std::stable_sort(arr.begin(), arr.end(), compare);
for (auto e: arr)
std::cout << e << std::endl;
static inline bool compare_int(const int& a, const int& b)
return a > b;
static inline void test3()
std::cout << "test3:n";
std::vector<int> arr =
9, 3, 13, 7
;
std::stable_sort(arr.begin(), arr.end(), compare_int);
for (auto e: arr)
std::cout << e << ' ';
std::cout << std::endl;
int main()
test1();
test2();
test3();
return 0;
However, I get the following output
test1:
2
1
test2:
1
2
test3:
13 9 7 3
I'm confused, because as far as I know, the compare
function in test1 and test2 will return false, which indicates that these 2 elements should swap their location. But obviously, they do not change and are still in their original location.
Am I misinterpreting the return value of compare function? But in test3
it is indeed sorted in descending order.
I don't quite understand its internals, does it treat characters in a different way from integers?
c++ sorting std c++-standard-library
|
show 7 more comments
up vote
0
down vote
favorite
I have the following simple program. In test1
and test2
I tried to sort 2 strings "2" and "1", and in the example below, the function compare
will always return false.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cassert>
static inline bool compare(const std::string& a, const std::string& b)
if (isdigit(b[0]))
return false;
assert(isdigit(a[0]));
return true;
static inline void test1()
std::cout << "test1:n";
std::vector<std::string> arr =
"2", "1"
;
std::stable_sort(arr.begin(), arr.end(), compare);
for (auto e: arr)
std::cout << e << std::endl;
static inline void test2()
std::cout << "test2:n";
std::vector<std::string> arr =
"1", "2"
;
std::stable_sort(arr.begin(), arr.end(), compare);
for (auto e: arr)
std::cout << e << std::endl;
static inline bool compare_int(const int& a, const int& b)
return a > b;
static inline void test3()
std::cout << "test3:n";
std::vector<int> arr =
9, 3, 13, 7
;
std::stable_sort(arr.begin(), arr.end(), compare_int);
for (auto e: arr)
std::cout << e << ' ';
std::cout << std::endl;
int main()
test1();
test2();
test3();
return 0;
However, I get the following output
test1:
2
1
test2:
1
2
test3:
13 9 7 3
I'm confused, because as far as I know, the compare
function in test1 and test2 will return false, which indicates that these 2 elements should swap their location. But obviously, they do not change and are still in their original location.
Am I misinterpreting the return value of compare function? But in test3
it is indeed sorted in descending order.
I don't quite understand its internals, does it treat characters in a different way from integers?
c++ sorting std c++-standard-library
1
I am the sorting function. I callcompare("2", "1")
. You returnfalse
. Then I callcompare("1", "2")
. You again returnfalse
. See a problem? Your compare function says that "2" comes after "1", and at the same time "1" comes after "2". That's impossible, but that's what you coded.
– PaulMcKenzie
Nov 12 at 1:55
Thanks, but if I add an output in compare functionstd::cout << a << ' ' << b << std::endl;
, I find it prints1 2
in both times rather than2 1
, why will the compare function called twice with same order? For an array with 2 elemens, shouldn't it be enough to just compare once?
– biggerfish
Nov 12 at 2:09
The function can be called a million times if the runtime library feels like doing so. The goal is to see if your comparison function is bogus, and it is. If you claim that "2" comes before "1", and at the same time "1" comes before "2", does that sound like something will go haywire? See the docs about the comparison function and what a strict-weak-order means.
– PaulMcKenzie
Nov 12 at 2:10
I forgot to say, instd::sort
it will be called twice, but instd::stable_sort
it will only be called once with output1 2
– biggerfish
Nov 12 at 2:10
2
Yes, you are misunderstanding. There is no "order" in what you are doing. You are doing a "grouping". An order means specificallya < b
. If you say botha < b
andb < a
, that is ambiguous, not an ordering. If you want to keep the relative order within each group, that is whatstd::stable_partition
is meant for.
– PaulMcKenzie
Nov 12 at 2:39
|
show 7 more comments
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have the following simple program. In test1
and test2
I tried to sort 2 strings "2" and "1", and in the example below, the function compare
will always return false.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cassert>
static inline bool compare(const std::string& a, const std::string& b)
if (isdigit(b[0]))
return false;
assert(isdigit(a[0]));
return true;
static inline void test1()
std::cout << "test1:n";
std::vector<std::string> arr =
"2", "1"
;
std::stable_sort(arr.begin(), arr.end(), compare);
for (auto e: arr)
std::cout << e << std::endl;
static inline void test2()
std::cout << "test2:n";
std::vector<std::string> arr =
"1", "2"
;
std::stable_sort(arr.begin(), arr.end(), compare);
for (auto e: arr)
std::cout << e << std::endl;
static inline bool compare_int(const int& a, const int& b)
return a > b;
static inline void test3()
std::cout << "test3:n";
std::vector<int> arr =
9, 3, 13, 7
;
std::stable_sort(arr.begin(), arr.end(), compare_int);
for (auto e: arr)
std::cout << e << ' ';
std::cout << std::endl;
int main()
test1();
test2();
test3();
return 0;
However, I get the following output
test1:
2
1
test2:
1
2
test3:
13 9 7 3
I'm confused, because as far as I know, the compare
function in test1 and test2 will return false, which indicates that these 2 elements should swap their location. But obviously, they do not change and are still in their original location.
Am I misinterpreting the return value of compare function? But in test3
it is indeed sorted in descending order.
I don't quite understand its internals, does it treat characters in a different way from integers?
c++ sorting std c++-standard-library
I have the following simple program. In test1
and test2
I tried to sort 2 strings "2" and "1", and in the example below, the function compare
will always return false.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cassert>
static inline bool compare(const std::string& a, const std::string& b)
if (isdigit(b[0]))
return false;
assert(isdigit(a[0]));
return true;
static inline void test1()
std::cout << "test1:n";
std::vector<std::string> arr =
"2", "1"
;
std::stable_sort(arr.begin(), arr.end(), compare);
for (auto e: arr)
std::cout << e << std::endl;
static inline void test2()
std::cout << "test2:n";
std::vector<std::string> arr =
"1", "2"
;
std::stable_sort(arr.begin(), arr.end(), compare);
for (auto e: arr)
std::cout << e << std::endl;
static inline bool compare_int(const int& a, const int& b)
return a > b;
static inline void test3()
std::cout << "test3:n";
std::vector<int> arr =
9, 3, 13, 7
;
std::stable_sort(arr.begin(), arr.end(), compare_int);
for (auto e: arr)
std::cout << e << ' ';
std::cout << std::endl;
int main()
test1();
test2();
test3();
return 0;
However, I get the following output
test1:
2
1
test2:
1
2
test3:
13 9 7 3
I'm confused, because as far as I know, the compare
function in test1 and test2 will return false, which indicates that these 2 elements should swap their location. But obviously, they do not change and are still in their original location.
Am I misinterpreting the return value of compare function? But in test3
it is indeed sorted in descending order.
I don't quite understand its internals, does it treat characters in a different way from integers?
c++ sorting std c++-standard-library
c++ sorting std c++-standard-library
edited Nov 12 at 1:47
Deduplicator
34k64787
34k64787
asked Nov 12 at 1:34
biggerfish
638
638
1
I am the sorting function. I callcompare("2", "1")
. You returnfalse
. Then I callcompare("1", "2")
. You again returnfalse
. See a problem? Your compare function says that "2" comes after "1", and at the same time "1" comes after "2". That's impossible, but that's what you coded.
– PaulMcKenzie
Nov 12 at 1:55
Thanks, but if I add an output in compare functionstd::cout << a << ' ' << b << std::endl;
, I find it prints1 2
in both times rather than2 1
, why will the compare function called twice with same order? For an array with 2 elemens, shouldn't it be enough to just compare once?
– biggerfish
Nov 12 at 2:09
The function can be called a million times if the runtime library feels like doing so. The goal is to see if your comparison function is bogus, and it is. If you claim that "2" comes before "1", and at the same time "1" comes before "2", does that sound like something will go haywire? See the docs about the comparison function and what a strict-weak-order means.
– PaulMcKenzie
Nov 12 at 2:10
I forgot to say, instd::sort
it will be called twice, but instd::stable_sort
it will only be called once with output1 2
– biggerfish
Nov 12 at 2:10
2
Yes, you are misunderstanding. There is no "order" in what you are doing. You are doing a "grouping". An order means specificallya < b
. If you say botha < b
andb < a
, that is ambiguous, not an ordering. If you want to keep the relative order within each group, that is whatstd::stable_partition
is meant for.
– PaulMcKenzie
Nov 12 at 2:39
|
show 7 more comments
1
I am the sorting function. I callcompare("2", "1")
. You returnfalse
. Then I callcompare("1", "2")
. You again returnfalse
. See a problem? Your compare function says that "2" comes after "1", and at the same time "1" comes after "2". That's impossible, but that's what you coded.
– PaulMcKenzie
Nov 12 at 1:55
Thanks, but if I add an output in compare functionstd::cout << a << ' ' << b << std::endl;
, I find it prints1 2
in both times rather than2 1
, why will the compare function called twice with same order? For an array with 2 elemens, shouldn't it be enough to just compare once?
– biggerfish
Nov 12 at 2:09
The function can be called a million times if the runtime library feels like doing so. The goal is to see if your comparison function is bogus, and it is. If you claim that "2" comes before "1", and at the same time "1" comes before "2", does that sound like something will go haywire? See the docs about the comparison function and what a strict-weak-order means.
– PaulMcKenzie
Nov 12 at 2:10
I forgot to say, instd::sort
it will be called twice, but instd::stable_sort
it will only be called once with output1 2
– biggerfish
Nov 12 at 2:10
2
Yes, you are misunderstanding. There is no "order" in what you are doing. You are doing a "grouping". An order means specificallya < b
. If you say botha < b
andb < a
, that is ambiguous, not an ordering. If you want to keep the relative order within each group, that is whatstd::stable_partition
is meant for.
– PaulMcKenzie
Nov 12 at 2:39
1
1
I am the sorting function. I call
compare("2", "1")
. You return false
. Then I call compare("1", "2")
. You again return false
. See a problem? Your compare function says that "2" comes after "1", and at the same time "1" comes after "2". That's impossible, but that's what you coded.– PaulMcKenzie
Nov 12 at 1:55
I am the sorting function. I call
compare("2", "1")
. You return false
. Then I call compare("1", "2")
. You again return false
. See a problem? Your compare function says that "2" comes after "1", and at the same time "1" comes after "2". That's impossible, but that's what you coded.– PaulMcKenzie
Nov 12 at 1:55
Thanks, but if I add an output in compare function
std::cout << a << ' ' << b << std::endl;
, I find it prints 1 2
in both times rather than 2 1
, why will the compare function called twice with same order? For an array with 2 elemens, shouldn't it be enough to just compare once?– biggerfish
Nov 12 at 2:09
Thanks, but if I add an output in compare function
std::cout << a << ' ' << b << std::endl;
, I find it prints 1 2
in both times rather than 2 1
, why will the compare function called twice with same order? For an array with 2 elemens, shouldn't it be enough to just compare once?– biggerfish
Nov 12 at 2:09
The function can be called a million times if the runtime library feels like doing so. The goal is to see if your comparison function is bogus, and it is. If you claim that "2" comes before "1", and at the same time "1" comes before "2", does that sound like something will go haywire? See the docs about the comparison function and what a strict-weak-order means.
– PaulMcKenzie
Nov 12 at 2:10
The function can be called a million times if the runtime library feels like doing so. The goal is to see if your comparison function is bogus, and it is. If you claim that "2" comes before "1", and at the same time "1" comes before "2", does that sound like something will go haywire? See the docs about the comparison function and what a strict-weak-order means.
– PaulMcKenzie
Nov 12 at 2:10
I forgot to say, in
std::sort
it will be called twice, but in std::stable_sort
it will only be called once with output 1 2
– biggerfish
Nov 12 at 2:10
I forgot to say, in
std::sort
it will be called twice, but in std::stable_sort
it will only be called once with output 1 2
– biggerfish
Nov 12 at 2:10
2
2
Yes, you are misunderstanding. There is no "order" in what you are doing. You are doing a "grouping". An order means specifically
a < b
. If you say both a < b
and b < a
, that is ambiguous, not an ordering. If you want to keep the relative order within each group, that is what std::stable_partition
is meant for.– PaulMcKenzie
Nov 12 at 2:39
Yes, you are misunderstanding. There is no "order" in what you are doing. You are doing a "grouping". An order means specifically
a < b
. If you say both a < b
and b < a
, that is ambiguous, not an ordering. If you want to keep the relative order within each group, that is what std::stable_partition
is meant for.– PaulMcKenzie
Nov 12 at 2:39
|
show 7 more comments
2 Answers
2
active
oldest
votes
up vote
2
down vote
accepted
I'm going to answer my own question but many thanks to PaulMckenzie for his help in the discussion and Victor Istomin's answer.
It turns out that sort does not work in the way I thought it should be. It expects strict-weak-order, which means a > b
and b > a
cannot be true at the same time, otherwise the behavior is undefined. Also, its way to judge if 2 elements equal is using !(a < b) && !(b > a)
because it only uses the <
operator instead of ==
operator.
The mistake in my code is that I always return false in this case, so that the expression !(a < b) && !(b > a)
will be true, and sort considers them to equal, thus not swapping them.
The right solution as PaulMckenzie points out, is using stable_partiion
(or partition
if relative order is not needed). The principle is to use sort only when we have clear rule of comparing elements, if we just want to group same elements together, partition
is good.
It seems I had some false delusions about sort function, thanks for pointing out.
----------------- update ----------------
Caleth points out in the comment that the strict-weak-order is not enforced, but the behavior will be undefined if violated. Updated my description of that part. Thanks.
It isn't enforced.std::sort
is documented as having undefined behaviour if the comparison doesn't implement a strict weak ordering on the data. That doesn't mean "the result might be incorrect", it means "your program is no longer bound by the rules of C++", which includes such possibilities as "appears to work, but trashes unrelated data"
– Caleth
Nov 12 at 10:20
@biggerfish Maybe you got confused by the word "sort". In C++ and most other languages, "sort" has a specific meaning. In laid-back English talk, "sort" could mean to group things. But this isn't laid-back English, it is computer science.
– PaulMcKenzie
Nov 13 at 1:03
@Caleth Updated my answer, thanks for pointing out.
– biggerfish
Nov 13 at 6:11
@PaulMcKenzie Yes I think so. Thanks.
– biggerfish
Nov 13 at 6:13
add a comment |
up vote
0
down vote
It looks like 'compare' works exactly as you wrote: returns false if first char of second string is digit.
By the way, this compare function won't work as expected (whatever you expect from it, I have no idea) in general case. In C++, sort comparator should implement strict weak ordering. In other words, there should be no case when 'a < b' and 'b < a' at the same time.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254971%2fconfusing-result-of-stdsort-stable-sort-compare-function-return-value%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
I'm going to answer my own question but many thanks to PaulMckenzie for his help in the discussion and Victor Istomin's answer.
It turns out that sort does not work in the way I thought it should be. It expects strict-weak-order, which means a > b
and b > a
cannot be true at the same time, otherwise the behavior is undefined. Also, its way to judge if 2 elements equal is using !(a < b) && !(b > a)
because it only uses the <
operator instead of ==
operator.
The mistake in my code is that I always return false in this case, so that the expression !(a < b) && !(b > a)
will be true, and sort considers them to equal, thus not swapping them.
The right solution as PaulMckenzie points out, is using stable_partiion
(or partition
if relative order is not needed). The principle is to use sort only when we have clear rule of comparing elements, if we just want to group same elements together, partition
is good.
It seems I had some false delusions about sort function, thanks for pointing out.
----------------- update ----------------
Caleth points out in the comment that the strict-weak-order is not enforced, but the behavior will be undefined if violated. Updated my description of that part. Thanks.
It isn't enforced.std::sort
is documented as having undefined behaviour if the comparison doesn't implement a strict weak ordering on the data. That doesn't mean "the result might be incorrect", it means "your program is no longer bound by the rules of C++", which includes such possibilities as "appears to work, but trashes unrelated data"
– Caleth
Nov 12 at 10:20
@biggerfish Maybe you got confused by the word "sort". In C++ and most other languages, "sort" has a specific meaning. In laid-back English talk, "sort" could mean to group things. But this isn't laid-back English, it is computer science.
– PaulMcKenzie
Nov 13 at 1:03
@Caleth Updated my answer, thanks for pointing out.
– biggerfish
Nov 13 at 6:11
@PaulMcKenzie Yes I think so. Thanks.
– biggerfish
Nov 13 at 6:13
add a comment |
up vote
2
down vote
accepted
I'm going to answer my own question but many thanks to PaulMckenzie for his help in the discussion and Victor Istomin's answer.
It turns out that sort does not work in the way I thought it should be. It expects strict-weak-order, which means a > b
and b > a
cannot be true at the same time, otherwise the behavior is undefined. Also, its way to judge if 2 elements equal is using !(a < b) && !(b > a)
because it only uses the <
operator instead of ==
operator.
The mistake in my code is that I always return false in this case, so that the expression !(a < b) && !(b > a)
will be true, and sort considers them to equal, thus not swapping them.
The right solution as PaulMckenzie points out, is using stable_partiion
(or partition
if relative order is not needed). The principle is to use sort only when we have clear rule of comparing elements, if we just want to group same elements together, partition
is good.
It seems I had some false delusions about sort function, thanks for pointing out.
----------------- update ----------------
Caleth points out in the comment that the strict-weak-order is not enforced, but the behavior will be undefined if violated. Updated my description of that part. Thanks.
It isn't enforced.std::sort
is documented as having undefined behaviour if the comparison doesn't implement a strict weak ordering on the data. That doesn't mean "the result might be incorrect", it means "your program is no longer bound by the rules of C++", which includes such possibilities as "appears to work, but trashes unrelated data"
– Caleth
Nov 12 at 10:20
@biggerfish Maybe you got confused by the word "sort". In C++ and most other languages, "sort" has a specific meaning. In laid-back English talk, "sort" could mean to group things. But this isn't laid-back English, it is computer science.
– PaulMcKenzie
Nov 13 at 1:03
@Caleth Updated my answer, thanks for pointing out.
– biggerfish
Nov 13 at 6:11
@PaulMcKenzie Yes I think so. Thanks.
– biggerfish
Nov 13 at 6:13
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
I'm going to answer my own question but many thanks to PaulMckenzie for his help in the discussion and Victor Istomin's answer.
It turns out that sort does not work in the way I thought it should be. It expects strict-weak-order, which means a > b
and b > a
cannot be true at the same time, otherwise the behavior is undefined. Also, its way to judge if 2 elements equal is using !(a < b) && !(b > a)
because it only uses the <
operator instead of ==
operator.
The mistake in my code is that I always return false in this case, so that the expression !(a < b) && !(b > a)
will be true, and sort considers them to equal, thus not swapping them.
The right solution as PaulMckenzie points out, is using stable_partiion
(or partition
if relative order is not needed). The principle is to use sort only when we have clear rule of comparing elements, if we just want to group same elements together, partition
is good.
It seems I had some false delusions about sort function, thanks for pointing out.
----------------- update ----------------
Caleth points out in the comment that the strict-weak-order is not enforced, but the behavior will be undefined if violated. Updated my description of that part. Thanks.
I'm going to answer my own question but many thanks to PaulMckenzie for his help in the discussion and Victor Istomin's answer.
It turns out that sort does not work in the way I thought it should be. It expects strict-weak-order, which means a > b
and b > a
cannot be true at the same time, otherwise the behavior is undefined. Also, its way to judge if 2 elements equal is using !(a < b) && !(b > a)
because it only uses the <
operator instead of ==
operator.
The mistake in my code is that I always return false in this case, so that the expression !(a < b) && !(b > a)
will be true, and sort considers them to equal, thus not swapping them.
The right solution as PaulMckenzie points out, is using stable_partiion
(or partition
if relative order is not needed). The principle is to use sort only when we have clear rule of comparing elements, if we just want to group same elements together, partition
is good.
It seems I had some false delusions about sort function, thanks for pointing out.
----------------- update ----------------
Caleth points out in the comment that the strict-weak-order is not enforced, but the behavior will be undefined if violated. Updated my description of that part. Thanks.
edited Nov 13 at 6:11
answered Nov 12 at 6:37
biggerfish
638
638
It isn't enforced.std::sort
is documented as having undefined behaviour if the comparison doesn't implement a strict weak ordering on the data. That doesn't mean "the result might be incorrect", it means "your program is no longer bound by the rules of C++", which includes such possibilities as "appears to work, but trashes unrelated data"
– Caleth
Nov 12 at 10:20
@biggerfish Maybe you got confused by the word "sort". In C++ and most other languages, "sort" has a specific meaning. In laid-back English talk, "sort" could mean to group things. But this isn't laid-back English, it is computer science.
– PaulMcKenzie
Nov 13 at 1:03
@Caleth Updated my answer, thanks for pointing out.
– biggerfish
Nov 13 at 6:11
@PaulMcKenzie Yes I think so. Thanks.
– biggerfish
Nov 13 at 6:13
add a comment |
It isn't enforced.std::sort
is documented as having undefined behaviour if the comparison doesn't implement a strict weak ordering on the data. That doesn't mean "the result might be incorrect", it means "your program is no longer bound by the rules of C++", which includes such possibilities as "appears to work, but trashes unrelated data"
– Caleth
Nov 12 at 10:20
@biggerfish Maybe you got confused by the word "sort". In C++ and most other languages, "sort" has a specific meaning. In laid-back English talk, "sort" could mean to group things. But this isn't laid-back English, it is computer science.
– PaulMcKenzie
Nov 13 at 1:03
@Caleth Updated my answer, thanks for pointing out.
– biggerfish
Nov 13 at 6:11
@PaulMcKenzie Yes I think so. Thanks.
– biggerfish
Nov 13 at 6:13
It isn't enforced.
std::sort
is documented as having undefined behaviour if the comparison doesn't implement a strict weak ordering on the data. That doesn't mean "the result might be incorrect", it means "your program is no longer bound by the rules of C++", which includes such possibilities as "appears to work, but trashes unrelated data"– Caleth
Nov 12 at 10:20
It isn't enforced.
std::sort
is documented as having undefined behaviour if the comparison doesn't implement a strict weak ordering on the data. That doesn't mean "the result might be incorrect", it means "your program is no longer bound by the rules of C++", which includes such possibilities as "appears to work, but trashes unrelated data"– Caleth
Nov 12 at 10:20
@biggerfish Maybe you got confused by the word "sort". In C++ and most other languages, "sort" has a specific meaning. In laid-back English talk, "sort" could mean to group things. But this isn't laid-back English, it is computer science.
– PaulMcKenzie
Nov 13 at 1:03
@biggerfish Maybe you got confused by the word "sort". In C++ and most other languages, "sort" has a specific meaning. In laid-back English talk, "sort" could mean to group things. But this isn't laid-back English, it is computer science.
– PaulMcKenzie
Nov 13 at 1:03
@Caleth Updated my answer, thanks for pointing out.
– biggerfish
Nov 13 at 6:11
@Caleth Updated my answer, thanks for pointing out.
– biggerfish
Nov 13 at 6:11
@PaulMcKenzie Yes I think so. Thanks.
– biggerfish
Nov 13 at 6:13
@PaulMcKenzie Yes I think so. Thanks.
– biggerfish
Nov 13 at 6:13
add a comment |
up vote
0
down vote
It looks like 'compare' works exactly as you wrote: returns false if first char of second string is digit.
By the way, this compare function won't work as expected (whatever you expect from it, I have no idea) in general case. In C++, sort comparator should implement strict weak ordering. In other words, there should be no case when 'a < b' and 'b < a' at the same time.
add a comment |
up vote
0
down vote
It looks like 'compare' works exactly as you wrote: returns false if first char of second string is digit.
By the way, this compare function won't work as expected (whatever you expect from it, I have no idea) in general case. In C++, sort comparator should implement strict weak ordering. In other words, there should be no case when 'a < b' and 'b < a' at the same time.
add a comment |
up vote
0
down vote
up vote
0
down vote
It looks like 'compare' works exactly as you wrote: returns false if first char of second string is digit.
By the way, this compare function won't work as expected (whatever you expect from it, I have no idea) in general case. In C++, sort comparator should implement strict weak ordering. In other words, there should be no case when 'a < b' and 'b < a' at the same time.
It looks like 'compare' works exactly as you wrote: returns false if first char of second string is digit.
By the way, this compare function won't work as expected (whatever you expect from it, I have no idea) in general case. In C++, sort comparator should implement strict weak ordering. In other words, there should be no case when 'a < b' and 'b < a' at the same time.
answered Nov 12 at 1:53
Victor Istomin
661513
661513
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254971%2fconfusing-result-of-stdsort-stable-sort-compare-function-return-value%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I am the sorting function. I call
compare("2", "1")
. You returnfalse
. Then I callcompare("1", "2")
. You again returnfalse
. See a problem? Your compare function says that "2" comes after "1", and at the same time "1" comes after "2". That's impossible, but that's what you coded.– PaulMcKenzie
Nov 12 at 1:55
Thanks, but if I add an output in compare function
std::cout << a << ' ' << b << std::endl;
, I find it prints1 2
in both times rather than2 1
, why will the compare function called twice with same order? For an array with 2 elemens, shouldn't it be enough to just compare once?– biggerfish
Nov 12 at 2:09
The function can be called a million times if the runtime library feels like doing so. The goal is to see if your comparison function is bogus, and it is. If you claim that "2" comes before "1", and at the same time "1" comes before "2", does that sound like something will go haywire? See the docs about the comparison function and what a strict-weak-order means.
– PaulMcKenzie
Nov 12 at 2:10
I forgot to say, in
std::sort
it will be called twice, but instd::stable_sort
it will only be called once with output1 2
– biggerfish
Nov 12 at 2:10
2
Yes, you are misunderstanding. There is no "order" in what you are doing. You are doing a "grouping". An order means specifically
a < b
. If you say botha < b
andb < a
, that is ambiguous, not an ordering. If you want to keep the relative order within each group, that is whatstd::stable_partition
is meant for.– PaulMcKenzie
Nov 12 at 2:39