SML - 通过String迭代

时间:2016-02-09 12:21:03

标签: sml smlnj

我试图找出从文件中读取的句子是否有某种模式。

到目前为止,我已经编写了逐行读取文件中所有句子的代码,并将这些句子放到数组中。

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);

3 个答案:

答案 0 :(得分:2)

如果字母true在字符串中,请尝试编写一个评估为a的函数。使用explode获取Chars列表。递归或折叠该列表,直到找到a或到达结尾。拥有该功能时,将其概括为任何字符。这可能会导致O(n^2)运行时复杂性。

另一种方法是对字符列表进行排序,删除重复项,使用正确的字符列表对其进行压缩,并将每个元组与递归/折叠进行比较。由于排序,这应该在O(n log n)时间运行。

第三种方法是使用数组或哈希映射折叠字符列表。在数组或映射中,您可以添加当前字符。最后,您会看到是否找到了所有字符。如果你的hashmap是常量时间,这种方法应该在O(n)时间运行。

答案 1 :(得分:2)

分而治之:

  1. 编写一个函数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
    
  2. 编写一个函数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