Во-первых, ваш код не работает. size_t
является типом без знака и никогда не может быть i<0
.
Во-вторых, ваш код - это уродливое использование библиотеки std и неэффективное. Там должна быть библиотека регулярных выражений или тому подобное или использовать ручной сканер. Результирующий код намного чище и быстрее. Например (я не использую C много лет, но приведенный ниже код, созданный за 10 минут, работает.):
size_t findSlash(const char *sz, int i)
{
const char *s = sz;
if (i<0) {
for(;*s;s++);
for(;;s--){
if(s<sz) return -1;
if((*s == '/') || (*s == '\\'))
if(! ++i) break;
}
}
else {
for(;;s++){
if(! *s) return -1;
if((*s == '/') || (*s == '\\'))
if(! i--) break;
}
}
return s-sz;
}
Я не писал на Haskell или F #, но, например, код ниже на Erlang должен указывать, как это сделать на функциональном языке:
findslash(L, I) when is_list(L), is_integer(I) ->
if I<0 ->
case findslash(lists:reverse(L), -1*I - 1, 0) of
none -> none;
X -> length(L) - X - 1
end;
I>=0 -> findslash(L, I, 0)
end.
findslash([H|_], 0, X) when H=:=$/; H=:=$\\ -> X;
findslash([H|T], I, X) when H=:=$/; H=:=$\\ ->
findslash(T, I-1, X+1);
findslash([_|T], I, X) -> findslash(T, I, X+1);
findslash([], _, _) -> none.
Моя попытка в Haskell с проверкой ошибок и ленью для i> = 0:
findSlash :: String -> Int -> Maybe Int
findSlash str i
| i < 0 = reversed (_findSlash (reverse str) (-1*i-1) 0)
| i >= 0 = _findSlash str i 0
where
reversed Nothing = Nothing
reversed (Just a) = Just ((length str) - a - 1)
_findSlash (x:xs) i n
| x == '/' || x == '\\' = if i==0 then Just n else _findSlash xs (i-1) (n+1)
| True = _findSlash xs i (n+1)
_findSlash [] _ _ = Nothing