String manipulation with std::adjacent_findConverting between std::wstring and std::stringstd::vector memory manipulation with serialization and deserializationString manipulation in JavaStreambuffer and string manipulationMimic sprintf with std::string outputHomebrew std::string for use with kernelPrinting doubles using string manipulationDetermining if an std::string contains a numerical typeStudent class with std::stringstd::string implementation attempt

How to belay quickly ascending top-rope climbers?

Strategy to pay off revolving debt while building reserve savings fund?

Why are there few or no black super GMs?

Applying for jobs with an obvious scar

Is it possible to have a career in SciComp without contributing to arms research?

What was the difference between a Games Console and a Home Computer?

Does unblocking power bar outlets through short extension cords increase fire risk?

Is straight-up writing someone's opinions telling?

Is it legal for a supermarket to refuse to sell an adult beer if an adult with them doesn’t have their ID?

What could make large expeditions ineffective for exploring territory full of dangers and valuable resources?

Operation Unzalgo

How can one convert an expression to a string while keeping the quotation marks of strings that are part of the expression?

Why isn't a binary file shown as 0s and 1s?

How do you give a date interval with diffuse dates?

In this iconic lunar orbit rendezvous photo of John Houbolt, why do arrows #5 and #6 point the "wrong" way?

Can Error correction and detection be done with out adding extra bits?

Zhora asks Deckard: "Are you for real?" Was this meant to be significant?

Are there any Saints that have miraculously overcome death (should have died, but did not)?

The most secure way to handle someone forgetting to verify their account?

Is there a difference between PIO and GPIO pins?

Obtaining head and parts without evaluation

How can electric field be defined as force per charge, if the charge makes its own, singular electric field?

I have found a mistake on someone's code published online: what is the protocol?

How to remove the first colon ':' from a timestamp?



String manipulation with std::adjacent_find


Converting between std::wstring and std::stringstd::vector memory manipulation with serialization and deserializationString manipulation in JavaStreambuffer and string manipulationMimic sprintf with std::string outputHomebrew std::string for use with kernelPrinting doubles using string manipulationDetermining if an std::string contains a numerical typeStudent class with std::stringstd::string implementation attempt






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








6












$begingroup$



For the given strings (not containing numbers), print their shortened
versions, where each adjacent sequence of the same characters longer
than 2, change to an expression consisting of a sign and a number of
repetitions.




Sample input:



4
AAA
ABCDEF
CCCCCCDDDDDDD
ZZAACCCDDDDEEEEEE


Sample output:



A3
ABCDEF
C6D7
ZZAAC3D4E6


My code:



#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>

std::string reduce(std::string const& word)
std::string result;
for (auto it = word.cbegin(); true;)
auto curr = std::adjacent_find(it, word.cend(), std::not_equal_to<int>());
auto dist = std::distance(it, curr) + (curr != word.cend());

if (dist < 3)
result += std::string(dist, *it);
else
result += *it + std::to_string(dist);


if (curr == word.cend())
break;

it = 1 + curr;

return result;


int main()
std::size_t tests;
std::cin >> tests;
while (tests--)
std::string word;
std::cin >> word;
std::cout << reduce(word) << "n";




How could I simplify or improve this code?










share|improve this question











$endgroup$







  • 1




    $begingroup$
    Welcome to Code Review! Please see What to do when someone answers. I have rolled back Rev 4 → 3
    $endgroup$
    – Sᴀᴍ Onᴇᴌᴀ
    Jul 10 at 15:16

















6












$begingroup$



For the given strings (not containing numbers), print their shortened
versions, where each adjacent sequence of the same characters longer
than 2, change to an expression consisting of a sign and a number of
repetitions.




Sample input:



4
AAA
ABCDEF
CCCCCCDDDDDDD
ZZAACCCDDDDEEEEEE


Sample output:



A3
ABCDEF
C6D7
ZZAAC3D4E6


My code:



#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>

std::string reduce(std::string const& word)
std::string result;
for (auto it = word.cbegin(); true;)
auto curr = std::adjacent_find(it, word.cend(), std::not_equal_to<int>());
auto dist = std::distance(it, curr) + (curr != word.cend());

