【问题标题】:SML - Iterate through StringSML - 遍历字符串
【发布时间】:2016-02-09 12:21:02
【问题描述】:

我正在尝试查找从文件中读取的句子是否有某种模式。

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

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

【问题讨论】:

  • 想找一些关于SML的资料但是看不懂...

标签: sml smlnj


【解决方案1】:

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

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

第三种方法是使用数组或哈希映射折叠字符列表。在数组或映射中添加当前字符是什么。最后,您会看到是否找到了所有字符。如果您的哈希图是恒定时间的,则此方法应在 O(n) 时间运行。

【讨论】:

  • 哦,我应该试试“爆炸”功能。谢谢!
  • 你能告诉我如何使用explode来遍历字符串中的字符吗?
  • 你可以像这样计算元音的数量:foldl (fn (c, n) => if isVowel c then n+1 else n) 0 (explode s)
  • SML/NJ 有一个哈希表实现(我认为它是扩展而不是标准基础库的一部分):smlnj.org/doc/smlnj-lib/Manual/hash-table.html
【解决方案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 -&gt; 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
    

    (是的,一次读取一行文件会节省内存。)

【讨论】:

    【解决方案3】:

    SML/NJ 库有许多数据结构,可用于集合和哈希表等内容。它们的文档并不完整,但this 解释了一些如何使用它们。使用他们的集合库,您可以编写如下内容:

    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
    

    【讨论】:

      猜你喜欢
      • 2018-05-15
      • 2011-08-27
      • 1970-01-01
      • 1970-01-01
      • 2021-03-03
      • 2014-12-30
      相关资源
      最近更新 更多