方案:如何在字符串中查找字符的位置

4

我想要找到一个字符串中等于特定字符的索引,但我似乎无法解决它。

这是我得到的内容,但它并没有起作用...

(define getPos 
  (lambda ()
    (define s (apply string-append myList))
    (getPosition pos (string->list s))))

(define getPosition 
  (lambda (position s)
    (if (and (< position (length s)) (equal? (car s) #\space)) 
        ((set! pos (+ pos 1)) (getPosition (cdr s) pos));increment the positon and continue the loop
        pos)));else

(define length
  (lambda (s);the value s must be coverted to a string->list when passed in
    (cond
      ((null? s) 0)
      (else (+ 1 (length (cdr s)))))))

1
当你有双重括号时,这意味着你将调用表达式的结果作为一个过程。例如:((get-function) 5 6) 但是 set! 被认为会评估为一个未知值,因此它不会成为一个有效的过程对象。对于块,你可以使用 (begin expression ...) - Sylwester
2个回答

2
解决方案很简单:我们需要测试列表中的每个字符,直到我们用尽所有元素或找到第一个出现的字符为止,并跟踪我们所处的位置。
你提出的解决方案看起来很奇怪,在Scheme中,我们试图避免使用set!和其他改变数据的操作-使用递归来遍历字符列表是更好的选择。可以使用以下类似的代码:
(define (getPosition char-list char pos)
  (cond ((null? char-list) #f)              ; list was empty
        ((char=? char (car char-list)) pos) ; we found it!
        (else (getPosition (cdr char-list) char (add1 pos))))) ; char was not found

对于以0为基准的索引,可以像这样使用,将字符串转换为字符列表并将位置初始化为0

(getPosition (string->list "abcde") #\e 0)
=> 4

当然,我们可以通过使用现有的程序来做得更好 - 这里是一种更加惯用的解决方案:
(require srfi/1) ; required for using the `list-index` procedure

(define (getPosition string char)
  (list-index (curry char=? char) 
              (string->list string)))

(getPosition "abcde" #\e)
=> 4

1
谢谢你的解决方案,但最终我自己想出来了 ^_^ - mr nooby noob
@user2403836 好的,但我希望你停止使用set!来实现循环,在Scheme中遍历列表的方法是错误的 ;) - Óscar López
那么假如我想在一个函数中将 x 设置为 2,我需要这样做吗(define x 2)? - mr nooby noob
@user2403836 是的,这是给变量赋值的一种方式。还可以使用 letlet*。但关键是,在Scheme编程中,给变量分配初始值后,后面不应该 修改 它 - 如果值必须更改,则修改应作为参数传递给函数调用,而不应该使用 set! 在原地进行修改。当然,set! 也有其有效的用途,但循环不是其中之一。 - Óscar López

0

使用 for 循环的解决方案:

#lang racket

(define (find-char c s)
  (for/first ([x s]              ; for each character in the string c
              [i (in-naturals)]  ; counts 0, 1, 2, ...
              #:when (char=? c x))
    i))

(find-char #\o "hello world")
(find-char #\x "hello world")

输出:

4
#f

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接