List 将C代码转换为F代码:列表操作
早上好, 首先我介绍我自己:我的名字叫马蒂亚,我是计算机科学专业的学生 我已经用另外两种编程语言(C#和Python)实现了三个函数,使用命令式循环,比如for和while,但我要做的是以递归方式转换它们 C#中的函数是:List 将C代码转换为F代码:列表操作,list,f#,c#-to-f#,List,F#,C# To F#,早上好, 首先我介绍我自己:我的名字叫马蒂亚,我是计算机科学专业的学生 我已经用另外两种编程语言(C#和Python)实现了三个函数,使用命令式循环,比如for和while,但我要做的是以递归方式转换它们 C#中的函数是: resetList:给定两个列表,该方法初始化第一个列表对象内的计数器,并将新对象放入第二个列表 public static List<myObject> resetList(List<myObject> inList, List<myObje
- resetList:给定两个列表,该方法初始化第一个列表对象内的计数器,并将新对象放入第二个列表
public static List<myObject> resetList(List<myObject> inList, List<myObject> outList, bool flag) { foreach (myObject myObj in inList) { myObj.FirstCounter= 0; if (flag) myObj.SecondCounter= 0; outList.Add(myObj ); } return outList; }
- findCharEqual:
let rec findCharEqual index (myObj1 : myObject) (myObj2 : myObject) = let char1 = myObj1.GetChar() let char2 = myObj1.GetChar(index) if (index < 6) && (char1 <> char2) then findCharEqual (index + 1) myObj1 myObj2 else new myObject(myObj2.Index, index, myObj2.Chars, myObj2.Counter + 1)
(... declaration of listIn, listOut, listTemp...)
while (listOut.Length < n) do
let mutable myObj1 = new myObject(0, 0, Array.empty, 0)
let mutable myObj2 = new myObject(0, 0, Array.empty,0)
if (listIn.Length = 0) then
if (listOut.Length > 1) then
myObj1 <- listOut.[listOut.Length - 2]
myObj2 <- new myObject(listOut.[listOut.Length - 1].Index, listOut.[listOut.Length - 1].Char + 1, listOut.[listOut.Length - 1].Chars, listOut.[listOut.Length - 1].Counter)
listOut <- removeObject (listOut.Length - 1) listOut
if (myObj2.Counter < 2) then
listIn <- listIn @ resetObject listTemp false
listTemp <- List.empty<myObject>
else
myObj1 <- new myObject(listOut.Head.Index, listOut.Head.Char + 1, listOut.Head.Chars, listOut.Head.Counter)
listOut <- List.empty<myObject>
listOut <- listOut @ [myObj1]
listIn <- listIn @ resetObject listTemp true
listTemp <- List.empty<myObject>
myObj2 <- listIn.Head
listIn <- removeObject 0 listIn
else
myObj1 <- listOut.[listOut.Length - 1]
myObj2 <- listIn.Head
listIn <- removeObject 0 listIn
let mutable indFxDx = myObj2.Char
myObj2 <- fingEqualChar indFxDx myObj1 myObj2
if (myObj2.Char < 6) then
if (myObj1.leftChar = myObj2.rightChar) then
listOut <- listOut @ [myObj2]
if (listTemp.Length > 0) then
listIn <- listIn @ resetObject listTemp false
listTemp <- List.empty<myObject>
else
listTemp <- listTemp @ [myObj2]
(…listIn、listOut、listTemp的声明…)
而(listOut.Length1),则
myObj1以下是您可以做的事情:
let resetList inList outList flag =
outList @ inList |> List.map (fun i -> i.FirstCounter = 0;
match flag with
| true -> i.SecondCounter = 0; i
| _ -> i)
let randomList n =
let rnd = new Random()
seq {while true do yield rnd.Next(1,56)}
|> Seq.distinct
|> Seq.take n
|> Seq.toList
let findCharEqual obj1 obj2 =
let c = obj1.getChar()
let d = obj2.getChar()
if c = d then
c
else
findCharEqual obj1 obj2
在迭代或递归思考之前先考虑高阶函数如果您正在学习F#,那么首先自己编写一些递归函数是很有用的。稍后,您将了解到它们中的许多与某些现有模式相匹配,并且您将使用类似于List.map
(如Ankur的解决方案)的函数
因此,要递归地编写resetList
函数,可以执行以下操作:
let rec resetList inList flag =
match inList with
| [] -> [] // For empty list, we can only return emtpy list
| x::xs ->
// For non-empty list, create an object depending on the 'flag'
let obj =
if flag then new myObject(myObj.Index, 0, myObj.Chars, 0)
else new myObject(myObj.Index, 0, myObj.Chars, myObj.Counter)
// Process the rest of the list (recursively) and then add
// object we just created to the front
obj :: (resetList xs flag)
这个实现不是尾部递归的,这意味着它在递归调用restList
之后做了一些事情(它将值附加到前端)。如果您正在处理长列表,这可能会是一个问题,但是您现在可能不需要担心
有关更多信息和介绍。您的第一个函数只是在一个列表上迭代,复制它并对其中的对象执行一些副作用。复制F#列表没有任何意义,因为它们是不可变的,所以惯用翻译为:
let resetList inList flag =
for o in inList do
o.FirstCounter <- 0
if flag then
o.SecondCounter <- 0
inList
下一个循环时相同:
let rec loop index myChar =
if index < 6 && not (myObject2.getChar().Equals myChar) then
myObject1.getCharAt index |> loop (index + 1)
myObject1.getChar() |> loop myObject1.Index
myObject1.Counter <- myObject1.Counter + 1
让rec循环索引myChar=
如果索引<6&¬(myObject2.getChar()等于myChar),则
myObject1.getCharAt索引|>循环(索引+1)
myObject1.getChar()|>循环myObject1.Index
myObject1.计数器
(... declaration of listIn, listOut, listTemp...)
while (listOut.Length < n) do
let mutable myObj1 = new myObject(0, 0, Array.empty, 0)
let mutable myObj2 = new myObject(0, 0, Array.empty,0)
if (listIn.Length = 0) then
if (listOut.Length > 1) then
myObj1 <- listOut.[listOut.Length - 2]
myObj2 <- new myObject(listOut.[listOut.Length - 1].Index, listOut.[listOut.Length - 1].Char + 1, listOut.[listOut.Length - 1].Chars, listOut.[listOut.Length - 1].Counter)
listOut <- removeObject (listOut.Length - 1) listOut
if (myObj2.Counter < 2) then
listIn <- listIn @ resetObject listTemp false
listTemp <- List.empty<myObject>
else
myObj1 <- new myObject(listOut.Head.Index, listOut.Head.Char + 1, listOut.Head.Chars, listOut.Head.Counter)
listOut <- List.empty<myObject>
listOut <- listOut @ [myObj1]
listIn <- listIn @ resetObject listTemp true
listTemp <- List.empty<myObject>
myObj2 <- listIn.Head
listIn <- removeObject 0 listIn
else
myObj1 <- listOut.[listOut.Length - 1]
myObj2 <- listIn.Head
listIn <- removeObject 0 listIn
let mutable indFxDx = myObj2.Char
myObj2 <- fingEqualChar indFxDx myObj1 myObj2
if (myObj2.Char < 6) then
if (myObj1.leftChar = myObj2.rightChar) then
listOut <- listOut @ [myObj2]
if (listTemp.Length > 0) then
listIn <- listIn @ resetObject listTemp false
listTemp <- List.empty<myObject>
else
listTemp <- listTemp @ [myObj2]
(... declaration of listIn, listOut, listTemp...)
let rec findSolution i =
if i < n then
(... function atre the while declaration, to the end...)
findSolution (i + 1)
listOut <- findSolution 0
let resetList inList outList flag =
outList @ inList |> List.map (fun i -> i.FirstCounter = 0;
match flag with
| true -> i.SecondCounter = 0; i
| _ -> i)
let randomList n =
let rnd = new Random()
seq {while true do yield rnd.Next(1,56)}
|> Seq.distinct
|> Seq.take n
|> Seq.toList
let findCharEqual obj1 obj2 =
let c = obj1.getChar()
let d = obj2.getChar()
if c = d then
c
else
findCharEqual obj1 obj2
let rec resetList inList flag =
match inList with
| [] -> [] // For empty list, we can only return emtpy list
| x::xs ->
// For non-empty list, create an object depending on the 'flag'
let obj =
if flag then new myObject(myObj.Index, 0, myObj.Chars, 0)
else new myObject(myObj.Index, 0, myObj.Chars, myObj.Counter)
// Process the rest of the list (recursively) and then add
// object we just created to the front
obj :: (resetList xs flag)
let resetList inList flag =
for o in inList do
o.FirstCounter <- 0
if flag then
o.SecondCounter <- 0
inList
let rec loop i =
if i < n then
let randomNumber = randomizer.Next(1, 56 + 1)
if listOut.Contains randomNumber then
listOut.[i] <- randomNumber
loop (i + 1)
let rec loop index myChar =
if index < 6 && not (myObject2.getChar().Equals myChar) then
myObject1.getCharAt index |> loop (index + 1)
myObject1.getChar() |> loop myObject1.Index
myObject1.Counter <- myObject1.Counter + 1