Java TreeMap.floorKey() equivalent for std::mapThread-safe std::map accessorUtilizing std::map and std::array for displaying a modulus gridImplementation of std::mapcontains() algorithm for std::vectorSentinel based find with conditional fallback to std::findC++ Trie using std::map and std::unique_ptrstd::map with random orderSpecializing std::hash for std::arraystd::vector for podsImprovement for std::map <int, run_some_function> double dispatch

What happens to Cessna electric flaps that are moving when power is lost?

How large would a mega structure have to be to host 1 billion people indefinitely?

Dates on degrees don’t make sense – will people care?

What does it mean to "control target player"?

Suggested order for Amazon Prime Doctor Who series

Silly doubt about tidal effects and Einstein Field Equations

Would it be a copyright violation if I made a character’s full name refer to a song?

Did the CIA blow up a Siberian pipeline in 1982?

Can humans ever directly see a few photons at a time? Can a human see a single photon?

How to make clear to people I don't want to answer their "Where are you from?" question?

What happens when auto number reaches its pre-set max?

Can there be an UN resolution to remove a country from the UNSC?

Parameterize chained calls to a utility program in Bash

How long would it take to cross the Channel in 1890's?

Has there been any indication at all that further negotiation between the UK and EU is possible?

Why do textbooks often include the solutions to odd or even numbered problems but not both?

Prime sieve in Python

What reason would an alien civilization have for building a Dyson Sphere (or Swarm) if cheap Nuclear fusion is available?

What could exist inside and between the walls of a Dyson Sphere?

Is a single radon-daughter atom in air a solid?

Do I have to explain the mechanical superiority of the player-character within the fiction of the game?

What exactly is the 'online' in OLAP and OLTP?

How to find the last non zero element in every column throughout dataframe?

Hot coffee brewing solutions for deep woods camping



Java TreeMap.floorKey() equivalent for std::map


Thread-safe std::map accessorUtilizing std::map and std::array for displaying a modulus gridImplementation of std::mapcontains() algorithm for std::vectorSentinel based find with conditional fallback to std::findC++ Trie using std::map and std::unique_ptrstd::map with random orderSpecializing std::hash for std::arraystd::vector for podsImprovement for std::map <int, run_some_function> double dispatch






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








1












$begingroup$


I wanted something equivalent to this Java program:




TreeMap<Integer,Integer> map = new TreeMap<Integer,Integer>();
map.put(10, 100);
map.put(20, 200);
map.put(30, 300);
map.put(40, 400);
map.put(50, 500);
map.put(60, 600);
map.put(70, 700);
map.put(80, 800);

System.out.println(map.floorKey(5));
System.out.println(map.floorKey(9));
System.out.println(map.floorKey(10));
System.out.println(map.floorKey(11));
System.out.println(map.floorKey(90));



output:




null null 10 10 80



As there is no direct API to achieve the same in C++, I wrote the following code to implement a similar floorKey() function:



template <typename key,typename value>
int floorKey(map<key, value> input, int key)

auto begin = input.begin();
if (begin->first > key)//if key is less than the first key. It must retrun -1;
return -1;

auto end = input.end();
end--;
if (end->first < key)//if key is greater than last key, it must return last key
return end->first;

//if key is equal to any existing key, it should return the key
auto find = input.find(key);

if (find != input.end())
return key;

//Return the floor key for the given key
auto lower = input.lower_bound(key);

lower--;
return lower->first;



Here's the test program:



int main()

map<int, int> map;
map.insert( 10, 100 );
map.insert( 20, 200 );
map.insert( 30, 300 );
map.insert( 40, 400 );
map.insert( 50, 500 );
map.insert( 60, 600 );
map.insert( 70, 700 );
map.insert( 80, 800 );


cout << floorKey(map, 5) << endl;
cout << floorKey(map, 9) << endl;
cout << floorKey(map, 10) << endl;
cout << floorKey(map, 11) << endl;
cout << floorKey(map, 90) << endl;
return 0;



output:




-1 -1 10 10 80



Is there any better way to get the same? Anything else I can improve?










share|improve this question









New contributor



