2011-09-29 21 views
10

Bất cứ ai có thể vui lòng cung cấp cho tôi một ví dụ có thể giúp tôi hiểu các mô hình lập trình thủ tục, chức năng, logic và hướng đối tượng cạnh nhau bằng cách sử dụng cùng một ví dụ-vấn đề.Bạn có thể trình bày cùng một ví dụ bằng cách sử dụng các ngôn ngữ lập trình Thủ tục, Chức năng, Logic và OO không?

Vui lòng cung cấp cho tôi đoạn mã ví dụ về vấn đề tương tự bằng cách sử dụng các ngôn ngữ lập trình Thủ tục, Chức năng, Logic và OO.

+1

Hmm. Bạn chấp nhận câu trả lời của tôi, sau đó không chấp nhận nó và cung cấp một tiền thưởng. Điều gì đã thay đổi suy nghĩ của bạn? (Chỉ cần tò mò, không trolling cho đại diện.) –

+1

Hầu hết các mã được dự định để chứng minh các tính năng ngôn ngữ chứ không phải là Paradigm/Phương pháp luận của ngôn ngữ. – anonymous

Trả lời

8

Chúng ta hãy thử đơn giản hơn ví dụ - chỉ tính số Fibonacci n-th.

Thứ nhất, thủ tục (trong Pascal):

program Fibonacci; 

function fib(n: Integer): Integer; 
var a: Integer = 1; 
    b: Integer = 1; 
    f: Integer; 
    i: Integer; 
begin 
    if (n = 1) or (n = 2) then 
    fib := 1 
    else 
    begin 
     for i := 3 to n do 
     begin 
     f := a + b; 
     b := a; 
     a := f; 
     end; 
     fib := f; 
    end; 
end; 

begin 
    WriteLn(fib(6)); 
end. 

Ví dụ này cho thấy tính năng của ngôn ngữ thủ tục:

  • Có một số chương trình con (hàm trong trường hợp này)
  • biến được gán giá trị có thể nhiều lần (: = nhà điều hành)
  • Có chu kỳ (cho nhà điều hành trong trường hợp này)
  • Ngôn ngữ là bắt buộc, tức là chúng ta đang nói với máy tính phải làm gì để những gì

Thứ hai, đối tượng định hướng (bằng Python):

class Fibonacci: 
    def __init__(self): 
     self.cache = {} 
    def fib(self, n): 
     if self.cache.has_key(n): 
      return self.cache[n] 
     if n == 1 or n == 2: 
      return 1 
     else: 
      a = 1 
      b = 1 
      for i in range(2, n): 
       f = a + b; 
       b = a; 
       a = f; 
      self.cache[n] = f; 
      return f; 


fibonaccyCounter = Fibonacci() 
print fibonaccyCounter.fib(6) 

Trên thực tế các vấn đề không đáng để tạo một lớp, vì vậy tôi đã thêm bộ nhớ đệm của các kết quả đã được tính toán.

Ví dụ này cho thấy:

  • lớp và instantiation (tạo chẳng hạn) nó
  • lớp đã phần bộ nhớ, tiểu bang riêng (tự và các thành viên của nó)
  • Ngôn ngữ là bắt buộc, tức là sở hữu chúng tôi đang nói với máy tính phải làm gì theo thứ tự nào

Không được hiển thị nhưng chúng tôi có thể ví dụ xuống lớp này từ lớp trừu tượng trả về thành viên thứ n của một số chuỗi. Bởi subslassing chúng tôi nhận lớp xác định dãy Fibonacci, dãy 1,2,3 ..., chuỗi 1,4,9,16, ... vv

Thứ ba, trong phong cách chức năng (Haskell):

import Text.Printf 

fib :: Int -> Int 
fib 0 = 0 
fib 1 = 1 
fib n = fib (n-1) + fib (n-2) 

main = printf "%d\n" (fib 6) 

tính năng sau của một mô hình lập trình chức năng được thể hiện:

  • không có nhà nước, không có biến - chỉ cần chức năng xác định
  • không có chu kỳ - chỉ đệ quy
  • đối sánh mẫu: chúng tôi đã xác định riêng "fib 0", "fib 1" và "fib n" đối với các số còn lại, không có cấu trúc nào như nếu là cần thiết
  • kiểu khai báo - chúng tôi không xác định thứ tự các bước cần tính chính giá trị hàm: trình biên dịch/thông dịch viên/thời gian chạy con số này ra bởi chính nó, cho các định nghĩa chức năng. Chúng tôi nói với máy tính những gì chúng tôi muốn nhận được, không phải làm gì.
  • Đánh giá lười biếng. Nếu chính được gọi là "fib 2" thì "fib n" không được gọi vì các hàm chỉ được đánh giá khi kết quả của chúng là cần thiết để được chuyển thành tham số cho các hàm khác.