if (dist < 3)
result += std::string(dist, *it);
else
result += *it + std::to_string(dist);


if (curr == word.cend())
break;

it = 1 + curr;

return result;


int main()
std::size_t tests;
std::cin >> tests;
while (tests--)
std::string word;
std::cin >> word;
std::cout << reduce(word) << "n";




How could I simplify or improve this code?










share|improve this question











$endgroup$







  • 1




    $begingroup$
    Welcome to Code Review! Please see What to do when someone answers. I have rolled back Rev 4 → 3
    $endgroup$
    – Sᴀᴍ Onᴇᴌᴀ
    Jul 10 at 15:16













6












6








6





$begingroup$



For the given strings (not containing numbers), print their shortened
versions, where each adjacent sequence of the same characters longer
than 2, change to an expression consisting of a sign and a number of
repetitions.




Sample input:



4
AAA
ABCDEF
CCCCCCDDDDDDD
ZZAACCCDDDDEEEEEE


Sample output:



A3
ABCDEF
C6D7
ZZAAC3D4E6


My code:



#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>

std::string reduce(std::string const& word)
std::string result;
for (auto it = word.cbegin(); true;)
auto curr = std::adjacent_find(it, word.cend(), std::not_equal_to<int>());
auto dist = std::distance(it, curr) + (curr != word.cend());

if (dist < 3)
result += std::string(dist, *it);
else
result += *it + std::to_string(dist);


if (curr == word.cend())
break;

it = 1 + curr;

return result;


int main()
std::size_t tests;
std::cin >> tests;
while (tests--)
std::string word;
std::cin >> word;
std::cout << reduce(word) << "n";




How could I simplify or improve this code?










share|improve this question











$endgroup$





For the given strings (not containing numbers), print their shortened
versions, where each adjacent sequence of the same characters longer
than 2, change to an expression consisting of a sign and a number of
repetitions.




Sample input:



4
AAA
ABCDEF
CCCCCCDDDDDDD
ZZAACCCDDDDEEEEEE


Sample output:



A3
ABCDEF
C6D7
ZZAAC3D4E6


My code:



#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>

std::string reduce(std::string const& word)
std::string result;
for (auto it = word.cbegin(); true;)
auto curr = std::adjacent_find(it, word.cend(), std::not_equal_to<int>());
auto dist = std::distance(it, curr) + (curr != word.cend());

if (dist < 3)
result += std::string(dist, *it);
else
result += *it + std::to_string(dist);


if (curr == word.cend())
break;

it = 1 + curr;

return result;


int main()
std::size_t tests;
std::cin >> tests;
while (tests--)
std::string word;
std::cin >> word;
std::cout << reduce(word) << "n";




How could I simplify or improve this code?







c++ programming-challenge strings c++14






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jul 10 at 15:16









Sᴀᴍ Onᴇᴌᴀ

12.4k6 gold badges25 silver badges84 bronze badges




12.4k6 gold badges25 silver badges84 bronze badges










asked Jul 9 at 14:39









DessusDessus

356 bronze badges




356 bronze badges







  • 1




    $begingroup$
    Welcome to Code Review! Please see What to do when someone answers. I have rolled back Rev 4 → 3
    $endgroup$
    – Sᴀᴍ Onᴇᴌᴀ
    Jul 10 at 15:16












  • 1




    $begingroup$
    Welcome to Code Review! Please see What to do when someone answers. I have rolled back Rev 4 → 3
    $endgroup$
    – Sᴀᴍ Onᴇᴌᴀ
    Jul 10 at 15:16







1




1




$begingroup$
Welcome to Code Review! Please see What to do when someone answers. I have rolled back Rev 4 → 3
$endgroup$
– Sᴀᴍ Onᴇᴌᴀ
Jul 10 at 15:16




$begingroup$
Welcome to Code Review! Please see What to do when someone answers. I have rolled back Rev 4 → 3
$endgroup$
– Sᴀᴍ Onᴇᴌᴀ
Jul 10 at 15:16










2 Answers
2






active

oldest

