【问题标题】:String-append not working; keeps overwriting previous strings字符串附加不起作用;不断覆盖以前的字符串
【发布时间】:2012-01-02 17:19:50
【问题描述】:

我正在尝试做一个简单的任务,将一个数字多次附加到一个字符串,并希望这会构建一个字符串。

但它不起作用,每次调用(string-append ....) 似乎什么都不做。

这是我的代码:

(define myString "")
(string-append (number->string 4) myString)
(string-append (number->string 5) myString)
(string-append (number->string 6) myString)
(string-append (number->string 7) myString)
(display myString)

这显示:

“4”

“5”

“6”

“7”

(display myString) 有一个空行

我做错了什么?

如果我以其他方式这样做,它也不起作用:

(define myString "")
(string-append myString (number->string 4))
(string-append myString (number->string 5))
(string-append myString (number->string 6))
(string-append myString (number->string 7))
(display myString)

感谢您的帮助

【问题讨论】:

    标签: string lisp scheme append


    【解决方案1】:

    string-append 不会更改现有字符串;它返回一个作为操作结果的新字符串。

    如果这看起来不寻常,请考虑加法运算符+。当我写

    3+4

    我不会把3改成7,只是返回操作的结果。

    所以,在你的情况下,如果你写

    (define my-string (string-append (number->string 4) (number->string 5)))
    (display my-string)
    

    你应该看到

    45
    

    为了进一步向您提供建议,了解您的目标可能会有所帮助。

    【讨论】:

    • 这是一个将中缀表示法转换为后缀表示法的程序。我正在使用该网站的堆栈:zoo.cs.yale.edu/classes/cs201/Fall_2007/materials/pdfs/… 我读入用户输入,并将其转换为字符列表。然后我检查第一个字符是数字、括号还是运算符,并在其上运行算法,所以如果我想要一个全局字符串,则将这些数字添加到其中,我该怎么做?我已经在我的函数上方声明了一个字符串,但我不确定如何重新分配 (string-append) 的返回值
    • 我建议您重新考虑您的设计。你可以编写你的程序,让它简单地返回一个新的字符串,而不是使用全局值。
    • 你是对的,我应该重新设计它以避免全局变量 - 我已经习惯了 OOP 语言哈哈!我最终使用该链接中的堆栈来存储我最初想要附加到字符串的动态变量,到目前为止一切都很好 - 我有一个程序需要一个中缀字符串 ((1+3)*4) 和吐出一个后缀表达式 1 3 + 4 *。不,我需要学习的是如何在没有 ( ) 括号的情况下打印出一个列表!感谢您的帮助!
    【解决方案2】:

    表达式(string-append (number->string 4) myString) 的计算结果为"4",这就是您的代码打印4 的原因。同样,(string-append (number->string 5) myString) 的计算结果为 "5",依此类推。两者都没有真正改变变量myString 的值。

    要真正改变变量的值,您需要使用Scheme 的赋值语言set! 将变量赋值。 (名称中的! 是一个Scheme 约定,告诉你这是一个破坏性 操作——即破坏myString 中的先前值并用新值替换它的操作.) 例如,你可以这样写:

    (define myString "")
    (set! myString (string-append myString (number->string 4))) ;; assigns "4" to myString
    (set! myString (string-append myString (number->string 5))) ;; assigns "45" to myString
    (set! myString (string-append myString (number->string 6))) ;; assigns "456" to myString
    (set! myString (string-append myString (number->string 7))) ;; assigns "4567" to myString
    (display myString) ;; prints 4567
    

    但是,您可以一开始就构建您想要的表达式,而不必执行所有这些破坏性操作:

    (define myString 
      (string-append (number->string 4) 
        (string-append (number->string 5) 
          (string-append (number->string 6) 
            (string-append (number->string 7) "")))))
    (display myString) ;; prints 4567
    

    那时,我不会编写如此重复的代码,而是编写fold-right

    (define myString 
      (fold-right (lambda (num str) 
                    (string-append (number->string num) str)) 
        "" (list 4 5 6 7)))
    (display myString) ;; prints 4567
    

    如果您必须将"4567" 分配给名为myString 的全局变量,那么您可以在上述两个代码sn-ps 中的任何一个中简单地将define 替换为set!。然而,虽然set! 有时可以派上用场,但惯用的Scheme 倾向于谨慎使用set!s 和其他破坏性操作。我喜欢将感叹号视为“谨慎行事!”的意思!

    【讨论】:

    • (set!myString (string-append myString (number->string 4))) 这是我一直在寻找的,因为要添加的值将从列表/堆栈中动态变化.因此,对于静态信息,您的其他选择更是如此。我最终重新设计了程序并使用了全局堆栈而不是字符串(我知道我不应该使用任何全局数据,但就这样吧 - 我太习惯于 OOP 语言)谢谢!
    • 你可能会尝试的另一件事会更 Schemely:cons 传入的值在它们进来时放到一个列表中。然后,稍后,如果你需要将它们全部作为字符串吐出,你可以使用上面的fold-right 之类的东西。
    猜你喜欢
    • 1970-01-01
    • 2012-03-03
    • 2011-08-29
    • 1970-01-01
    • 2015-09-25
    • 2014-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多