Skip to content

Commit 363ba03

Browse files
committed
Base LDS and LNDS on longest increasing subsequence
1 parent 3883324 commit 363ba03

File tree

3 files changed

+27
-24
lines changed

3 files changed

+27
-24
lines changed

include/cpp-sort/detail/longest_non_descending_subsequence.h renamed to include/cpp-sort/detail/longest_increasing_subsequence.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
* Copyright (c) 2021-2025 Morwenn
33
* SPDX-License-Identifier: MIT
44
*/
5-
#ifndef CPPSORT_DETAIL_LONGEST_NON_DESCENDING_SUBSEQUENCE_H_
6-
#define CPPSORT_DETAIL_LONGEST_NON_DESCENDING_SUBSEQUENCE_H_
5+
#ifndef CPPSORT_DETAIL_LONGEST_INCREASING_SUBSEQUENCE_H_
6+
#define CPPSORT_DETAIL_LONGEST_INCREASING_SUBSEQUENCE_H_
77

88
////////////////////////////////////////////////////////////
99
// Headers
@@ -15,23 +15,23 @@
1515
#include <cpp-sort/utility/as_function.h>
1616
#include <cpp-sort/utility/functional.h>
1717
#include "iterator_traits.h"
18-
#include "upper_bound.h"
18+
#include "lower_bound.h"
1919

2020
namespace cppsort::detail
2121
{
22-
// Longest non-decreasing subsequence, computed with an altered
22+
// Longest increasing subsequence, computed with an altered
2323
// patience sorting algorithm - returns a pair containing the
24-
// size of the LNDS and the size of the collection
24+
// size of the LIS and the size of the collection
2525

2626
template<
2727
bool RecomputeSize,
2828
typename ForwardIterator,
2929
typename Compare,
3030
typename Projection
3131
>
32-
auto longest_non_descending_subsequence(ForwardIterator first, ForwardIterator last,
33-
difference_type_t<ForwardIterator> size,
34-
Compare compare, Projection projection)
32+
auto longest_increasing_subsequence(ForwardIterator first, ForwardIterator last,
33+
difference_type_t<ForwardIterator> size,
34+
Compare compare, Projection projection)
3535
-> std::pair<difference_type_t<ForwardIterator>, difference_type_t<ForwardIterator>>
3636
{
3737
constexpr bool is_random_access = std::is_base_of_v<
@@ -59,18 +59,18 @@ namespace cppsort::detail
5959
// Top (smaller) elements in patience sorting stacks
6060
std::vector<ForwardIterator> stack_tops;
6161

62-
while (first != last) {
63-
auto it = detail::upper_bound(
62+
do {
63+
auto it = detail::lower_bound(
6464
stack_tops.begin(), stack_tops.end(),
6565
proj(*first), compare, utility::indirect{} | projection);
6666

6767
if (it == stack_tops.end()) {
68-
// The element is bigger than everything else,
68+
// The element is strictly bigger than everything else,
6969
// create a new "stack" to put it
7070
stack_tops.emplace_back(first);
7171
} else {
72-
// The element is strictly smaller than the top
73-
// of a given stack, replace the stack top
72+
// The element is strictly smaller than or equal to
73+
// the top of a given stack, replace the stack top
7474
*it = first;
7575
}
7676
++first;
@@ -79,10 +79,10 @@ namespace cppsort::detail
7979
// Compute the size as-we-go if iterators are not random-access
8080
++size;
8181
}
82-
}
82+
} while (first != last);
8383

8484
return { stack_tops.size(), size };
8585
}
8686
}
8787

88-
#endif // CPPSORT_DETAIL_LONGEST_NON_DESCENDING_SUBSEQUENCE_H_
88+
#endif // CPPSORT_DETAIL_LONGEST_INCREASING_SUBSEQUENCE_H_

include/cpp-sort/probes/rem.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111
#include <functional>
1212
#include <iterator>
1313
#include <utility>
14+
#include <cpp-sort/comparators/flip.h>
15+
#include <cpp-sort/comparators/not_fn.h>
1416
#include <cpp-sort/sorter_facade.h>
1517
#include <cpp-sort/sorter_traits.h>
1618
#include <cpp-sort/utility/functional.h>
1719
#include <cpp-sort/utility/size.h>
18-
#include "../detail/longest_non_descending_subsequence.h"
20+
#include "../detail/longest_increasing_subsequence.h"
1921
#include "../detail/type_traits.h"
2022

2123
namespace cppsort::probe
@@ -49,10 +51,10 @@ namespace cppsort::probe
4951
// with the assumption that it's better than O(n) - which is at least
5052
// consistent as far as the standard library is concerned. We also
5153
// handle C arrays whose size is known and part of the type.
52-
auto res = cppsort::detail::longest_non_descending_subsequence<false>(
54+
auto res = cppsort::detail::longest_increasing_subsequence<false>(
5355
std::begin(range), std::end(range),
5456
utility::size(range),
55-
std::move(compare), std::move(projection)
57+
cppsort::not_fn(cppsort::flip(compare)), std::move(projection)
5658
);
5759
auto lnds_size = res.second - res.first;
5860
return lnds_size >= 0 ? lnds_size : 0;
@@ -73,8 +75,9 @@ namespace cppsort::probe
7375
// We give 0 as a "dummy" value since it will be recomputed, but it
7476
// is also used by the non-random-access iterators version as the
7577
// initial value used for the size count
76-
auto res = cppsort::detail::longest_non_descending_subsequence<true>(
77-
first, last, 0, std::move(compare), std::move(projection)
78+
auto res = cppsort::detail::longest_increasing_subsequence<true>(
79+
first, last, 0,
80+
cppsort::not_fn(cppsort::flip(compare)), std::move(projection)
7881
);
7982
auto lnds_size = res.second - res.first;
8083
return lnds_size >= 0 ? lnds_size : 0;

include/cpp-sort/probes/sus.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
////////////////////////////////////////////////////////////
1111
#include <functional>
1212
#include <utility>
13-
#include <cpp-sort/comparators/not_fn.h>
13+
#include <cpp-sort/comparators/flip.h>
1414
#include <cpp-sort/sorter_facade.h>
1515
#include <cpp-sort/sorter_traits.h>
1616
#include <cpp-sort/utility/functional.h>
17-
#include "../detail/longest_non_descending_subsequence.h"
17+
#include "../detail/longest_increasing_subsequence.h"
1818
#include "../detail/type_traits.h"
1919

2020
namespace cppsort::probe
@@ -37,10 +37,10 @@ namespace cppsort::probe
3737
{
3838
// We don't need the size information, so we can avoid
3939
// computing it altogether
40-
auto res = cppsort::detail::longest_non_descending_subsequence<false>(
40+
auto res = cppsort::detail::longest_increasing_subsequence<false>(
4141
first, last,
4242
0, // Dummy value, not useful here
43-
cppsort::not_fn(compare), std::move(projection)
43+
cppsort::flip(compare), std::move(projection)
4444
);
4545
return res.first > 0 ? res.first - 1 : 0;
4646
}

0 commit comments

Comments
 (0)