Во время чтения очередной статьи про собеседования на программиста, столкнулся с такой простой на первый взгляд задачей: претенденту предложили написать функцию, которая "переворачивает" строку. Аналог ReverseString, но свой. Ответ, который дал претендент, не устроил собеседователя. Оказалось, что он ждал уточняющего вопроса: в какой кодировке, дескать, задана строка, а ответ должен был быть принят для кодировки UTF-8. С задачей претендент, похоже, не справился, а я решил написать свой вариант, поскольку на первой странице гугля такового не обнаружилось. Предлагаю на суд общественности:
- Код: Выделить всё
 // переворачивает строку, записанную в UTF-8 в обратном направлении 
function ReverseStringUtf8(const S:string):string;
var
  PrimeChar,LastChar:integer;
  B:byte;
begin
  PrimeChar:=1;
  LastChar:=Length(S);
  SetLength(Result,LastChar);
  while LastChar>0 do begin
    B:=ord(S[PrimeChar]);
    if B and $F7=$F0 then begin
      // четырёхбайтный символ
      Result[LastChar-3]:=S[PrimeChar+0];
      Result[LastChar-2]:=S[PrimeChar+1];
      Result[LastChar-1]:=S[PrimeChar+2];
      Result[LastChar-0]:=S[PrimeChar+3];
      Inc(PrimeChar,4);
      Dec(LastChar,4);
    end else if B and $F0=$E0 then begin
      // трёхбайтовый символ
      Result[LastChar-2]:=S[PrimeChar+0];
      Result[LastChar-1]:=S[PrimeChar+1];
      Result[LastChar-0]:=S[PrimeChar+2];
      Inc(PrimeChar,3);
      Dec(LastChar,3);
    end else if B and $E0=$C0 then begin
      // двухбайтовый символ
      Result[LastChar-1]:=S[PrimeChar+0];
      Result[LastChar-0]:=S[PrimeChar+1];
      Inc(PrimeChar,2);
      Dec(LastChar,2);
    end else begin
      // однобайтный символ
      Result[LastChar]:=S[PrimeChar];
      Inc(PrimeChar);
      Dec(LastChar);
    end;
  end;
end;