我试图找出从文件中读取的句子是否有某种模式。
到目前为止,我已经编写了逐行读取文件中所有句子的代码,并将这些句子放到数组中。
val infile = "c:/input.txt" ;
fun readlist (infile : string) =
let val ins = TextIO.openIn infile
fun loop ins = case TextIO.inputLine ins of
SOME line => line :: loop ins
| NONE => []
in loop ins before TextIO.closeIn ins
end;
val pureGraph = readlist(infile);
答案 0 :(得分:2)
如果字母true
在字符串中,请尝试编写一个评估为a
的函数。使用explode获取Chars列表。递归或折叠该列表,直到找到a
或到达结尾。拥有该功能时,将其概括为任何字符。这可能会导致O(n^2)
运行时复杂性。
另一种方法是对字符列表进行排序,删除重复项,使用正确的字符列表对其进行压缩,并将每个元组与递归/折叠进行比较。由于排序,这应该在O(n log n)
时间运行。
第三种方法是使用数组或哈希映射折叠字符列表。在数组或映射中,您可以添加当前字符。最后,您会看到是否找到了所有字符。如果你的hashmap是常量时间,这种方法应该在O(n)
时间运行。
答案 1 :(得分:2)
分而治之:
编写一个函数isPanagram : string -> bool
,用于确定单行。
一种策略可能是:从所有字母开始。循环遍历字符串,并为字符串中的每个字符将其从集合中删除,直到字符串结尾,或者集合为空。如果集合为空,则为panagram。这要求您以某种方式表示集合,例如使用列表或二叉搜索树。
考虑通过索引循环遍历字符串,而不是将其展开:
val allLetters = ...
fun remove x ... = ...
fun isEmpty ... = ...
fun isPanagram s =
let val len = size s
fun loop i missingLetters =
isEmpty missingLetters orelse
i < len andalso loop (i+1) (remove (String.sub (s, i)) missingLetters)
in loop 0 allLetters end
编写一个函数readLines : string -> string list
,它读取文件的内容并将这些行分成列表的元素:
fun isLinebreak c = c = #"\r" orelse c = #"\n"
fun readLines filename =
let val ins = TextIO.openIn filename
val data = TextIO.inputAll ins
val _ = TextIO.closeIn ins
in String.tokens isLinebreak data end
(是的,一次读取一行文件将节省内存。)
答案 2 :(得分:2)
SML / NJ库有许多数据结构,可用于集合和散列表之类的东西。它们没有完整记录,但this解释了如何使用它们。使用他们的set库,您可以编写如下内容:
structure CharSet = RedBlackSetFn(struct
type ord_key = char
val compare = Char.compare
end)
val alphabet = CharSet.fromList (explode "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
fun isPanagram s =
let val chars = CharSet.fromList (map Char.toUpper (explode s))
val letters = CharSet.intersection (chars,alphabet)
in CharSet.numItems letters = 26
end;
像这样使用:
- isPanagram "We promptly judged antique ivory buckles for the next prize.";
val it = true : bool
- isPanagram "We promptly judged antique plastic buckles for the next prize.";
val it = false : bool