简体   繁体   中英

Why does the following Clojure not detect a palindrome?

I'm just trying to convert to a string and compare to the reverse

(defn is-palindrome? [num]
  (= (str num) (reverse (str num))))

Something like

(is-palindrome 1221)

Is returning false

Try this instead:

(defn is-palindrome? [num]
  (= (str num) (apply str (reverse (str num)))))

In your code, the expression (reverse (str 1221)) returns the list of characters (\\1 \\2 \\2 \\1) , which needs to be turned back into a string for the comparison to work. Alternatively, you could convert both numbers to character lists and perform a list comparison instead:

(defn is-palindrome? [num]
  (= (seq (str num)) (reverse (str num))))
(defn palindrome? [num]
  (= (seq (str num)) (clojure.string/reverse (str num))))

Your code returns false because it is comparing a string with a sequence, which can never be equal.

You can make it work by explicitly converting the string into a seq as follows:

(defn is-palindrome? [num] 
  (let [digit-sequence (seq (str num))]
    (= digit-sequence (reverse digit-sequence))))

It turns out the the overhead of manipulating collections of characters dominates, so it's actually faster to compare the original string to a reversed version even though it seems like you're comparing twice as many characters as necessary. Make sure you use clojure.string/reverse, not clojure.core/reverse. The usual Clojure convention is to end a predicate with a question mark, but not to use the "is" prefix.

(require 'clojure.string)

(defn palindrome? [s] (= s (clojure.string/reverse s)))
(defn palindrome-num? [n] (palindrome? (str n)))
(reverse (str 1221))

returns a List of characters

(\1 \2 \2 \1)

but (str 1221) is a java String

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM