c# - 如何在 F# 中递归调用
问题描述
我正在将 ac# 递归函数转换为 f#。我对 F# 不是很熟悉。我有一堆错误,我不知道为什么。我确实查找了递归函数语法,但是对于我拥有的所有 if 语句,我对如何在 f# 中编写它感到困惑。
这是c#递归函数
private List<double> ReturnClosestInList(List<double> allKey, int begin, int end)
{
if (end >= begin)
{
int mid = begin + (end - begin) / 2;
if (allKey[mid] > input) return ReturnClosestInList(allKey, begin, mid - 1);
return ReturnClosestInList(allKey, mid + 1, end);
}
if (end < 0) end = begin + 1;
if (begin < 0) begin = end + 1;
if (end > allKey.Count - 1) end = begin - 1;
if (begin > allKey.Count - 1) begin = end - 1;
return new List<double> { allKey[begin], allKey[end] };
}
这是我编写的 f# 代码和错误:
let rec ReturnClosestInList (allKey : List<double>) (start : int) (finish : int) (input : double)=
if(finish >= start) then
let mid = start + (finish - start) / 2
if(allKey.[mid] > input) then
ReturnClosestInList allKey start (mid - 1) input
else ReturnClosestInList allKey (start + 1) mid input
else
if finish < 0 then
finish = start + 1
elif start < 0 then
start = finish + 1
elif finish > allKey.Length - 1 then
finish = start - 1
else start > allKey.Length - 1 then
start = finish - 1
let c : List<double> = [allKey.[start]; allKey.[finish]]
c
解决方案
您的代码有两个问题。首先是您将start
andfinish
视为可变值。另一个是您的else
分支不返回值。
要解决前者,我认为最好的方法是使用以下方法重新分配变量:
let start, finish =
if finish < 0 then
start, start + 1
elif start < 0 then
finish + 1, finish
elif finish > allKey.Length - 1 then
start, start - 1
elif start > allKey.Length - 1 then
finish - 1, finish
else start, finish
这个想法是您正在定义同名的新变量,并为它们分配一个新值。由于您需要更新其中一个或另一个的值,因此代码会重新分配它们(else
分支没有做任何特别的事情)。
第一个问题是你的两个分支if
都必须返回一个结果。为此,您需要编写如下内容:
if(finish >= start) then
let mid = start + (finish - start) / 2
if(allKey.[mid] > input) then
ReturnClosestInList allKey start (mid - 1) input
else ReturnClosestInList allKey (start + 1) mid input
else
let start, finish =
// (all the code to tweak start/finish goes here)
[allKey.[start]; allKey.[finish]]
这样,if
case 的返回值就是你从递归调用中得到的任何值。另一种情况的回报是您使用[ ... ]
.
还值得注意的是,您的代码看起来不是很实用,因此如果您正在学习 F#,我建议您使用模式匹配而不是从 C# 转换代码来编写此代码。你会得到一个更好、更容易理解的解决方案。
推荐阅读
- c - 如何从txt文件中删除新行?
- pyodbc - 在 azure databrick 中使用 pyodbc 连接 SQL Server
- firebase - 如何在 Firestore -Flutter 中将所有文档从一个集合复制到另一个集合?
- c# - 更新数据绑定对象中的值时的良好程序结构
- fortran - 在Fortran中初始化参数化派生类型的参数大小数组?
- apache-spark - 选择数据框中总和 = 50 的最大行数
- python-3.x - 如何知道在抓取时使用哪些标签?
- python - 索引超出范围 - numpy 数组
- django - Django:未应用字段验证器和 UNIQUE 约束
- r - r data.table - 首先选择所有行(在每个组中)