当前位置:  开发笔记 > 编程语言 > 正文

C++到功能

如何解决《C++到功能》经验,为你挑选了2个好方法。

我想知道如何在函数式编程语言中这样做.也许F#或Haskell.

有人可以告诉我一个例子而不使用任何函数调用除了findrfind

此函数使用inum 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

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有