votes


















5












$begingroup$

First impressions: nicely presented code; good use of the appropriate standard library functions and classes.



A minor suggestion would be to change the name, given that reduce is a well-known concept in functional programming (and is a function in <numeric>). Perhaps call it compress?



I'd suggest extracting the constant 3 to give it a meaningful name.



Can we eliminate the break with some reorganisation of the loop? Perhaps by using std::mismatch(it, it+1) instead of std::adjacent_find()? (I haven't fully thought that through; it might not be better.)



We can avoid constructing a new string here:




 result += std::string(dist, *it);



by using the overload of append() that takes two iterators:



 result.append(dist, *it);





share|improve this answer









$endgroup$




















    1












    $begingroup$

    A few things might be better, but you will need to measure if they actually help. (untested code)



    The most costly thing in your program (except the I/O) is properly allocation for the strings. So to avoid continuous reallocation you could try



    result.reserve(word.size());


    and



    constexpr int LargeBuffer 4096 ;
    std::string word;
    word.reserve(LargeBuffer); // reuse the buffer.
    while (tests--)
    std::cin >> word;
    std::cout << reduce(word) << "n"; // this call might use NRVO



    That might still trigger one allocation per word, so a more drastic rebuild could be



    std::string& reduce(std::string const& word, std::string & result)


    and



    constexpr int LargeBuffer 4096 ;
    std::string word, result;
    word.reserve(LargeBuffer); // reuse the buffer.
    result.reserve(LargeBuffer);
    while (tests--)
    std::cin >> word;
    result.clear(); // should not dealloc.
    std::cout << reduce(word, result) << "n";



    The strings will grow and keep their new size if the actual word is larger than expected.



    The next most expensive should be the std::to_string



     if (dist < 3) 
    result.append(dist, *it); // from Toby's answer
    else
    result.append(*it);
    if (dist < 10)
    result.append('0'+dist);
    else
    result.append(std::to_string(dist)); // hopefully we are saved here by short string optimisation




    The change should work nicely for your example data, less so if the repeats randomly change between <10 and >= 10.






    share|improve this answer









    $endgroup$















      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
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f223812%2fstring-manipulation-with-stdadjacent-find%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









      5












      $begingroup$

      First impressions: nicely presented code; good use of the appropriate standard library functions and classes.



      A minor suggestion would be to change the name, given that reduce is a well-known concept in functional programming (and is a function in <numeric>). Perhaps call it compress?



      I'd suggest extracting the constant 3 to give it a meaningful name.



      Can we eliminate the break with some reorganisation of the loop? Perhaps by using std::mismatch(it, it+1) instead of std::adjacent_find()? (I haven't fully thought that through; it might not be better.)



      We can avoid constructing a new string here:




       result += std::string(dist, *it);



      by using the overload of append() that takes two iterators:



       result.append(dist, *it);





      share|improve this answer









      $endgroup$

















        5












        $begingroup$

        First impressions: nicely presented code; good use of the appropriate standard library functions and classes.



        A minor suggestion would be to change the name, given that reduce is a well-known concept in functional programming (and is a function in <numeric>). Perhaps call it compress?



        I'd suggest extracting the constant 3 to give it a meaningful name.



        Can we eliminate the break with some reorganisation of the loop? Perhaps by using std::mismatch(it, it+1) instead of std::adjacent_find()? (I haven't fully thought that through; it might not be better.)



        We can avoid constructing a new string here:




         result += std::string(dist, *it);



        by using the overload of append() that takes two iterators:



         result.append(dist, *it);





        share|improve this answer









        $endgroup$















          5












          5








          5





          $begingroup$

          First impressions: nicely presented code; good use of the appropriate standard library functions and classes.



          A minor suggestion would be to change the name, given that reduce is a well-known concept in functional programming (and is a function in <numeric>). Perhaps call it compress?



          I'd suggest extracting the constant 3 to give it a meaningful name.



          Can we eliminate the break with some reorganisation of the loop? Perhaps by using std::mismatch(it, it+1) instead of std::adjacent_find()? (I haven't fully thought that through; it might not be better.)



          We can avoid constructing a new string here:




           result += std::string(dist, *it);



          by using the overload of append() that takes two iterators:



           result.append(dist, *it);





          share|improve this answer









          $endgroup$



          First impressions: nicely presented code; good use of the appropriate standard library functions and classes.



          A minor suggestion would be to change the name, given that reduce is a well-known concept in functional programming (and is a function in <numeric>). Perhaps call it compress?



          I'd suggest extracting the constant 3 to give it a meaningful name.



          Can we eliminate the break with some reorganisation of the loop? Perhaps by using std::mismatch(it, it+1) instead of std::adjacent_find()? (I haven't fully thought that through; it might not be better.)



          We can avoid constructing a new string here:




           result += std::string(dist, *it);



          by using the overload of append() that takes two iterators:



           result.append(dist, *it);






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jul 9 at 15:27









          Toby SpeightToby Speight

          30.8k7 gold badges45 silver badges133 bronze badges




          30.8k7 gold badges45 silver badges133 bronze badges























              1












              $begingroup$

              A few things might be better, but you will need to measure if they actually help. (untested code)



              The most costly thing in your program (except the I/O) is properly allocation for the strings. So to avoid continuous reallocation you could try



              result.reserve(word.size());


              and



              constexpr int LargeBuffer 4096 ;
              std::string word;
              word.reserve(LargeBuffer); // reuse the buffer.
              while (tests--)
              std::cin >> word;
              std::cout << reduce(word) << "n"; // this call might use NRVO



              That might still trigger one allocation per word, so a more drastic rebuild could be



              std::string& reduce(std::string const& word, std::string & result)


              and



              constexpr int LargeBuffer 4096 ;
              std::string word, result;
              word.reserve(LargeBuffer); // reuse the buffer.
              result.reserve(LargeBuffer);
              while (tests--)
              std::cin >> word;
              result.clear(); // should not dealloc.
              std::cout << reduce(word, result) << "n";



              The strings will grow and keep their new size if the actual word is larger than expected.



              The next most expensive should be the std::to_string



               if (dist < 3) 
              result.append(dist, *it); // from Toby's answer
              else
              result.append(*it);
              if (dist < 10)
              result.append('0'+dist);
              else
              result.append(std::to_string(dist)); // hopefully we are saved here by short string optimisation




              The change should work nicely for your example data, less so if the repeats randomly change between <10 and >= 10.






              share|improve this answer









              $endgroup$

















                1












                $begingroup$

                A few things might be better, but you will need to measure if they actually help. (untested code)



                The most costly thing in your program (except the I/O) is properly allocation for the strings. So to avoid continuous reallocation you could try



                result.reserve(word.size());


                and



                constexpr int LargeBuffer 4096 ;
                std::string word;
                word.reserve(LargeBuffer); // reuse the buffer.
                while (tests--)
                std::cin >> word;
                std::cout << reduce(word) << "n"; // this call might use NRVO



                That might still trigger one allocation per word, so a more drastic rebuild could be



                std::string& reduce(std::string const& word, std::string & result)


                and



                constexpr int LargeBuffer 4096 ;
                std::string word, result;
                word.reserve(LargeBuffer); // reuse the buffer.
                result.reserve(LargeBuffer);
                while (tests--)
                std::cin >> word;
                result.clear(); // should not dealloc.
                std::cout << reduce(word, result) << "n";



                The strings will grow and keep their new size if the actual word is larger than expected.



                The next most expensive should be the std::to_string



                 if (dist < 3) 
                result.append(dist, *it); // from Toby's answer
                else
                result.append(*it);
                if (dist < 10)
                result.append('0'+dist);
                else
                result.append(std::to_string(dist)); // hopefully we are saved here by short string optimisation




                The change should work nicely for your example data, less so if the repeats randomly change between <10 and >= 10.






                share|improve this answer









                $endgroup$















                  1












                  1








                  1





                  $begingroup$

                  A few things might be better, but you will need to measure if they actually help. (untested code)



                  The most costly thing in your program (except the I/O) is properly allocation for the strings. So to avoid continuous reallocation you could try



                  result.reserve(word.size());


                  and



                  constexpr int LargeBuffer 4096 ;
                  std::string word;
                  word.reserve(LargeBuffer); // reuse the buffer.
                  while (tests--)
                  std::cin >> word;
                  std::cout << reduce(word) << "n"; // this call might use NRVO



                  That might still trigger one allocation per word, so a more drastic rebuild could be



                  std::string& reduce(std::string const& word, std::string & result)


                  and



                  constexpr int LargeBuffer 4096 ;
                  std::string word, result;
                  word.reserve(LargeBuffer); // reuse the buffer.
                  result.reserve(LargeBuffer);
                  while (tests--)
                  std::cin >> word;
                  result.clear(); // should not dealloc.
                  std::cout << reduce(word, result) << "n";



                  The strings will grow and keep their new size if the actual word is larger than expected.



                  The next most expensive should be the std::to_string



                   if (dist < 3) 
                  result.append(dist, *it); // from Toby's answer
                  else
                  result.append(*it);
                  if (dist < 10)
                  result.append('0'+dist);
                  else
                  result.append(std::to_string(dist)); // hopefully we are saved here by short string optimisation




                  The change should work nicely for your example data, less so if the repeats randomly change between <10 and >= 10.






                  share|improve this answer









                  $endgroup$



                  A few things might be better, but you will need to measure if they actually help. (untested code)



                  The most costly thing in your program (except the I/O) is properly allocation for the strings. So to avoid continuous reallocation you could try



                  result.reserve(word.size());


                  and



                  constexpr int LargeBuffer 4096 ;
                  std::string word;
                  word.reserve(LargeBuffer); // reuse the buffer.
                  while (tests--)
                  std::cin >> word;
                  std::cout << reduce(word) << "n"; // this call might use NRVO



                  That might still trigger one allocation per word, so a more drastic rebuild could be



                  std::string& reduce(std::string const& word, std::string & result)


                  and



                  constexpr int LargeBuffer 4096 ;
                  std::string word, result;
                  word.reserve(LargeBuffer); // reuse the buffer.
                  result.reserve(LargeBuffer);
                  while (tests--)
                  std::cin >> word;
                  result.clear(); // should not dealloc.
                  std::cout << reduce(word, result) << "n";



                  The strings will grow and keep their new size if the actual word is larger than expected.



                  The next most expensive should be the std::to_string



                   if (dist < 3) 
                  result.append(dist, *it); // from Toby's answer
                  else
                  result.append(*it);
                  if (dist < 10)
                  result.append('0'+dist);
                  else
                  result.append(std::to_string(dist)); // hopefully we are saved here by short string optimisation




                  The change should work nicely for your example data, less so if the repeats randomly change between <10 and >= 10.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jul 9 at 22:21









                  SurtSurt

                  5122 silver badges8 bronze badges




                  5122 silver badges8 bronze badges



























                      draft saved

                      draft discarded
















































                      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%2f223812%2fstring-manipulation-with-stdadjacent-find%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

                      Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

                      Circuit construction for execution of conditional statements using least significant bitHow are two different registers being used as “control”?How exactly is the stated composite state of the two registers being produced using the $R_zz$ controlled rotations?Efficiently performing controlled rotations in HHLWould this quantum algorithm implementation work?How to prepare a superposed states of odd integers from $1$ to $sqrtN$?Why is this implementation of the order finding algorithm not working?Circuit construction for Hamiltonian simulationHow can I invert the least significant bit of a certain term of a superposed state?Implementing an oracleImplementing a controlled sum operation

                      Magento 2 “No Payment Methods” in Admin New OrderHow to integrate Paypal Express Checkout with the Magento APIMagento 1.5 - Sales > Order > edit order and shipping methods disappearAuto Invoice Check/Money Order Payment methodAdd more simple payment methods?Shipping methods not showingWhat should I do to change payment methods if changing the configuration has no effects?1.9 - No Payment Methods showing upMy Payment Methods not Showing for downloadable/virtual product when checkout?Magento2 API to access internal payment methodHow to call an existing payment methods in the registration form?