santosh kumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$


















    1












    $begingroup$


    I wanted something equivalent to this Java program:




    TreeMap<Integer,Integer> map = new TreeMap<Integer,Integer>();
    map.put(10, 100);
    map.put(20, 200);
    map.put(30, 300);
    map.put(40, 400);
    map.put(50, 500);
    map.put(60, 600);
    map.put(70, 700);
    map.put(80, 800);

    System.out.println(map.floorKey(5));
    System.out.println(map.floorKey(9));
    System.out.println(map.floorKey(10));
    System.out.println(map.floorKey(11));
    System.out.println(map.floorKey(90));



    output:




    null null 10 10 80



    As there is no direct API to achieve the same in C++, I wrote the following code to implement a similar floorKey() function:



    template <typename key,typename value>
    int floorKey(map<key, value> input, int key)

    auto begin = input.begin();
    if (begin->first > key)//if key is less than the first key. It must retrun -1;
    return -1;

    auto end = input.end();
    end--;
    if (end->first < key)//if key is greater than last key, it must return last key
    return end->first;

    //if key is equal to any existing key, it should return the key
    auto find = input.find(key);

    if (find != input.end())
    return key;

    //Return the floor key for the given key
    auto lower = input.lower_bound(key);

    lower--;
    return lower->first;



    Here's the test program:



    int main()

    map<int, int> map;
    map.insert( 10, 100 );
    map.insert( 20, 200 );
    map.insert( 30, 300 );
    map.insert( 40, 400 );
    map.insert( 50, 500 );
    map.insert( 60, 600 );
    map.insert( 70, 700 );
    map.insert( 80, 800 );


    cout << floorKey(map, 5) << endl;
    cout << floorKey(map, 9) << endl;
    cout << floorKey(map, 10) << endl;
    cout << floorKey(map, 11) << endl;
    cout << floorKey(map, 90) << endl;
    return 0;



    output:




    -1 -1 10 10 80



    Is there any better way to get the same? Anything else I can improve?










    share|improve this question









    New contributor



    santosh kumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






    $endgroup$














      1












      1








      1





      $begingroup$


      I wanted something equivalent to this Java program:




      TreeMap<Integer,Integer> map = new TreeMap<Integer,Integer>();
      map.put(10, 100);
      map.put(20, 200);
      map.put(30, 300);
      map.put(40, 400);
      map.put(50, 500);
      map.put(60, 600);
      map.put(70, 700);
      map.put(80, 800);

      System.out.println(map.floorKey(5));
      System.out.println(map.floorKey(9));
      System.out.println(map.floorKey(10));
      System.out.println(map.floorKey(11));
      System.out.println(map.floorKey(90));



      output:




      null null 10 10 80



      As there is no direct API to achieve the same in C++, I wrote the following code to implement a similar floorKey() function:



      template <typename key,typename value>
      int floorKey(map<key, value> input, int key)

      auto begin = input.begin();
      if (begin->first > key)//if key is less than the first key. It must retrun -1;
      return -1;

      auto end = input.end();
      end--;
      if (end->first < key)//if key is greater than last key, it must return last key
      return end->first;

      //if key is equal to any existing key, it should return the key
      auto find = input.find(key);

      if (find != input.end())
      return key;

      //Return the floor key for the given key
      auto lower = input.lower_bound(key);

      lower--;
      return lower->first;



      Here's the test program:



      int main()

      map<int, int> map;
      map.insert( 10, 100 );
      map.insert( 20, 200 );
      map.insert( 30, 300 );
      map.insert( 40, 400 );
      map.insert( 50, 500 );
      map.insert( 60, 600 );
      map.insert( 70, 700 );
      map.insert( 80, 800 );


      cout << floorKey(map, 5) << endl;
      cout << floorKey(map, 9) << endl;
      cout << floorKey(map, 10) << endl;
      cout << floorKey(map, 11) << endl;
      cout << floorKey(map, 90) << endl;
      return 0;



      output:




      -1 -1 10 10 80



      Is there any better way to get the same? Anything else I can improve?










      share|improve this question









      New contributor



      santosh kumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      $endgroup$




      I wanted something equivalent to this Java program:




      TreeMap<Integer,Integer> map = new TreeMap<Integer,Integer>();
      map.put(10, 100);
      map.put(20, 200);
      map.put(30, 300);
      map.put(40, 400);
      map.put(50, 500);
      map.put(60, 600);
      map.put(70, 700);
      map.put(80, 800);

      System.out.println(map.floorKey(5));
      System.out.println(map.floorKey(9));
      System.out.println(map.floorKey(10));
      System.out.println(map.floorKey(11));
      System.out.println(map.floorKey(90));



      output:




      null null 10 10 80



      As there is no direct API to achieve the same in C++, I wrote the following code to implement a similar floorKey() function:



      template <typename key,typename value>
      int floorKey(map<key, value> input, int key)

      auto begin = input.begin();
      if (begin->first > key)//if key is less than the first key. It must retrun -1;
      return -1;

      auto end = input.end();
      end--;
      if (end->first < key)//if key is greater than last key, it must return last key
      return end->first;

      //if key is equal to any existing key, it should return the key
      auto find = input.find(key);

      if (find != input.end())
      return key;

      //Return the floor key for the given key
      auto lower = input.lower_bound(key);

      lower--;
      return lower->first;



      Here's the test program:



      int main()

      map<int, int> map;
      map.insert( 10, 100 );
      map.insert( 20, 200 );
      map.insert( 30, 300 );
      map.insert( 40, 400 );
      map.insert( 50, 500 );
      map.insert( 60, 600 );
      map.insert( 70, 700 );
      map.insert( 80, 800 );


      cout << floorKey(map, 5) << endl;
      cout << floorKey(map, 9) << endl;
      cout << floorKey(map, 10) << endl;
      cout << floorKey(map, 11) << endl;
      cout << floorKey(map, 90) << endl;
      return 0;



      output:




      -1 -1 10 10 80



      Is there any better way to get the same? Anything else I can improve?







      c++ search






      share|improve this question









      New contributor



      santosh kumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.










      share|improve this question









      New contributor



      santosh kumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      share|improve this question




      share|improve this question








      edited 7 hours ago









      Toby Speight

      29.7k745128




      29.7k745128






      New contributor



      santosh kumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      asked 8 hours ago









      santosh kumarsantosh kumar

      1061




      1061




      New contributor



      santosh kumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




      New contributor




      santosh kumar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          3 Answers
          3






          active

          oldest

          votes


















          5












          $begingroup$

          Headers and namespaces



          The function is missing a definition of map. This is probably what you want:



          #include <map>

          using std::map;


          Similarly, the main() needs:



          #include <iostream>
          using std::cout;
          using std::endl;


          That said, there's no good reason for std::endl in this code: an ordinary newline is sufficient, and we don't need the extra flushing behaviour of std::endl.



          Naming



          It's an error to use the typename key as the name of a parameter here:




          template <typename key,typename value>
          int floorKey(map<key, value> input, int key)



          It's pretty idiomatic to use PascalCase for template arguments, to distinguish them from function parameters:



          template<typename Key, typename Value>
          int floorKey(std::map<Key, Value> input, Key key)


          (I've also corrected the function to accept the correct type for the key argument).



          Don't pass containers by value



          We have a potentially large map, which we don't need to modify. That suggests that it's better passed as a reference to a const object. As we don't know the type of the key, we should probably assume that it's also better passed by reference (it could plausibly be a std::string, for example). That gives us:



          template<typename Key, typename Value>
          int floorKey(const std::map<Key, Value>& input, const Key& key)


          It's good that we used auto for the iterators begin and end, as it means that we don't need to change the body of the function to deal with them both now being const iterators.



          Algorithm



          There's really no need to search for an exactly matching key if we then go on to call lower_bound() - we could just call upper_bound() instead, which will find the first key greater than key, and decrement (if valid) to get the result:



          auto it = input.upper_bound(key);

          return it == input.begin()
          ? -1
          : (--it)->first;


          Note that we have a problem here: if Key isn't a signed numeric type, then we can't return -1. We really need a type-dependent value for this.




          Modified code



          #include <map>

          template<typename Key, typename Value>
          const Key& floorKey(const std::map<Key, Value>& input,
          const Key& key, const Key& default_value = )

          auto it = input.upper_bound(key);

          return it == input.begin()
          ? default_value
          : (--it)->first;





          #include <iostream>

          int main()

          std::map<int, int> map =

          10, 100 ,
          20, 200 ,
          30, 300 ,
          40, 400 ,
          50, 500 ,
          60, 600 ,
          70, 700 ,
          80, 800 ,
          ;


          std::cout << floorKey(map, 5, -1) << 'n'
          << floorKey(map, 9, -1) << 'n'
          << floorKey(map, 10, -1) << 'n'
          << floorKey(map, 11, -1) << 'n'
          << floorKey(map, 90, -1) << 'n';






          share|improve this answer











          $endgroup$




















            4












            $begingroup$

            Your code is obviously wrong:



            template <typename key,typename value>


            This line suggests that the code works for arbitrary maps, yet you require an int key, no matter what the key type of the map is.



            Returning -1 is not proper C++ style. You should return an iterator, as all other container functions do.



            Passing the map by value makes an unnecessary copy of the whole map. Use a const & instead.






            share|improve this answer









            $endgroup$




















              2












              $begingroup$

              You know about lower_bound/upper_bound, why not use just once and then see if the iterator is at the beginning and where the key in the returned iterator lands compared to the given key?



              template <typename key,typename value>
              int floorKey(map<key, value> input, int key)

              auto greater = input.upper_bound(key);

              if(greater == input.begin())
              return -1;

              assert(greater->first > key);

              --greater;
              return greater->first;



              upper_bound always returns and iterator that is just past the key. So decrement I it to get the floor.






              share|improve this answer











              $endgroup$












              • $begingroup$
                Where is lower declared and initialized?
                $endgroup$
                – Toby Speight
                3 hours ago













              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: "196"
              ;
              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',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              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
              );



              );






              santosh kumar is a new contributor. Be nice, and check out our Code of Conduct.









              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222587%2fjava-treemap-floorkey-equivalent-for-stdmap%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              5












              $begingroup$

              Headers and namespaces



              The function is missing a definition of map. This is probably what you want:



              #include <map>

              using std::map;


              Similarly, the main() needs:



              #include <iostream>
              using std::cout;
              using std::endl;


              That said, there's no good reason for std::endl in this code: an ordinary newline is sufficient, and we don't need the extra flushing behaviour of std::endl.



              Naming



              It's an error to use the typename key as the name of a parameter here:




              template <typename key,typename value>
              int floorKey(map<key, value> input, int key)



              It's pretty idiomatic to use PascalCase for template arguments, to distinguish them from function parameters:



              template<typename Key, typename Value>
              int floorKey(std::map<Key, Value> input, Key key)


              (I've also corrected the function to accept the correct type for the key argument).



              Don't pass containers by value



              We have a potentially large map, which we don't need to modify. That suggests that it's better passed as a reference to a const object. As we don't know the type of the key, we should probably assume that it's also better passed by reference (it could plausibly be a std::string, for example). That gives us:



              template<typename Key, typename Value>
              int floorKey(const std::map<Key, Value>& input, const Key& key)


              It's good that we used auto for the iterators begin and end, as it means that we don't need to change the body of the function to deal with them both now being const iterators.



              Algorithm



              There's really no need to search for an exactly matching key if we then go on to call lower_bound() - we could just call upper_bound() instead, which will find the first key greater than key, and decrement (if valid) to get the result:



              auto it = input.upper_bound(key);

              return it == input.begin()
              ? -1
              : (--it)->first;


              Note that we have a problem here: if Key isn't a signed numeric type, then we can't return -1. We really need a type-dependent value for this.




              Modified code



              #include <map>

              template<typename Key, typename Value>
              const Key& floorKey(const std::map<Key, Value>& input,
              const Key& key, const Key& default_value = )

              auto it = input.upper_bound(key);

              return it == input.begin()
              ? default_value
              : (--it)->first;





              #include <iostream>

              int main()

              std::map<int, int> map =

              10, 100 ,
              20, 200 ,
              30, 300 ,
              40, 400 ,
              50, 500 ,
              60, 600 ,
              70, 700 ,
              80, 800 ,
              ;


              std::cout << floorKey(map, 5, -1) << 'n'
              << floorKey(map, 9, -1) << 'n'
              << floorKey(map, 10, -1) << 'n'
              << floorKey(map, 11, -1) << 'n'
              << floorKey(map, 90, -1) << 'n';






              share|improve this answer











              $endgroup$

















                5












                $begingroup$

                Headers and namespaces



                The function is missing a definition of map. This is probably what you want:



                #include <map>

                using std::map;


                Similarly, the main() needs:



                #include <iostream>
                using std::cout;
                using std::endl;


                That said, there's no good reason for std::endl in this code: an ordinary newline is sufficient, and we don't need the extra flushing behaviour of std::endl.



                Naming



                It's an error to use the typename key as the name of a parameter here:




                template <typename key,typename value>
                int floorKey(map<key, value> input, int key)



                It's pretty idiomatic to use PascalCase for template arguments, to distinguish them from function parameters:



                template<typename Key, typename Value>
                int floorKey(std::map<Key, Value> input, Key key)


                (I've also corrected the function to accept the correct type for the key argument).



                Don't pass containers by value



                We have a potentially large map, which we don't need to modify. That suggests that it's better passed as a reference to a const object. As we don't know the type of the key, we should probably assume that it's also better passed by reference (it could plausibly be a std::string, for example). That gives us:



                template<typename Key, typename Value>
                int floorKey(const std::map<Key, Value>& input, const Key& key)


                It's good that we used auto for the iterators begin and end, as it means that we don't need to change the body of the function to deal with them both now being const iterators.



                Algorithm



                There's really no need to search for an exactly matching key if we then go on to call lower_bound() - we could just call upper_bound() instead, which will find the first key greater than key, and decrement (if valid) to get the result:



                auto it = input.upper_bound(key);

                return it == input.begin()
                ? -1
                : (--it)->first;


                Note that we have a problem here: if Key isn't a signed numeric type, then we can't return -1. We really need a type-dependent value for this.




                Modified code



                #include <map>

                template<typename Key, typename Value>
                const Key& floorKey(const std::map<Key, Value>& input,
                const Key& key, const Key& default_value = )

                auto it = input.upper_bound(key);

                return it == input.begin()
                ? default_value
                : (--it)->first;





                #include <iostream>

                int main()

                std::map<int, int> map =

                10, 100 ,
                20, 200 ,
                30, 300 ,
                40, 400 ,
                50, 500 ,
                60, 600 ,
                70, 700 ,
                80, 800 ,
                ;


                std::cout << floorKey(map, 5, -1) << 'n'
                << floorKey(map, 9, -1) << 'n'
                << floorKey(map, 10, -1) << 'n'
                << floorKey(map, 11, -1) << 'n'
                << floorKey(map, 90, -1) << 'n';






                share|improve this answer











                $endgroup$















                  5












                  5








                  5





                  $begingroup$

                  Headers and namespaces



                  The function is missing a definition of map. This is probably what you want:



                  #include <map>

                  using std::map;


                  Similarly, the main() needs:



                  #include <iostream>
                  using std::cout;
                  using std::endl;


                  That said, there's no good reason for std::endl in this code: an ordinary newline is sufficient, and we don't need the extra flushing behaviour of std::endl.



                  Naming



                  It's an error to use the typename key as the name of a parameter here:




                  template <typename key,typename value>
                  int floorKey(map<key, value> input, int key)



                  It's pretty idiomatic to use PascalCase for template arguments, to distinguish them from function parameters:



                  template<typename Key, typename Value>
                  int floorKey(std::map<Key, Value> input, Key key)


                  (I've also corrected the function to accept the correct type for the key argument).



                  Don't pass containers by value



                  We have a potentially large map, which we don't need to modify. That suggests that it's better passed as a reference to a const object. As we don't know the type of the key, we should probably assume that it's also better passed by reference (it could plausibly be a std::string, for example). That gives us:



                  template<typename Key, typename Value>
                  int floorKey(const std::map<Key, Value>& input, const Key& key)


                  It's good that we used auto for the iterators begin and end, as it means that we don't need to change the body of the function to deal with them both now being const iterators.



                  Algorithm



                  There's really no need to search for an exactly matching key if we then go on to call lower_bound() - we could just call upper_bound() instead, which will find the first key greater than key, and decrement (if valid) to get the result:



                  auto it = input.upper_bound(key);

                  return it == input.begin()
                  ? -1
                  : (--it)->first;


                  Note that we have a problem here: if Key isn't a signed numeric type, then we can't return -1. We really need a type-dependent value for this.




                  Modified code



                  #include <map>

                  template<typename Key, typename Value>
                  const Key& floorKey(const std::map<Key, Value>& input,
                  const Key& key, const Key& default_value = )

                  auto it = input.upper_bound(key);

                  return it == input.begin()
                  ? default_value
                  : (--it)->first;





                  #include <iostream>

                  int main()

                  std::map<int, int> map =

                  10, 100 ,
                  20, 200 ,
                  30, 300 ,
                  40, 400 ,
                  50, 500 ,
                  60, 600 ,
                  70, 700 ,
                  80, 800 ,
                  ;


                  std::cout << floorKey(map, 5, -1) << 'n'
                  << floorKey(map, 9, -1) << 'n'
                  << floorKey(map, 10, -1) << 'n'
                  << floorKey(map, 11, -1) << 'n'
                  << floorKey(map, 90, -1) << 'n';






                  share|improve this answer











                  $endgroup$



                  Headers and namespaces



                  The function is missing a definition of map. This is probably what you want:



                  #include <map>

                  using std::map;


                  Similarly, the main() needs:



                  #include <iostream>
                  using std::cout;
                  using std::endl;


                  That said, there's no good reason for std::endl in this code: an ordinary newline is sufficient, and we don't need the extra flushing behaviour of std::endl.



                  Naming



                  It's an error to use the typename key as the name of a parameter here:




                  template <typename key,typename value>
                  int floorKey(map<key, value> input, int key)



                  It's pretty idiomatic to use PascalCase for template arguments, to distinguish them from function parameters:



                  template<typename Key, typename Value>
                  int floorKey(std::map<Key, Value> input, Key key)


                  (I've also corrected the function to accept the correct type for the key argument).



                  Don't pass containers by value



                  We have a potentially large map, which we don't need to modify. That suggests that it's better passed as a reference to a const object. As we don't know the type of the key, we should probably assume that it's also better passed by reference (it could plausibly be a std::string, for example). That gives us:



                  template<typename Key, typename Value>
                  int floorKey(const std::map<Key, Value>& input, const Key& key)


                  It's good that we used auto for the iterators begin and end, as it means that we don't need to change the body of the function to deal with them both now being const iterators.



                  Algorithm



                  There's really no need to search for an exactly matching key if we then go on to call lower_bound() - we could just call upper_bound() instead, which will find the first key greater than key, and decrement (if valid) to get the result:



                  auto it = input.upper_bound(key);

                  return it == input.begin()
                  ? -1
                  : (--it)->first;


                  Note that we have a problem here: if Key isn't a signed numeric type, then we can't return -1. We really need a type-dependent value for this.




                  Modified code



                  #include <map>

                  template<typename Key, typename Value>
                  const Key& floorKey(const std::map<Key, Value>& input,
                  const Key& key, const Key& default_value = )

                  auto it = input.upper_bound(key);

                  return it == input.begin()
                  ? default_value
                  : (--it)->first;





                  #include <iostream>

                  int main()

                  std::map<int, int> map =

                  10, 100 ,
                  20, 200 ,
                  30, 300 ,
                  40, 400 ,
                  50, 500 ,
                  60, 600 ,
                  70, 700 ,
                  80, 800 ,
                  ;


                  std::cout << floorKey(map, 5, -1) << 'n'
                  << floorKey(map, 9, -1) << 'n'
                  << floorKey(map, 10, -1) << 'n'
                  << floorKey(map, 11, -1) << 'n'
                  << floorKey(map, 90, -1) << 'n';







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 3 hours ago

























                  answered 6 hours ago









                  Toby SpeightToby Speight

                  29.7k745128




                  29.7k745128























                      4












                      $begingroup$

                      Your code is obviously wrong:



                      template <typename key,typename value>


                      This line suggests that the code works for arbitrary maps, yet you require an int key, no matter what the key type of the map is.



                      Returning -1 is not proper C++ style. You should return an iterator, as all other container functions do.



                      Passing the map by value makes an unnecessary copy of the whole map. Use a const & instead.






                      share|improve this answer









                      $endgroup$

















                        4












                        $begingroup$

                        Your code is obviously wrong:



                        template <typename key,typename value>


                        This line suggests that the code works for arbitrary maps, yet you require an int key, no matter what the key type of the map is.



                        Returning -1 is not proper C++ style. You should return an iterator, as all other container functions do.



                        Passing the map by value makes an unnecessary copy of the whole map. Use a const & instead.






                        share|improve this answer









                        $endgroup$















                          4












                          4








                          4





                          $begingroup$

                          Your code is obviously wrong:



                          template <typename key,typename value>


                          This line suggests that the code works for arbitrary maps, yet you require an int key, no matter what the key type of the map is.



                          Returning -1 is not proper C++ style. You should return an iterator, as all other container functions do.



                          Passing the map by value makes an unnecessary copy of the whole map. Use a const & instead.






                          share|improve this answer









                          $endgroup$



                          Your code is obviously wrong:



                          template <typename key,typename value>


                          This line suggests that the code works for arbitrary maps, yet you require an int key, no matter what the key type of the map is.



                          Returning -1 is not proper C++ style. You should return an iterator, as all other container functions do.



                          Passing the map by value makes an unnecessary copy of the whole map. Use a const & instead.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 7 hours ago









                          Roland IlligRoland Illig

                          13.8k12355




                          13.8k12355





















                              2












                              $begingroup$

                              You know about lower_bound/upper_bound, why not use just once and then see if the iterator is at the beginning and where the key in the returned iterator lands compared to the given key?



                              template <typename key,typename value>
                              int floorKey(map<key, value> input, int key)

                              auto greater = input.upper_bound(key);

                              if(greater == input.begin())
                              return -1;

                              assert(greater->first > key);

                              --greater;
                              return greater->first;



                              upper_bound always returns and iterator that is just past the key. So decrement I it to get the floor.






                              share|improve this answer











                              $endgroup$












                              • $begingroup$
                                Where is lower declared and initialized?
                                $endgroup$
                                – Toby Speight
                                3 hours ago















                              2












                              $begingroup$

                              You know about lower_bound/upper_bound, why not use just once and then see if the iterator is at the beginning and where the key in the returned iterator lands compared to the given key?



                              template <typename key,typename value>
                              int floorKey(map<key, value> input, int key)

                              auto greater = input.upper_bound(key);

                              if(greater == input.begin())
                              return -1;

                              assert(greater->first > key);

                              --greater;
                              return greater->first;



                              upper_bound always returns and iterator that is just past the key. So decrement I it to get the floor.






                              share|improve this answer











                              $endgroup$












                              • $begingroup$
                                Where is lower declared and initialized?
                                $endgroup$
                                – Toby Speight
                                3 hours ago













                              2












                              2








                              2





                              $begingroup$

                              You know about lower_bound/upper_bound, why not use just once and then see if the iterator is at the beginning and where the key in the returned iterator lands compared to the given key?



                              template <typename key,typename value>
                              int floorKey(map<key, value> input, int key)

                              auto greater = input.upper_bound(key);

                              if(greater == input.begin())
                              return -1;

                              assert(greater->first > key);

                              --greater;
                              return greater->first;



                              upper_bound always returns and iterator that is just past the key. So decrement I it to get the floor.






                              share|improve this answer











                              $endgroup$



                              You know about lower_bound/upper_bound, why not use just once and then see if the iterator is at the beginning and where the key in the returned iterator lands compared to the given key?



                              template <typename key,typename value>
                              int floorKey(map<key, value> input, int key)

                              auto greater = input.upper_bound(key);

                              if(greater == input.begin())
                              return -1;

                              assert(greater->first > key);

                              --greater;
                              return greater->first;



                              upper_bound always returns and iterator that is just past the key. So decrement I it to get the floor.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited 3 hours ago

























                              answered 8 hours ago









                              ratchet freakratchet freak

                              12.4k1344




                              12.4k1344











                              • $begingroup$
                                Where is lower declared and initialized?
                                $endgroup$
                                – Toby Speight
                                3 hours ago
















                              • $begingroup$
                                Where is lower declared and initialized?
                                $endgroup$
                                – Toby Speight
                                3 hours ago















                              $begingroup$
                              Where is lower declared and initialized?
                              $endgroup$
                              – Toby Speight
                              3 hours ago




                              $begingroup$
                              Where is lower declared and initialized?
                              $endgroup$
                              – Toby Speight
                              3 hours ago










                              santosh kumar is a new contributor. Be nice, and check out our Code of Conduct.









                              draft saved

                              draft discarded


















                              santosh kumar is a new contributor. Be nice, and check out our Code of Conduct.












                              santosh kumar is a new contributor. Be nice, and check out our Code of Conduct.











                              santosh kumar is a new contributor. Be nice, and check out our Code of Conduct.














                              Thanks for contributing an answer to Code Review Stack Exchange!


                              • 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.

                              Use MathJax to format equations. MathJax reference.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222587%2fjava-treemap-floorkey-equivalent-for-stdmap%23new-answer', 'question_page');

                              );

                              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







                              Popular posts from this blog

                              Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                              Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                              François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480