Home c Strlen () on si in one line

Strlen () on si in one line

Author

Date

Category

Davlya visited the interview, one of the tasks was to implement the strlen () function without the use of third-party functions, that is, with their hands. As a complete amateur in SI, I portrayed a simple cycle. I was specified that this implementation is uneconom of, and also that it can be recorded without unnecessary variables and in one line. Of course, it is not in the sense of shocking everything in one line, namely another algorithm. It was not about productivity or optimization from the point of view of practice, and as I understand it, the question was purely academic.
It caused my interest, as I could not do this on the interview. Communicating with a more competent colleague received implementation from him:

size_t str_len (Const Char * Str)
{
  Return (* STR)? STR_LEN (++ STR) + 1: 0;
}

I would probably haven’t thought of this way, but now the question of colleagues – is there an option in one line without recursion?

PS:
We also started the topic on SO on the topic of the same name.
I hope it will be interesting to those participating in the discussion.


Answer 1, Authority 100%

I also try to add a small comment to the answer. :

If even someone managed to write such a one-stroke with any of these cycles, in any case, you will need at least one more line in order to return the result:

size_t custom_strlen (...) {
  for (steep single-stroke) {}
  Return length; // do not escape from this line
}

taking into account this consideration and the fact that the condition clearly stipulates only “implement functional strlen () without using third-party functions,” I tried a little schmit:

void stanislaw_len (char * str, size_t * len) {
  For (* Len = 0; * STR; ++ str, (* Len) ++);
}

p.s. I know that it is a hack, just tried from sports interest.


More interestingly: I compared the methods and strlen offered here:

void stanislaw_len (char * str, size_t * len) {
  For (* Len = 0; * STR; ++ str, (* Len) ++);
}
Size_T Kovadim_len (char * t) {
  Return (STRCHR (T, 0) - T) / SizeOF (CHAR);
}
Size_T AVP_LEN (Const Char * Str) {
  REGISTER CONST CHAR * S = STR;
  While (* Str ++);
  RETURN (SIZE_T) (STR - S - 1);
}
Char * String = "This Is A Rather Long String! This is a Rather Long String! This is a raather long string!";
Size_t n = 1000000;
size_t m = 10;
__block Size_T Counter = 0;
Benchmark (M, ^ {
  For (int i = 0; i & lt; n; i ++) {
    Size_T Length;
    Stanislaw_len (String, & amp; Length);
    Counter + = Length;
  }
});
Nslog (@ "Stanislaw_len% LD", Counter);
... the rest is similar

Here are the results for O3:

The Block Have Been Run 10 Times. Average IS: 67.163414 MilliseConds
2014-03-12 16: 59: 10.429 SandboxCommandlineApp [17606: 303] Stanislaw_len () 890000000
The Block Have Been Run 10 Times. Average IS: 72.448875 MilliseConds
2014-03-12 16: 59: 11.156 SandboxCommandlineApp [17606: 303] avp_len () 890000000
The Block Have Been Run 10 Times. Average IS: 12.458966 Milliseconds
2014-03-12 16: 59: 11.281 SandboxcommandLineApp [17606: 303] Kovadim_len () 890000000
The Block Have Been Run 10 Times. Average IS: 8.514538 Milliseconds
2014-03-12 16: 59: 11.367 SandboxCommandlineApp [17606: 303] strlen () 890000000

Question to the connoisseurs: What can be shitted in Apple-oski LIBC Dylib-ah, what is such a big difference in speed? This is especially incomprehensible due to the fact that the last Open Source published is the strlen.c It contains very similar to the hill passes, like me and @avp (option Kovadim is not counting here, since it rely on the system library again)?


Answer 2, Authority 127%

in SI is impossible. All that can be written in one line and without calling other functions is performed during O (1), and we need to write an algorithm that works at least O (n) (n – & nbsp; string length).


Answer 3, Authority 100%

The wording says “without calling third-party functions.” And the function standard Libraries are third-party features? As for me, it is not. And my solution is then the following:

int newlen (char * t) {
  Return (STRCHR (T, 0) - T) / SizeOF (CHAR);
}

About the recursive option from the question – I looked at the compiled option (GCC 4.4-4.9 at the optimization level of O2, Clang 3) – There is no recursion – the compiler unfolds into the cycle.

str_len (char const *): # @str_len (char const *)
  Xorl% Eax,% EAX
  CMPB $ 0, (% RDI)
  Je .lbb0_3.
  Xorl% Eax,% EAX
.Lbb0_2: #% tailrecurse
  CMPB $ 0, 1 (% RDI,% RAX)
  LEAQ 1 (% RAX),% RAX
  JNE .LBB0_2.
.Lbb0_3: #% tailrecurse._crit_edge
  RET.

code is not perfect, but quite good. No stack, no unnecessary memory appeals.


Answer 4

int strlen (const char * str) {
  For (Const char * c = str ;; C++) if (! * c) Return C-STR;
}

Answer 5

int str_len (const char * str) {
  for (char const * a = str, * b = str ;; a -, b ++) if (! * b) for (int i = 0 ;; a ++, i ++) if (a == b) Return i / 2 ;
}

Answer 6

int strlen (const char * str) {
  For (Const char * c = str ;; ({if (* C++ == '\ 0') Return C - STR - 1;}));
}

Answer 7

I would do this:

size_t slen (Const char * s)
{
  int k = 0;
  While (s [K ++]);
  Return --k;
}

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions