Find how many times each number appears in the list

If we had a list Acontaining (1 2 1 1 2 3 3 4 4 4)how we could get a new list Bwith ((1 . 30) (2 . 20) (3 . 20) (4 . 30))in it, so number_after_dot is a percentage of the number_before_dot in the list A.

For example, it 1is 30% of the list A, 220% of the list A, etc.

(1 . 30) is a pair that can be made using (cons 1 30)

+3
source share
2 answers

I think you want to calculate a percentage list equal to each element. You used the word "unique", but this is a bit confusing as there are no unique elements in your list. This is based on your input and output example, where the list (1 2 1 1 2 3 3 4 4 4)consists of "30% units."

You can break it down into roughly a recursive algorithm consisting of the following steps:

  • If the input list is empty, return an empty list.
  • Otherwise, get the first item. Calculate how many times this happens on the list.
  • Calculate the percentage and consitem with this percentage.
  • Remove all occurrences of the first item from the list cdrin the list.
  • Record this list and the conslist of pairs (element . percentage).

To make the first part, use filter:

> (filter (lambda (x) (eq? (car A) x)) A)
(1 1 1)

A (1 1 1). , :

> (length (filter (lambda (x) (eq? (car A) x)) A))
3

, (length A) 100:

> (* 100 (/ (length (filter (lambda (x) (eq? (car A) x)) A)) (length A)))
30

cons (car A) .

, remove, filter: , :

> (remove (lambda (x) (eq? (car A) x)) A)
(2 2 3 3 4 4 4)

, . , ( ) . , - , , .

, , , , , . , !

(define (percentages all)
  (let ((len (length all))) ; pre-calculate the length
    ;; this is an internal definition which is called at ***
    (define (p rest)
      (if (null? rest)
          rest
          ;; equal-to is a list of all the elements equal to the first
          ;; ie something like (1 1 1)
          (let ((equal-to (filter (lambda (x) (eq? (car rest) x))
                                  rest))
                ;; not-equal-to is the rest of the list
                ;; ie something like (2 2 3 3 4 4 4)
                (not-equal-to (remove (lambda (x) (eq? (car rest) x))
                                      rest)))
            (cons (cons (car rest) (* 100 (/ (length equal-to) len)))
                  ;; recurse on the rest of the list
                  (p not-equal-to)))))
    (p all))) ; ***
+2

. :

  • .
  • .
  • , .

:

(define (run-length-encode lst)
  (define (rle val-lst cur-val cur-cnt acc)
    (if (pair? val-lst)
        (let ((new-val (car val-lst)))
          (if (eq? new-val cur-val)
              (rle (cdr val-lst) cur-val (+ cur-cnt 1) acc)
              (rle (cdr val-lst) new-val 1 (cons (cons cur-val cur-cnt) acc))))
        (cons (cons cur-val cur-cnt) acc)))
  (if (pair? lst)
      (reverse (rle (cdr lst) (car lst) 1 '()))
      '()))

:

(define (scale-cdr count-list total-count)
  (define (normalize pr)
    (cons (car pr) (/ (* 100 (cdr pr)) total-count)))
  (map normalize count-list))

-, . sort ( ). :

(define (elem-percent lst)
  (scale-cdr (run-length-encode (sort lst <)) (length lst)))

:

> (elem-percent '())
'()
> (elem-percent (list 1 2 3 4 5))
'((1 . 20) (2 . 20) (3 . 20) (4 . 20) (5 . 20))
> (elem-percent (list 1 2 1 1))
'((1 . 75) (2 . 25))
> (elem-percent (list 1 2 1 1 2 3 3 4 4 4))
'((1 . 30) (2 . 20) (3 . 20) (4 . 30))
+2

Source: https://habr.com/ru/post/1787613/


All Articles