Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8235185
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 7, 20262026-06-07T18:43:13+00:00 2026-06-07T18:43:13+00:00

I was curious how std:next_permutation was implemented so I extracted the the gnu libstdc++

  • 0

I was curious how std:next_permutation was implemented so I extracted the the gnu libstdc++ 4.7 version and sanitized the identifiers and formatting to produce the following demo…

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

template<typename It>
bool next_permutation(It begin, It end)
{
        if (begin == end)
                return false;

        It i = begin;
        ++i;
        if (i == end)
                return false;

        i = end;
        --i;

        while (true)
        {
                It j = i;
                --i;

                if (*i < *j)
                {
                        It k = end;

                        while (!(*i < *--k))
                                /* pass */;

                        iter_swap(i, k);
                        reverse(j, end);
                        return true;
                }

                if (i == begin)
                {
                        reverse(begin, end);
                        return false;
                }
        }
}

int main()
{
        vector<int> v = { 1, 2, 3, 4 };

        do
        {
                for (int i = 0; i < 4; i++)
                {
                        cout << v[i] << " ";
                }
                cout << endl;
        }
        while (::next_permutation(v.begin(), v.end()));
}

The output is as expected: http://ideone.com/4nZdx

My questions are: How does it work? What is the meaning of i, j and k? What value do they hold at the different parts of execution? What is a sketch of a proof of its correctness?

Clearly before entering the main loop it just checks the trivial 0 or 1 element list cases. At entry of the main loop i is pointing to the last element (not one past end) and the list is at least 2 elements long.

What is going on in the body of the main loop?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-07T18:43:15+00:00Added an answer on June 7, 2026 at 6:43 pm

    Let’s look at some permutations:

    1 2 3 4
    1 2 4 3
    1 3 2 4
    1 3 4 2
    1 4 2 3
    1 4 3 2
    2 1 3 4
    ...
    

    How do we go from one permutation to the next? Firstly, let’s look at things a little differently. We can view the elements as digits and the permutations as numbers. Viewing the problem in this way we want to order the permutations/numbers in “ascending” order.

    When we order numbers we want to “increase them by the smallest amount”. For example when counting we don’t count 1, 2, 3, 10, … because there are still 4, 5, … in between and although 10 is larger than 3, there are missing numbers which can be gotten by increasing 3 by a smaller amount. In the example above we see that 1 stays as the first number for a long time as there are many reorderings of the last 3 “digits” which “increase” the permutation by a smaller amount.

    So when do we finally “use” the 1? When there are only no more permutations of the last 3 digits.
    And when are there no more permutations of the last 3 digits? When the last 3 digits are in descending order.

    Aha! This is key to understanding the algorithm. We only change the position of a “digit” when everything to the right is in descending order because if it isn’t in descending order then there are still more permutations to go (ie we can “increase” the permutation by a smaller amount).

    Let’s now go back to the code:

    while (true)
    {
        It j = i;
        --i;
    
        if (*i < *j)
        { // ...
        }
    
        if (i == begin)
        { // ...
        }
    }
    

    From the first 2 lines in the loop, j is an element and i is the element before it.
    Then, if the elements are in ascending order, (if (*i < *j)) do something.
    Otherwise, if the whole thing is in descending order, (if (i == begin)) then this is the last permutation.
    Otherwise, we continue and we see that j and i are essentially decremented.

    We now understand the if (i == begin) part so all we need to understand is the if (*i < *j) part.

    Also note: “Then if the elements are in ascending order …” which supports our previous observation that we only need to do something to a digit “when everything to the right is in descending order”. The ascending order if statement is essentially finding the leftmost place where “everything to the right is in descending order”.

    Let’s look again at some examples:

    ...
    1 4 3 2
    2 1 3 4
    ...
    2 4 3 1
    3 1 2 4
    ...
    

    We see that when everything to the right of a digit is in descending order, we find the next largest digit and put it in front and then put the remaining digits in ascending order.

    Let’s look at the code:

    It k = end;
    
    while (!(*i < *--k))
        /* pass */;
    
    iter_swap(i, k);
    reverse(j, end);
    return true;
    

    Well, since the things to the right are in descending order, to find the “next largest digit” we just have to iterate from the end, which we see in the first 3 lines of code.

    Next, we swap the “next largest digit” to the front with the iter_swap() statement and then since we know that digit was the next largest, we know that the digits to the right are still in descending order, so to put it in ascending order, we just have to reverse() it.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Please let us consider following code: #include <iostream> using namespace std; union{ int i;
I have the following code which works as expected: #include <iostream> using namespace std;
I am curious if std::cout has a return value, because when I do this:
...well, I got strange results! I was curious about the performance of std::vector vs.
Possible Duplicate: std::string and its automatic memory resizing I am just curious, how are
I wanted to write a unicode version of std::exception and std::runtime_error. So I thought
I have a simple C++ program: #include <iostream> int main() { std::cout << "Hello\n";
I was curious as to whether the following scenario is safe. I have the
Consider this example: #include <algorithm> #include <iostream> int main() { std::string str = abcde4fghijk4l5mnopqrs6t8uvwxyz;
I am just a bit curious about the new function std::move() that has just

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.