2010-09-12 24 views
5

Tôi gần như hoàn thành nhiệm vụ này và nó đang giết tôi. Đây là bài THIRD của tôi về ba phần khác nhau của điều này, và tôi thành thật xấu hổ rằng tôi đang đấu tranh nhiều với nhiệm vụ này. Bản thân bài tập là tạo một chương trình thực hiện phép cộng và trừ các số nguyên lớn bằng cách sử dụng các danh sách liên kết (và từ từ tôi bắt đầu ghét các danh sách liên kết, bên ngoài Lisp). Mọi thứ dường như đang hoạt động, tiết kiệm cho việc cộng và trừ thực tế. Tôi không chắc liệu đó có phải là hàm số học hay không, bởi vì chúng hoạt động trước đây (nhưng không bao giờ 100%), nhưng nó không đau khi kiểm tra với cộng đồng S/O (thông thường tôi sẽ không yêu cầu điều này nhiều lắm giúp đỡ trong một bài tập bởi vì tôi thích tự mình tìm ra những thứ khác, nhưng đây là một tuần đầy khủng khiếp và bận rộn, và thời hạn nhanh chóng đến gần).Thêm và trừ Bigints bằng cách sử dụng các danh sách được liên kết

Các hàm số học tôi đã viết như sau, bất kỳ ai cũng có thể giúp tôi tìm ra điều gì sai?

/* 
* Function add 
* 
* @Paramater STRUCT* Integer 
* @Parameter STRUCT* Integer 
* 
* Takes two linked lists representing 
* big integers stored in reversed order, 
* and returns a linked list containing 
* the sum of the two integers. 
* 
* @Return STRUCT* Integer 
* 
* TODO Comment me 
*/ 
struct integer* add(struct integer *p, struct integer *q) 
{ 
    int carry = 0; 

    struct integer *sHead, *sCurr; 
    struct integer *pHead, *qHead; 

    pHead = p; 
    qHead = q; 

    sHead = NULL; 

    while(p) 
    { 
     sCurr = (struct integer*) malloc (sizeof(struct integer)); 
     sCurr->digit = p->digit + q->digit + carry; 
     sCurr->next = sHead; 
     sHead = sCurr; 

     carry = 0; 

     /* 
     * If the current digits sum to greater than 9, 
     * create a carry value and replace the current 
     * value with value mod 10. 
     */ 
     if(sCurr->digit > 9) 
     { 
      carry = 1; 
      sCurr->digit = sCurr->digit % 10; 
     } 

     /* 
     * If the most significant digits of the numbers 
     * sum to 10 or greater, create an extra node 
     * at the end of the sum list and assign it the 
     * value of 1. 
     */ 
     if(carry == 1 && sCurr->next == NULL) 
     { 
      struct integer *sCarry = (struct integer*) malloc (sizeof(struct integer)); 
      sCarry->digit = 1; 
      sCarry->next = NULL; 
      reverse(&sCurr); 
      sCurr->next = sCarry; 
      reverse(&sCurr); 
     } 

     p = p->next; 
     if(q->next) q = q->next; 
     else q->digit = 0; 
    } 

    return sHead; 
} 

/* 
* Function subtract 
* 
* @Parameter STRUCT* Integer 
* @Parameter STRUCT* Integer 
* 
* Takes two linked lists representing struct integers. 
* Traverses through the lists, subtracting each 
* digits from the subsequent nodes to form a new 
* struct integer, and then returns the newly formed 
* linked list. 
* 
* @Return STRUCT* Integer 
* 
* TODO Comment me 
*/ 
struct integer* subtract(struct integer *p, struct integer *q) 
{ 
    int borrow = 0; 

    struct integer *dHead, *dCurr; 
    struct integer *pHead, *qHead; 

    pHead = p; 
    qHead = q; 

    dHead = NULL; 

    while(p) 
    { 
     dCurr = (struct integer*) malloc (sizeof(struct integer)); 
     if(q) 
     { 
      dCurr->digit = p->digit - q->digit - borrow; 
     } 
     else 
     { 
      dCurr->digit = p->digit - borrow; 
     } 
     dCurr->next = dHead; 

     if(dCurr->digit < 0) 
     { 
      dCurr->digit += 10; 
      borrow = 1; 
     } 

     dHead = dCurr; 

     p = p->next; 
     if(q->next) q = q->next; 
    } 

    return dHead; 
} 



Sản lượng mẫu sẽ trông như thế này:

8888888888 + 2222222222 = 11111111110 
10000000000 – 9999999999 = 1 
10000000000 – 9999999999 = 1 

nhưng thay vào đó, nó trông như thế này:

