Racket:如何获取字符串中某个字符出现的次数

问题描述 投票:0回答:2

我正在尝试获取 RACKET 中字符串中某个字符出现的次数。

我正在传递字符“#”,我应该收到 3。

我做错了什么?

(define (numCaracter character string1)
  (numCaracter-aux character string1 0 0))

(define (numCaracter-aux c s1 numC x)
   (cond
     ((= x (string-length s1)) numC)
     ((eq? c (string-ref s1 x)) (numCaracter-aux c s1 (+ 1 numC) (+ 1 x)))
     (else (numCaracter-aux c s1 numC (+ 1 x))))) 

(numCaracter "#\a" "banana")
lisp racket
2个回答
0
投票

您的代码有两个问题:

  • "#\a"
    是一个角色吗?
  • 你应该如何比较角色?

第二点是微妙而重要的一点。

eq?
的作用是告诉您两个对象实际上是否是同一个相同的对象。 但可能存在一些您称之为“相同”的对象,但实际上它们并不是同一个对象。 数字就是一个很好的例子:很明显
(eq? 1 1)
应该是真的。 但是呢

(define (big n m)
  (for/product ([e (in-range 1 n)])
    (* e m)))

(eq? (big 100 123) (big 100 123))

(big 100 123)
742351665480632681361574507959522940219863107926668019564998091421702580066558131502770412261037347873964172894230830459668242628528330665058838091519120194482100362028630508871608854457172959508668790743797878802883944000708882685320114585932837885833026170012541369814338006896897825563613579482679096651236246935631886366444007162831175680000000000000000000000
。 这个数字太大了,机器无法表示:它大约有 1200 位。 每次创建此数字时,都会在内存中创建一些大型结构,通常这些结构将是不同的对象。 因此,当比较两个这样的数字时,
eq?
会返回
#f
,或者几乎肯定会这样做。

但我想将它们视为同一事物,并且(以及数字的专用谓词),如果两个不可变对象在语义上相同,则有一个谓词返回 true。 该谓词是

eqv?

角色的情况可能并不明显,但事实确实如此。 原因是字符通常不是微小的对象:它们可以是成熟的 Unicode 对象,也可以非常大。 所以,再次强调,

eqv?
为角色做了正确的事情。

但是,您可能只想使用一个目的是比较字符的谓词,这不仅有效,而且会为您发现其他错误。

最后:您可以修改代码以向后遍历字符串:为什么这会让它变得更简单?


0
投票

除非是为了课堂作业而编写自己的例程是重点,否则只需使用 SRFI-13 字符串库中的

string-count
(随 Racket 一起提供):

> (require srfi/13)
> (string-count "banana" #\a)
3
© www.soinside.com 2019 - 2024. All rights reserved.