In first, your code is broken. size_t
is unsigned type and never can be i<0
.
In second, your code is ugly std library misuse and ineffective. There should be used regular expression library or such or use handcrafted scanner. Resulting code is far cleaner and faster. For example (I have not been using C for many years but below code crafted in 10 minutes works.):
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;
}
I haven't used to write Haskell or F# but for example below code in Erlang should state as example how to do it in functional language:
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.
My attempt in Haskell with error checking and keeps laziness for 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