8888888888 + 2222222222 = 1111111110 
10000000000 - 9999999999 = 10000000001 
10000000000 - 9999999999 = 10000000001 

EDIT Toàn bộ chương trình, ở dạng hiện tại lúc 3:30 chiều EST, có sẵn here để tham khảo hoặc trong trường hợp các chức năng này không phải là vấn đề.

+0

Cách sử dụng trình gỡ lỗi và hiển thị những gì đã xảy ra trên mỗi bước. Dường như nó không phải là về danh sách liên kết, nhưng về cách bạn trừ đi. BTW, tốt hơn nên đặt tên là "mượn" hơn "mang" trừ đi. – pmod

+0

Quan tâm đặc biệt là đầu ra của dCurr-> chữ số, p-> chữ số, q-> chữ số. Và bạn đã không hiển thị như thế nào là loại số nguyên được xác định. – pmod

+0

@Pmod Xin lỗi, tôi sẽ đưa lên một phần trước của toàn bộ chương trình làm tài liệu tham khảo. – Andy

Trả lời

1

else q->digit = 0;
Bạn đang thay đổi đối số bên trong hàm.

Thử thay đổi chức năng của bạn để chấp nhận các đối số const và biên dịch lại.

struct integer* add(const struct integer *p, const struct integer *q) 
struct integer* subtract(const struct integer *p, const struct integer *q) 
+0

Là một phần của nhiệm vụ, tôi không thể thay đổi định nghĩa chức năng. :/ – Andy

+0

Ok, nhưng vẫn thay đổi, biên dịch với 'const' cho đến khi bạn không nhận được lỗi, sau đó xóa' const' :) – pmg

+0

Nó chỉ ra rằng vấn đề lớn nhất WS 'else q-> digit = 0' về một trong số các lỗi đáng kinh ngạc, cảm ơn vì đã chỉ ra điều đó. – Andy

1

Phần mà đọc

if(dCurr->next == NULL && carry == 1) 
{ 
    struct integer *dCarry = (struct integer*) malloc (sizeof(struct integer)); 
    dCarry->digit = -1; 
    dCarry->next = NULL; 
    dCurr->next = dCarry; 
} 

trông hơi ra khỏi chỗ. Từ mã ở trên, dCurr->next được đặt là các chữ số mà chúng tôi đã tính toán trong các vòng trước đó, vì vậy nó chỉ là NULL trên chữ số đầu tiên. Tôi nghĩ rằng bạn có nghĩa là để kiểm tra p->next thay thế.

Tôi giả định rằng điều kiện len(p) >= len(q) giữ cho chức năng này. Nếu không, bạn sẽ phải làm một cái gì đó về xử lý nơi nó không giữ (chạy ra khỏi các nút p trước khi bạn chạy ra khỏi q nút). Tôi cũng giả sử các chữ số nằm trong danh sách từ chữ số ít quan trọng nhất đến chữ số quan trọng nhất. Nếu không, bạn có thể cần phải đảo ngược p và q trước khi xử lý chúng.

Một điều khác mà tôi không thể hiểu là cách bạn xử lý các số âm. Hoặc thậm chí nếu bạn có nghĩa vụ phải xử lý chúng. Không dễ dàng thêm vào một cấu trúc như thế này, bởi vì cách tiếp cận ngây thơ của việc thêm thứ gì đó vào cuối sẽ không hoạt động khi trừ đi: khi q là số âm, bạn sẽ đi tới tất cả các rắc rối trừ q từ p, và sau đó khám phá bạn nên thêm vào thay vào đó.

+0

May mắn thay, chương trình chỉ đề với số nguyên không âm. Ngoài ra, tôi đã thiết lập nó để 'trừ()' không bao giờ được gọi với 'p Andy

1

Trong chức năng compare() bạn "đi bộ" p và sau đó thử đi lại lần nữa.

int compare(struct integer *p, struct integer *q) 
{ 
    /* ... */ 
    while(p) 
    { 
     pCount++; 
     p = p->next; 
    } 

p bây giờ là NULL

/* ... */ 
    while(p) 
    { 
     /* ... */ 
    } 

Vòng lặp while không bao giờ chạy.

+0

Rất tốt, cảm ơn bạn. Bây giờ vấn đề duy nhất còn lại là hàm 'subtract()'. :( – Andy

+0

Điều gì xảy ra nếu độ dài của các số cần trừ là khác nhau? Hãy nói '12' - '8' ... Hoạt động của chữ số đầu tiên của hàm là gì? – pmg

+0

Vâng, các số được lưu trữ ngược lại, vì vậy nó nên làm '2 - 8 = -6', và sau đó' -6 + 10 = 4' – Andy

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