C++ String Interview Question

后端 未结 7 1203
悲哀的现实
悲哀的现实 2021-02-13 18:22

I was recently in a C++ technical interview, where I was given a bit of simple string manipulation code, which is intended to take a string and return a string that is comprised

相关标签:
7条回答
  • 2021-02-13 18:56
    // compiled with cl /Ox first_last_n.cpp /W4 /EHsc
    
    inline void
    first_last_n2(string::size_type n, const std::string &s, string &out)  // method 2
    {
      // check against degenerate input
      assert(n > 0);
      assert(n <= s.size());
    
      out.reserve(2*n);
      out.assign(s, 0, n);
      out.append(s, s.size()-n, n);
    }
    

    Times:

    method 1:  // original method
    2.281
    method 2:  // my method
    0.687
    method 3:  // your code.
    0.782
    

    Note: Timing specifically tests "long" strings. I.e. those where short string optimization is not used. (My strings were 100 length).

    0 讨论(0)
  • 2021-02-13 19:07

    My only thought is that if this function is only called with C null-terminated strings, you might be requiring the extra construction of a std::string for parameter 's'.

    Possibly the 'more' efficient method would be to allow either a std::string or const char *s passed in.

    0 讨论(0)
  • 2021-02-13 19:08

    If you don't need to maintain the contents of the original string, then you can copy the last n characters into positions [n+1, 2n] of the original string and truncate it at 2n. You will have to be careful to first expand the string and also be careful not to overwrite any characters before writing to them if the string is shorter than 2n.

    This will halve the number of operations to construct the string, as well as remove the need to create a new string. So its theoretically between 2 and 4 times faster. But of course you have just destroyed the original string, which you'd have to ask the interviewer if it is acceptable.

    0 讨论(0)
  • 2021-02-13 19:12

    Memcpy is a cheat?

    #include <cstring>
    #include <iostream>
    #include <string>
    
    std::string first_last_n(int n, const std::string& s)
    {
      if (s.size() < n)
          return "";
    
        char str[n*2];
        memcpy(str, s.data(), n);
        memcpy(str+n, s.data() + s.size()-n, n);
    
        return (const char *)str;
    }
    
    int main()
    {
        std::cout << first_last_n(2, "123454321") << std::endl;
    }
    

    EDIT So I removed the other one. This is not a cheat.

    0 讨论(0)
  • 2021-02-13 19:15

    How about removing the middle N-2n characters, where N is the length of the source string?

    0 讨论(0)
  • 2021-02-13 19:17

    If you must pass the tests then you're going to have to write inefficient code, because you must return a copy of a string. This implies you must use dynamic allocation, possibly multiple times because of the copy.

    So change the tests and change the signature.

    template<class Out>
    Out first_last_n(const std::string::size_type& n, const std::string& s, Out r)
    {
        r = copy_n(s.begin(), n, r);
        std::string::const_iterator pos(s.end());
        std::advance(pos, -n);
        return copy_n(pos, n, r);
    }
    

    Then call it like so:

    std::string s("Hello world!");
    char r[5];
    r[4] = 0;
    first_last_n(2, s, r);
    

    This allows you to use dynamic programming, and it eliminates the need of dynamic allocation in the function.

    I like my algorithms minimalistic, and I purposely eliminated the check for n being smaller or equal to the size of the string. I replace the check with a pre-condition for the function. Preconditions are faster than checks: they have zero overhead.

    0 讨论(0)
提交回复
热议问题