4clojure上几道Medium类型题目解析与答案
第43题
英文描述
Write a function which reverses the interleave process into x number of subsequences.
翻译
编写一个函数,将交织过程转换为x个子序列。
测试案例
- (= (__ [1 2 3 4 5 6] 2) '((1 3 5) (2 4 6)))
- (= (__ (range 9) 3) '((0 3 6) (1 4 7) (2 5 8)))
- (= (__ (range 10) 5) '((0 5) (1 6) (2 7) (3 8) (4 9)))
题目解析
- 参数1为一个序列,参数2(后面设为times)为需要将序列分解成子序列的个数,这样将序列长度与参数2相除就能得到每个序列的长度size
- 这样我们可以用loop循环参数2个次数,然后每个子序列为循环次数*times
- 将子序列连接起来就是完整答案了
答案代码
(fn f43
[args times]
(let [size (/ (count args) times)]
(loop [n 0 result []]
(if (< n times)
(recur (inc n)
(conj result (let [x (fn
[sizes first-num times cols]
(loop [m 0 col []]
(if (< m sizes)
(recur (inc m) (conj col (nth cols (+ first-num (* m times)))))
col)))] (x size n times args))))
result)))
)
第44题
英文描述
Write a function which can rotate a sequence in either direction.
翻译
编写一个可以沿任一方向旋转序列的函数。
测试案例
- (= (__ 2 [1 2 3 4 5]) '(3 4 5 1 2))
- (= (__ -2 [1 2 3 4 5]) '(4 5 1 2 3))
- (= (__ 6 [1 2 3 4 5]) '(2 3 4 5 1))
- (= (__ 1 '(:a :b :c)) '(:b :c :a))
- (= (__ -4 '(:a :b :c)) '(:c :a :b))
题目解析
- 观察第一个参数,与序列长度(设为length)对比,有5中情况
1、为0,这种情况返回原序列
2、介于0和length之间,这种情况序列第一个取第参数个
3、大于length,这种情况将参数取余数,然后跟第二种情况一样
4、小于0但大于-length,这种情况将参数与length相加,然后与第二种一样
5、小与-length,这种情况将参数取模,然后跟第二种一样
答案代码
(fn f44
[index acc]
(let [s (count acc) a (mod index s)]
(concat (drop a acc) (take a acc)))
)
第46题
英文描述
Write a higher-order function which flips the order of the arguments of an input function.
翻译
编写一个高阶函数,该函数可以翻转输入函数的参数顺序。
测试案例
- (= 3 ((__ nth) 2 [1 2 3 4 5]))
- (= true ((__ >) 7 8))
- (= 4 ((__ quot) 2 8))
- (= [1 2 3] ((__ take) [1 2 3 4 5] 3))
题目解析
- 将参数反转,可以用到reverse 函数
- 考虑到多个参数的情况,用apply处理
答案代码
(fn
[f]
(fn f* [& args]
(apply f (reverse args))))
第54题
英文描述
Write a function which returns a sequence of lists of x items each. Lists of less than x items should not be returned.
翻译
编写一个函数,该函数返回每个x项的列表序列。少于x个项目的列表不应返回。
测试案例
- (= (__ 3 (range 9)) '((0 1 2) (3 4 5) (6 7 8)))
- (= (__ 2 (range 8)) '((0 1) (2 3) (4 5) (6 7)))
- (= (__ 3 (range 8)) '((0 1 2) (3 4 5)))
题目解析
- 从测试案例中可以看出,返回的序列是连续的
- 这里我们可以依次drop 序列前面的数据当作子序列的值
答案代码
(fn f54
[s acc]
(loop [result [] new-acc acc]
(if (>= (count new-acc) s)
(recur (concat result (list (take s new-acc))) (drop s new-acc))
result))
)
第56题
英文描述
Write a function which removes the duplicates from a sequence. Order of the items must be maintained.
翻译
编写一个从序列中删除重复项的函数。必须保持项目的顺序。
题目解析
- 将序列中重复数据去除
- 保持原来的顺序
- 这里我们以一个空序列为结果值,然后遍历原序列跟结果值想对比,如果存在结果序列包含子项,则不做处理,如果不包含,则将子项加到结果值中
答案代码
(fn f56
[args]
(let [ f* (fn [col s]
(if (.contains col s)
col
(conj col s)))]
(reduce f* [] args)))
第69题
英文描述
Write a function which takes a function f and a variable number of maps. Your function should return a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) should be combined with the mapping in the result by calling (f val-in-result val-in-latter)
test not run
翻译
编写一个函数,该函数需要一个函数f和可变数量的映射。您的函数应返回一个映射,该映射由映射到第一个映射的其余映射组成。如果一个键出现在多个映射中,则应通过调用(f val-in-result val-in-late)将后者的映射(从左到右)与结果中的映射合并测试
测试案例
- (= (__ * {:a 2, :b 3, :c 4} {:a 2} {:b 2} {:c 5})
{:a 4, :b 6, :c 20}) - (= (__ - {1 10, 2 20} {1 3, 2 10, 3 15})
{1 7, 2 10, 3 15}) - (= (__ concat {:a [3], :b [6]} {:a [4 5], :c [8 9]} {:b [7]})
{:a [3 4 5], :b [6 7], :c [8 9]})
题目解析
- 参数1 为函数,参数2为map,后续参数都为map
- 后续参数中map的key如存在与参数2map中,则val值为两map的val值作为函数的参数执行的结果
- 如后续参数中的key不在map2中,则将这个key-val加到map2中
答案代码
(fn f690
[f map1 & maps]
(let [map2 (into {} maps)
f* (fn ff69 [map [k v]]
(if (not= nil (get map k))
(assoc map k (f (get map k) v))
(assoc map k v)))]
(reduce f* map1 map2 )))
第74题
英文描述
Given a string of comma separated integers, write a function which returns a new comma separated string that only contains the numbers which are perfect squares.
翻译
给定一串用逗号分隔的整数,编写一个函数,该函数返回一个新的用逗号分隔的字符串,该字符串仅包含由正整数(有正整数的平凡根)组成的数字。
题目解析
- 首先需要将字符串分割成序列
- 然后判断每个值是否有正整数的平方根
- 将满足条件的字符拼接在一起
答案代码
(fn f7774
[args]
(let [acc (clojure.string/split args #",")
f1 (fn
[args1]
(loop [n 0]
(if (<= n (Math/sqrt args1))
(if (= (* n n) args1)
true
(recur (inc n)))
false))
)
f2 (fn [str2 arg2]
(if (f1 (Integer/parseInt arg2))
(str str2 (str arg2 ","))
str2))
result (reduce f2 "" acc)]
(if (> (count result) 2)
(subs result 0 (- (count result) 1))
result))
)
总结说明
以上代码均以个人思路为前提编写的代码,题目答案并不唯一。
clojure作为函数式编程语言相比java语言,一个很大的特点就是没有变量,所以很多题目跟java解题思路完全不一样;编写答案代码量相对与java而言少很多。本人目前学习Clojure一周多点的时间,理解有限,所以上述题目可能还有更简洁的答案。