Nhưng tính năng chính của ngôn ngữ chức năng là các hàm là đối tượng lớp đầu tiên. Điều này có thể được chứng minh bằng thực hiện khác của fib:

fib n = fibs!!n 
fibs = 0 : 1 : zipWith (+) fibs (tail fibs) 

Ở đây chúng ta đang đi qua fibs chức năng như tham số để zipWith chức năng. Ví dụ này cũng thể hiện đánh giá lười biếng: danh sách "vô hạn" chỉ được tính đến mức cần thiết cho các chức năng khác.

Nhân tiện, chức năng không cần thiết có nghĩa là không hướng đối tượng. Một ví dụ về ngôn ngữ lập trình có cả chức năng và hướng đối tượng là Scala.

Prolog:

fib(1, 1). 
fib(2, 1). 


fib(X, Y):- 
     X > 1, 
     X1 is X - 1, 
     X2 is X - 2, 
     fib(X1, Z), 
     fib(X2, W), 
     Y is W + Z. 


main :- 
    fib(6,X), write(X), nl. 

Tiếp theo đặc điểm của phong cách lập trình logic có thể được nhìn thấy:

  • Ngôn ngữ là tường thuật. Như trong phong cách chức năng, chúng ta định nghĩa mọi thứ và không nói ra thứ tự để làm chúng.
  • Nhưng sự khác biệt với kiểu chức năng là chúng ta định nghĩa các biến vị ngữ, chứ không phải các hàm. Trong trường hợp này, biến vị ngữ fib (X, Y) có nghĩa là "số Fibonacci X là Y".Cho một số vị ngữ đã biết (fib (1, 1) và fib (2, 1) - tức là số Fibonacci đầu tiên là 1 và số Fibonacci thứ hai là 1) và các quy tắc suy ra các biến vị ngữ khác (Y là số Fibonacci X-thứ Y là một tổng số Fibonacci X-1 và số Fibonacci X-2), Prolog sẽ làm cho các vị từ được đề cập đến. Trên thực tế có thể có nhiều hơn 1 câu trả lời!
  • Không có giá trị đầu vào và giá trị trả về - thay vì điều này, chúng tôi xác định mối quan hệ giữa "đầu vào" và "đầu ra".

Chương trình này cũng có thể được sử dụng để tìm ra rằng Fibonacci số 8 là ở vị trí thứ 6 trong chuỗi:

?- between(0,inf,X), fib(X,8). 
X = 6 . 
+1

Tính năng chính của các ngôn ngữ chức năng là các hàm là các đối tượng lớp đầu tiên, tức là có thể được liên kết với "biến", được chuyển thành tham số, được trả về từ các hàm khác. Ví dụ của tôi trong Haskell đã không thể hiện điều này. Tôi đang thay thế nó bằng cách sử dụng danh sách vô hạn và 'zipWith'. –

6

Euler Vấn đề Dự án số 2: http://projecteuler.net/problem=2

Haskell (chức năng/logic):

p2 = sum [x | x <- fibs, (x `mod` 2) == 0] where 
    fibs = unfoldr acc (0,1) where 
      acc (prev, cur) | (prev+cur) > 4000000 = Nothing 
          | otherwise   = Just (prev+cur, (cur, prev+cur)) 

Python (OO):

class FibSum(object): 
    def __init__(self, end): 
     self.end = end 
     self.next_two = (1,0) 
     self.sum = 0 

    def __iter__(self): 
     return self 

    def next(self): 
     current, previous = self.next_two 
     self.next_two = (previous+current, current) 
     new = current+previous 

     if current >= self.end: 
      raise StopIteration 
     elif (new % 2) == 0: 
      self.sum += new 
     else: 
      pass 


fibcount = FibSum(4000000) 
[i for i in fibcount] 
print fibcount.sum 

C (thủ tục/bắt buộc):

#include <stdio.h> 

int main(void) 
{ 
    long int sum, newnum, previous = 0; 
    long int current = 1; 

    while(current <= 4000000) 
    { 
     newnum = previous+current; 
     if ((newnum % 2) == 0) 
     { 
      sum = sum + newnum; 
     } 
     previous = current; 
     current = newnum; 

    } 
    printf("%d\n", sum); 
} 

Và đây là một phiên bản rất không hiệu quả bằng văn bản trong MIT Scheme

(define (unfold func seed) 
    (let* ((result (func seed))) 
    (cond ((null? result)()) 
    (else (cons (car result) (unfold func (second result))))))) 

