Performance F中的返回字符串和代码优化#
如何修改下面的代码以返回“字符串”,以便返回的输出显示在我的MVC页面上,并且希望从用户处接受Performance F中的返回字符串和代码优化#,performance,f#,f#-interactive,Performance,F#,F# Interactive,如何修改下面的代码以返回“字符串”,以便返回的输出显示在我的MVC页面上,并且希望从用户处接受enteredChar 有没有更好的方法来创建这个金字塔 当前代码: let enteredChar = 'F' // As Interactive window doesn't support to Read Input let mylist = ['A'..enteredChar] let mylistlength = mylist |> List.length let myfunc i x
enteredChar
有没有更好的方法来创建这个金字塔
当前代码:
let enteredChar = 'F' // As Interactive window doesn't support to Read Input
let mylist = ['A'..enteredChar]
let mylistlength = mylist |> List.length
let myfunc i x tlist1 =
(for j = 0 to mylistlength-i-2 do printf "%c" ' ')
let a1 = [for p in tlist1 do if p < x then yield p]
for p in a1 do printf "%c" p
printf "%c" x
let a2 = List.rev a1
for p in a2 do printf "%c" p
printfn "%s" " "
mylist |> List.iteri(fun i x -> myfunc i x mylist)
如果我理解你的问题(这可能属于),这里有一种重写函数的方法:
让showPyramid(输出:TextWriter)lastChar=
设chars=[|A'…lastChar]
设getRowChars n=
让rec循环acc i=
[|
如果i
范例
showPyramid Console.Out 'F'
或者,输出到字符串
use output = new StringWriter()
showPyramid output 'F'
let pyramid = output.ToString()
编辑
看到托马斯的答案后,我意识到我跳过了你问题中的“返回字符串”。我更新了代码并添加了一些示例来展示如何做到这一点。作为Daniel解决方案的替代方案,您可以通过对代码逻辑进行最小的更改来实现所需的功能。您可以使用
printf.bprintf
将输出写入指定的StringBuilder
,而不是使用将输出写入控制台的printf.bprintf
。然后,您只需从StringBuilder
获取结果字符串
修改后的函数如下所示。我添加了参数str
,并将printf
替换为printf.bprintf str
(将printfn
替换为bprintf
以及其他\n
字符):
我认为Daniel的解决方案看起来更好,但这是将打印代码转换为字符串构建代码的最直接的方法(基本上可以使用搜索和替换完成)。一些小优化可能是:
- 使用
而不是StringBuilder
,这对于长字符串来说相当慢printf
- 使用
而不是Array
,因为List
更适合Array
String
open System
open System.Text
let generateString c =
let sb = StringBuilder()
let generate i x arr =
String.replicate (Array.length arr-i-1) " " |> sb.Append |> ignore
let a1 = Array.filter (fun p -> p < x) arr
String(a1) |> sb.Append |> ignore
sb.Append x |> ignore
String(Array.rev a1) |> sb.Append |> ignore
sb.AppendLine " " |> ignore
let arr = [|'A'..c|]
arr |> Array.iteri(fun i x -> generate i x arr)
sb.ToString()
generateString 'F' |> printfn "%s"
开放系统
开放系统.Text
设发电机限制c=
让sb=StringBuilder()
让我们生成i x arr=
String.replicate(Array.length arr-i-1)“|>sb.Append |>ignore
设a1=Array.filter(funp->psb.Append |>ignore
sb.附加x |>忽略
字符串(Array.rev a1)|>sb.Append |>ignore
sb.AppendLine“”|>忽略
设arr=[|A'..c]
arr |>Array.iteri(乐趣i x->生成i x arr)
(某人)
生成器字符串“F”|>printfn“%s”
这里有另一种方法,它似乎是功能组合的一个很好的演示。我打赌这是这里所有答案中最短的答案。:)
- 首先,我们生成一个不寻常的初始数据数组。它的元素
包含一个空格或任何您想要的分隔符;出于调试目的,我更喜欢破折号([0]
)-
行生成一个函数,用于计算要放置的字符。(1)
的结果可以是正的(并且有一个要放置的字符),也可以是零负的,并且应该有一个空格。注意,没有行abs(col len+1)+1
语句:它隐藏在if
函数中李>max
行组成一个函数(2)
,用于生成一个单独的行李>int->string
行将上述函数作为序列初始值设定项的参数传递(3)
let genCell row col = row-abs(col-len+1)+1 |> max 0 |> Array.get src
let genRow = genCell >> Seq.init (len*2-1) >> charsToString
Seq.init len genRow
注
genRow
由于函数组合的原因,不需要正式参数:参数被绑定到genCell
,返回单个参数的函数,这正是Seq.init
所需要的。我想我还没有准备好函数组合。honesly仍在处理:)+1用于介绍函数组合。如果您能评论“为什么数组与字符串一起工作更好”,那将是一件好事?感谢String(a1)
是一个构造函数,它接收一个char
数组作为参数。此外,Array
由于其良好的缓存位置,可能比List
更快。
let str = StringBuilder()
mylist |> List.iteri(fun i x -> myfunc i x mylist str)
str.ToString()
open System
open System.Text
let generateString c =
let sb = StringBuilder()
let generate i x arr =
String.replicate (Array.length arr-i-1) " " |> sb.Append |> ignore
let a1 = Array.filter (fun p -> p < x) arr
String(a1) |> sb.Append |> ignore
sb.Append x |> ignore
String(Array.rev a1) |> sb.Append |> ignore
sb.AppendLine " " |> ignore
let arr = [|'A'..c|]
arr |> Array.iteri(fun i x -> generate i x arr)
sb.ToString()
generateString 'F' |> printfn "%s"
let pyramid (ch:char) =
let ar = [| 'A'..ch |]
let len = ar.Length
Array.mapi
(fun i ch ->
let ar = ar.[0..i]
String.replicate (len - i - 1) " " + new string(ar) + new string((Array.rev ar).[1..]))
ar
|> String.concat "\n"
pyramid 'F' |> printfn "%s"
let charsToString = Seq.map string >> String.concat String.Empty
let pyramid lastChar =
let src = '-'::['A'..lastChar] |> List.toArray
let len = Array.length src - 1
fun row col -> row-abs(col-len+1)+1 |> max 0 |> Array.get src // (1)
>> Seq.init (len*2-1) >> charsToString // (2)
|> Seq.init len // (3)
pyramid 'X' |> Seq.iter (printfn "%s")
let genCell row col = row-abs(col-len+1)+1 |> max 0 |> Array.get src
let genRow = genCell >> Seq.init (len*2-1) >> charsToString
Seq.init len genRow