我想知道如何在函数式编程语言中这样做.也许F#或Haskell.
有人可以告诉我一个例子而不使用任何函数调用除了find
和rfind
?
此函数使用i
num slash
((向后<0)查找下一个斜杠.
size_t findSlash(const char *sz, size_t i) { std::string s = sz; size_t a, b, c, n, ai = abs(i), pos=0; for (n=0; n
jrockway.. 13
哈斯克尔:
import Data.List findSlash :: String -> Int -> Int findSlash str i = findIndices (\c -> c == '\\' || c == '/') str !! i处理负面指数(这很难看,因为你真的不想这样做):
findSlash :: String -> Int -> Int findSlash str i = index (findIndices (\c -> c == '\\' || c == '/') str) i where index xs i | i < 0 = (reverse xs) !! ((-i) - 1) | i >= 0 = xs !! i处理错误:
findSlash :: String -> Int -> Maybe Int findSlash str i = index i where xs = findIndices (\c -> c == '\\' || c == '/') str l = length xs index i | i < 0 && i < (-l) = Nothing | i >= 0 && i >= l = Nothing | i < 0 = Just $ (reverse xs) !! ((-i) - 1) | i >= 0 = Just $ xs !! i现在你可以说:
map (findSlash "/foo/bar/baz") [-4..4]得到:
-- -4 -3 -2 -1 0 1 2 3 4 [Nothing,Just 0,Just 4,Just 8,Just 0,Just 4,Just 8,Nothing,Nothing]无论如何,处理从末尾的偏移使得代码非常难看,并且破坏了懒惰评估的可能性.所以我认为大多数人会使用第一个,也许会进行一些错误检查.(这也会导致懒惰,因为长度会强制评估整个列表.你可以使用"drop"而不是"!!"但是,要避免错误并阻止评估整个结果列表.TMTOWTDI.)
1> jrockway..:哈斯克尔:
import Data.List findSlash :: String -> Int -> Int findSlash str i = findIndices (\c -> c == '\\' || c == '/') str !! i处理负面指数(这很难看,因为你真的不想这样做):
findSlash :: String -> Int -> Int findSlash str i = index (findIndices (\c -> c == '\\' || c == '/') str) i where index xs i | i < 0 = (reverse xs) !! ((-i) - 1) | i >= 0 = xs !! i处理错误:
findSlash :: String -> Int -> Maybe Int findSlash str i = index i where xs = findIndices (\c -> c == '\\' || c == '/') str l = length xs index i | i < 0 && i < (-l) = Nothing | i >= 0 && i >= l = Nothing | i < 0 = Just $ (reverse xs) !! ((-i) - 1) | i >= 0 = Just $ xs !! i现在你可以说:
map (findSlash "/foo/bar/baz") [-4..4]得到:
-- -4 -3 -2 -1 0 1 2 3 4 [Nothing,Just 0,Just 4,Just 8,Just 0,Just 4,Just 8,Nothing,Nothing]无论如何,处理从末尾的偏移使得代码非常难看,并且破坏了懒惰评估的可能性.所以我认为大多数人会使用第一个,也许会进行一些错误检查.(这也会导致懒惰,因为长度会强制评估整个列表.你可以使用"drop"而不是"!!"但是,要避免错误并阻止评估整个结果列表.TMTOWTDI.)
2> Hynek -Pichi..:首先,你的代码被破坏了.
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我不习惯编写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