(define (test x) 
    (cond ((> (sum x) 4000000)()) 
    (else (list (sum x) (list (second x) (sum x)))))) 

(define (sum xs) 
    (cond ((null? (cdr xs)) (first xs)) 
    (else (+ (car xs) (sum (cdr xs)))))) 

(sum (filter (lambda (x) (eq? (modulo x 2) 0)) (unfold test (list 0 1)))) 

Prolog: Take from this here, posted by 13tazer31

fibonacci(_,Current,End,0) :- 
     Current > End. 
fibonacci(Previous, Current, End, Total) :- 
     divisible(Current, 2), 
     Next is Current + Previous, 
     fibonacci(Current, Next, End, Sum), 
     Total is Sum + Current, !. 
fibonacci(Previous, Current, End, Total) :- 
     Next is Current + Previous, 
     fibonacci(Current, Next, End, Total). 

divisible(Number, 0) :- 
     write(‘Error: division by 0′).   
divisible(Number, Divisor) :- 
     Number mod Divisor =:= 0. 
+0

Tôi không biết bất kỳ prolog nào, nhưng nó sẽ rất giống với phiên bản Haskell, và bạn có thể dễ dàng tìm thấy một số prolog trên các diễn đàn Project Euler giải quyết vấn đề này (tôi nghĩ bạn phải nhập câu trả lời đúng để truy cập nó) – Wes

+0

Tôi biết đây là lỗi của câu hỏi khi hỏi đoạn trích, nhưng có vẻ như không có đoạn nào trong số này thực sự thể hiện bất kỳ điều gì thành ngữ về những ngôn ngữ này. – Gian

1

Vâng nó rất đơn giản

  1. thủ tục, chức năng luận lý phép nói rằng bạn muốn tính toán điều gì đó (đó là những gì máy tính làm)
    1. giải quyết vấn đề thành các hàm f1, f2, f3 .... bây giờ nếu bạn nhìn vào vấn đề, bạn thấy nó được chia thành các hàm .. nhưng phải có điểm bắt đầu (từ nơi bạn bắt đầu tính toán) và điểm kết thúc (nơi bạn kết thúc tính toán) và giữa chúng là các hàm (f1, f2, f3). Vì vậy, những gì bạn đã thực sự thực hiện thay vì viết một hàm lớn (F) thực hiện mọi thứ và rất dài bạn đã phá vỡ nó thành các phần nhỏ hơn (được gọi là tái cấu trúc). Hiểu một hàm duy nhất dài 150 dòng là nhàm chán .. khi bạn đến cuối dòng, bạn sẽ quên nơi bạn bắt đầu, do đó chúng tôi chia nhỏ mọi thứ. Bây giờ chúng ta tính toán như thế nào ---> Chúng ta tạo ra một hàm duy nhất là tính toán() (gọi là mặt tiền) sẽ gọi các hàm còn lại (f1, f2, f3 ...) theo thứ tự mong muốn và sẽ trả về kết quả. Bây giờ hãy hiểu điều này: Nếu chúng tôi đã viết một hàm duy nhất có khoảng 150 dòng (độ phức tạp tăng lên) giả sử chúng tôi chia nhỏ nó thành 3 hàm và nói rằng mỗi chức năng là 50 dòng (quản lý được). chúng tôi giảm độ phức tạp vì tổng các dòng của 3 hàm vẫn là 150: D. sự phức tạp được giảm theo tên hàm .. trong đó nêu rõ chức năng làm gì .. nó có nghĩa là nhìn vào tên bạn có thể có một ý tưởng về chức năng của nó.

OO Lập trình logic:
Bây giờ chức năng nằm rải rác trong logic chức năng .. khi chúng tôi mang đến tất cả các chức năng liên quan (hành vi) bên trong một ô duy nhất (Class), chúng tôi đã giảm hơn nữa mức độ phức tạp. làm thế nào .. bởi "Tên lớp". Bây giờ bạn có thể nói rằng thay vì gọi f1, f2, f3 .. chúng ta gọi c1.f1(), c2.f2, c3.f3() trong đó "c" biểu thị một lớp (thiết kế điều khiển miền).

imp .. bất kể bạn sử dụng oops hay logic chức năng luôn luôn có điểm bắt đầu và kết thúc của tính toán ... nhớ tính toán() tôi đã nói về .. và câu hỏi là ai gọi nó .. và câu trả lời là bạn .. Tất cả mọi thứ OOP của logic hoặc logic thủ tục được ẩn đằng sau nó (Service Facade)

Các vấn đề liên quan