我正在编写一个递归OCaml函数,该函数将由分隔符连接的字符串列表中的字符串连接起来,而没有在最后一项上放置分隔符,但是我遇到了一些问题。我知道有一个string.concat函数,但我不想使用它,以了解OCaml如何在后台执行这些操作。这是我到目前为止的内容:
`
var rootReducer = Redux.combineReducers({
reducreForAge,
reducreForButtonGroup2,
reducreForSeach
});
var store = Redux.createStore(rootReducer)
`
我正在使用模式匹配来匹配字符串列表l,并涉及三种情况:如果字符串列表为空,情况1不返回任何内容;如果列表不包含尾部,则情况2仅返回首部。尾部3执行串联操作,同时递归join函数以串联列表中的其他项目,并在其间使用字符串分隔符。但是,我不确定如何实现此目标,同时又要在尾部递归并尊重OCaml对每个要求表达式的表达式的需求。在C或Java中,这是一个小问题,但无法解决,希望获得任何帮助或指针
答案 0 :(得分:1)
对于它的价值,我不明白为什么当列表的开头是一个空字符串时您为什么想要表现不同。
在这种情况下,内置字符串连接功能将执行以下操作:
# String.concat "," [""; "yes"];;
- : string = ",yes"
这对我来说似乎很合理,并且与非“”列表头的行为相同。
假设当头为“”时,您确实想做一些不同的事情,那么在这种情况下,您的代码不会进行任何递归。因此,整个输出将只是一个分隔符。
如果您继续使用else
运算符的两个用法和对^
的递归调用来编写join
部分,您应该发现代码在OCaml中同样容易就像在C或Java中一样。
答案 1 :(得分:0)
天真的join
很简单:
let rec join separator = function
| [] -> ""
| [str] -> str
| ""::strs -> join separator strs
| str::strs -> str ^ separator ^ join separator strs
这避免了假逗号,这似乎是您要尝试的操作。请注意,这不是List.concat
的行为。
尽管对于OCaml的新手来说,进行合理的编程是可以的,但是join
的这个版本是不可接受的:它确实以二次方的字符串长度总和工作。线性时间实现可能使用Buffer
:
let rec join separator = function
| [] -> ""
| [str] -> str
| str::strs ->
let buf = Buffer.create 0 in
Buffer.add_string buf str;
List.iter (function
| "" -> ()
| s ->
Buffer.add_string buf separator;
Buffer.add_string buf s)
strs;
Buffer.contents buf
比较丑陋,但时间复杂度可以接受。