String Scheme:如何在字符串中查找字符的位置

String Scheme:如何在字符串中查找字符的位置,string,list,position,scheme,racket,String,List,Position,Scheme,Racket,我试图找到一个字符串的索引,其中它等于某个字符,但我似乎能找到它。 这是我到目前为止得到的,但它不起作用 (define getPos (lambda () (define s (apply string-append myList)) (getPosition pos (string->list s)))) (define getPosition (lambda (position s) (if (and (< position (length

我试图找到一个字符串的索引,其中它等于某个字符,但我似乎能找到它。 这是我到目前为止得到的,但它不起作用

(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)))))))
(定义getPos
(lambda()
(定义s(应用字符串附加myList))
(getPosition位置(字符串->列表)))
(定义getPosition
(lambda(位置s)
(如果(和(列表
(续)
((空?s)0)
(其他(+1(长度(cdr s()()()))))

解决方案很简单:我们必须测试列表中的每个字符,直到元素用完或者找到第一个出现的字符,跟踪我们所处的位置

您提出的解决方案看起来很奇怪,在方案中,我们试图避免
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

带有
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

谢谢你的解决方案,但最终我自己解决了^ ^@user2403836好的,但我希望你停止使用
set对于实现循环,这是遍历Scheme中列表的错误方法;)如果我想在函数中把x设为2,我会怎么做(定义x2)?@user2403836是的,这是给变量赋值的一种方法。您还可以使用
let
let*
。但关键是——在Scheme中编程时,在将初始值分配给变量后,不要再修改它——如果值必须更改,则修改将作为参数传递给函数调用,但不应使用
set对其进行就地修改。当然,
set有有效的用途,但循环不是其中之一。如果有两组括号,则表示将作为过程调用表达式的结果。。例如,
((获取函数)56)
但是
设置的计算结果为未知值,因此它不会成为有效的过程对象。对于使用
(begin expression…)的块