I need to order values in a range so the range represent a chain.
struct Link
{
int id;
int next;
};
The values of Link::id
and Link::next
are arbitrary, and do not provide any semantic meaning by them selves (not for the ordering algorithm any way).
The relationship between two links (after ordering) is: lhs.next
is exactly rhs.id
.
preconditions
range
is guaranteed to hold values that can be ordered into exactly one chain.Example:
std::vector< Link> range{ { 4, 1}, { 1, 5}, { 3, 4}, { 2, 3}};
auto chain = some_algorithm( range);
// expect the ordering to be: { { 2, 3}, { 3, 4}, { 4, 1}, { 1, 5}};
I can think of at least two approaches, but I suspect this has been solved in an idiomatic way. So, my question is: how to solve this in an idiomatic way?
答案 0 :(得分:4)
I doubt that there is a idiomatic way because this isn't a common case.
Chaining is mostly done by pointers/iterators (e.g. std::list
) and the actual chaining is mostly done while inserting.
The interesting thing would be to find the first link and what to do with circular chaining and with error cases.
答案 1 :(得分:0)
这是我想出的:
“概念” R是某种表现形式,类似于 range 的类型,可以是容器,也可以是其他类型。
如果range
中有空格(链接方式),将对新链进行排序。我不想有一些“断言输出”或抛出。我仍然保持自己的目标,因为在用例中,我知道所有值都可以精确地形成一个链。
template< typename R, typename ISP>
R chain( R range, ISP is_link_predicate)
{
auto first = std::begin( range);
auto current = first;
const auto last = std::end( range);
while( current != last)
{
const auto next = current + 1;
// try to find a value in [next, last) that can be linked with *current.
auto link = std::find_if( next, last, [current,is_link_predicate]( auto& value){
return is_link_predicate( *current, value);
});
if( link != last)
{
using std::swap;
swap( *next, *link);
current = next;
}
else
{
// we need to check if some value in [next, last) can be "inserted" in the
// beginning of the chain. That is, can form a link with *first.
auto new_first = std::find_if( next, last, [first,is_link_predicate]( auto& value){
return is_link_predicate( value, *first);
});
if( new_first != last)
{
// we got a new_first, we need to rotate it first
//
// C = current
// N = next (not ordered).
// - = ordered values
// = = not ordered values
// X = value to be "inserted" first, new_first
//
// -----CN====X=== we start with
// X-----C======== we end up with
//
std::rotate( first, new_first, new_first + 1);
current = next;
}
else
{
// no values in [next, last) is part of the current chain.
// we start building the next chain.
current = next;
first = current;
}
}
}
return range;
}
评论?
答案 2 :(得分:0)
首先,您要做的不是排序,因此请注意排序。您永远无法判断A
是在B
之前还是之后,您只能判断A
可以在B
之前精确地为1还是在A1..An
之后精确地为1。因此,排序无法在这里为您提供帮助,甚至拓扑排序也无济于事。
一种算法:对链X
进行回溯,搜索所有可以与其链接的元素A1..AnX
,例如XA1..An
或RewriteEngine On
# If we receive a forwarded http request from a proxy...
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
# ...or just a plain old http request directly from the client
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
# Redirect to https version
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
,然后对新链重复上述步骤。起始链是空链,任何元素都可以链接。