2016-02-29 67 views
0

因此,我的任務要求我們使用雙向鏈表來將數字相加或相乘並打印出來。我能夠得到它的整個數字,但我不知道要改變什麼,以使其工作十進制數。這是迄今爲止我所擁有的。我知道這不是最有效或最乾淨的代碼,但我可以嘗試澄清的東西,如果它對你沒有意義 例如,如果我做50382 + 9281或482891 * 29734這個程序將工作正常,但我需要讓它工作的東西像4.9171 + 49.2917或423.135 * 59我有一個程序,適用於整數,但我需要得到它的工作十進制數字

編輯:假裝int值是雙打。我改變了它在我的實際代碼,但是當我做數學題,仍然是給我一個整數,所以我需要弄清楚如何在正確的地方

#include <iostream> 
#include <fstream> 
#include <string> 
#include <stdio.h> 
#include <cstdlib> 
#include <cstring> 
using namespace std; 
// A recursive program to add two linked lists 
#include <stdlib.h> 
#include <assert.h> 
#include <math.h> 
#include <string.h> 

// A linked List Node 
struct node 
{ 
    int data; 
    node* next; 
    node *prev; 
}; 

typedef struct node node; 

class LinkedList{ 


    // public member 
public: 
    // constructor 
    LinkedList(){ 
     int length = 0; 
     head = NULL; // set head to NULL 

     node *n = new node; 
     n->data = -1; 
     n->prev = NULL; 
     head = n; 
     tail = n; 
    } 

    // This prepends a new value at the beginning of the list 
    void addValue(int val){ 
     node *n = new node(); // create new Node 
     n->data = val;    // set value 
     n->prev = tail;   // make the node point to the next node. 

    // head->next = n; 
    // head = n; 
    // tail->next = n;      // If the list is empty, this is NULL, so the end of the list --> OK 
     tail = n;    // last but not least, make the head point at the new node. 
    } 

    void PrintForward(){ 
     node* temp = head; 
     while(temp->next != NULL){ 
      cout << temp->data; 
      temp = temp->next; 
     } 
     cout << '\n'; 
    } 

    void PrintReverse(){ 
     node* temp = tail; 
     while(temp->prev != NULL){ 
      cout << temp->data; 
      temp = temp->prev; 
     } 
     cout << '\n'; 
    } 

    void PrintReverse(node* in){ 
     node* temp = in; 
     if(temp->prev== NULL){ 
       if(temp->data == -1) 
      cout << temp->data << '\n'; 
      } 
     else{ 
      cout << temp->data << '\n'; 
      temp = temp->prev; 
      PrintReverse(temp); 

      } 
    } 
    // returns the first element in the list and deletes the Node. 
    // caution, no error-checking here! 
    int popValue(){ 
     node *n = head; 
     int ret = n->data; 

     head = head->next; 
     delete n; 
     return ret; 
    } 

    void swapN(node** a, node**b){ 
     node*t = *a; 
     *a = *b; 
     *b = t; 
    } 


     node *head; 
     node *tail; 
     // Node *n; 
}; 

/* A utility function to insert a node at the beginning of linked list */ 
    void push(struct node** head_ref, int new_data) 
    { 
     /* allocate node */ 
     struct node* new_node = (struct node*) malloc(sizeof(struct node)); 

     /* put in the data */ 
     new_node->data = new_data; 

     /* link the old list off the new node */ 
     new_node->next = (*head_ref); 

     /* move the head to point to the new node */ 
     (*head_ref) = new_node; 
    } 

/* A utility function to print linked list */ 
    void printList(struct node *node) 
    { 
     while (node != NULL) 
     { 
      printf("%d", node->data); 
      node = node->next; 
     } 
    // printf("\n"); 
    } 

// A utility function to swap two pointers 
    void swapPointer(node** a, node** b) 
    { 
     node* t = *a; 
     *a = *b; 
     *b = t; 
    } 

/* A utility function to get size of linked list */ 
    int getSize(struct node *node) 
    { 
     int size = 0; 
     while (node != NULL) 
     { 
      node = node->next; 
      size++; 
     } 
     return size; 
    } 

// Adds two linked lists of same size represented by head1 and head2 and returns 
// head of the resultant linked list. Carry is propagated while returning from 
// the recursion 
    node* addSameSize(node* head1, node* head2, int* carry) 
    { 
     // Since the function assumes linked lists are of same size, 
     // check any of the two head pointers 
     if (head1 == NULL) 
      return NULL; 

     int sum; 

     // Allocate memory for sum node of current two nodes 
     node* result = (node *)malloc(sizeof(node)); 

     // Recursively add remaining nodes and get the carry 
     result->next = addSameSize(head1->next, head2->next, carry); 

     // add digits of current nodes and propagated carry 
     sum = head1->data + head2->data + *carry; 
     *carry = sum/10; 
     sum = sum % 10; 

     // Assigne the sum to current node of resultant list 
     result->data = sum; 

     return result; 
    } 

// This function is called after the smaller list is added to the bigger 
// lists's sublist of same size. Once the right sublist is added, the carry 
// must be added toe left side of larger list to get the final result. 
    void addCarryToRemaining(node* head1, node* cur, int* carry, node** result) 
    { 
     int sum; 

     // If diff. number of nodes are not traversed, add carry 
     if (head1 != cur) 
     { 
      addCarryToRemaining(head1->next, cur, carry, result); 

      sum = head1->data + *carry; 
      *carry = sum/10; 
      sum %= 10; 

      // add this node to the front of the result 
      push(result, sum); 
     } 
    } 

// The main function that adds two linked lists represented by head1 and head2. 
// The sum of two lists is stored in a list referred by result 
    void addList(node* head1, node* head2, node** result) 
    { 
     node *cur; 

     // first list is empty 
     if (head1 == NULL) 
     { 
      *result = head2; 
      return; 
     } 

     // second list is empty 
     else if (head2 == NULL) 
     { 
      *result = head1; 
      return; 
     } 

     int size1 = getSize(head1); 
     int size2 = getSize(head2) ; 

     int carry = 0; 

     // Add same size lists 
     if (size1 == size2) 
      *result = addSameSize(head1, head2, &carry); 

     else 
     { 
      int diff = abs(size1 - size2); 

      // First list should always be larger than second list. 
      // If not, swap pointers 
      if (size1 < size2) 
       swapPointer(&head1, &head2); 

      // move diff. number of nodes in first list 
      for (cur = head1; diff--; cur = cur->next); 

      // get addition of same size lists 
      *result = addSameSize(cur, head2, &carry); 

      // get addition of remaining first list and carry 
      addCarryToRemaining(head1, cur, &carry, result); 
     } 

     // if some carry is still there, add a new node to the fron of 
     // the result list. e.g. 999 and 87 
     if (carry) 
      push(result, carry); 
    } 

     node* reverse_list(node *m) 
     { 
      node *next = NULL; 
      node *p = m; 
      node *prev; 

      while (p != NULL) { 
       prev = p->prev; 
       p->prev = next; 
       next = p; 
       p = prev; 
      } 

      return prev; 
     } 


    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
      void Multiply2(node* n1, node* n2); 
      int digitsPerNode = 2; 
      node* result; 
      node* resultp = result; 
      node* resultp2 = result; 
      void Multiply(node* n1, node* n2) 
      { 
       if (n2->prev != NULL) 
       { 
        Multiply(n1, n2->prev); 
       } 

       Multiply2(n1, n2); 
       resultp2 = resultp = resultp->prev; 
      } 

     void Multiply2(node* n1, node* n2) 
      { 
       if (n1->prev != NULL) 
       { 
        Multiply2(n1->prev, n2); 
       } 

       if (resultp2 == NULL) 
       { 
        resultp2->data = 0; 
        result = resultp = resultp2; 
       } 

       int m = n1->data * n2->data + resultp2->data; 

       int carryon = (int)(m/pow(10, digitsPerNode)); 
       resultp2->data = m % (int)pow(10, digitsPerNode); 
       if (carryon > 0) 
       { 
        if (resultp2->prev == NULL) 
        { 
         resultp2->prev->data = carryon; 
        } 
        else 
        { 
         resultp2->prev->data += carryon; 
        } 
       } 

       resultp2 = resultp2->prev; 
      } 






      /* int* buffer; 
      int lenBuffer = 0; 
      void multiplyHelper(int v, node* , int o); 
      void addToBuffer(int v, int i); 
      node* multiply(node* num1, node* num2) 
     { 
      if (num1 == NULL || num2 == NULL) return NULL; 

      int length1 = getSize(num1); 
      int length2 = getSize(num2); 
      if (length1 > length2) return multiply(num2, num1); 

      // initialize buffer 
      lenBuffer = length1 + length2; 
      buffer = new int[lenBuffer]; 
      memset(buffer, 0, sizeof(int) * lenBuffer); 

      // multiply 
      int offset = 0; 
      node* anode = num1; 
      while (anode && anode->data!= -1) 
      { 
       multiplyHelper(anode->data, num2, offset); 
       anode = anode->prev; 
       offset++; 
      } 
      // transfer buffer to a linked list 
      node* h; 
      int pos = 0; 

      while (pos < lenBuffer && buffer[pos] == 0) pos++; 
      if (pos < lenBuffer) 
      { 

       node* temp; 
       temp->data = buffer[pos++]; 
       h = temp; 

       anode = h; 
       while (pos < lenBuffer) 
       { 
        node* temp; 
        temp->data = buffer[pos++]; 
        anode->prev = temp; 
        anode = anode->prev; 
       } 
      } 
      delete buffer; 
      lenBuffer = 0; 
      buffer = NULL; 
      cout << h->data << endl; 
      return h; 
     } 

     // multiply a single digit with a number 
     // called by multiply() 
     void multiplyHelper(int value, node* head, int offset) 
     { 
      // assert(value >= 0 && value <= 9 && head != NULL); 
      if (value == 0) return; 

      node* anode = head; 
      int pos = 0; 
      while (anode != NULL) 
      { 
       int temp = value * anode->data; 
       int ones = temp % 10; 
       if (ones != 0) addToBuffer(ones, offset + pos + 1); 
       int tens = temp/10; 
       if (tens != 0) addToBuffer(tens, offset + pos); 

       anode = anode->prev; 
       cout << anode->data; 
       pos++; 
      } 

     } 

     // add a single digit to the buffer at place of index 
     // called by multiplyHelper() 
     void addToBuffer(int value, int index) 
     { 
     // assert(value >= 0 && value <= 9); 
      while (value > 0 && index >= 0) 
      { 
       int temp = buffer[index] + value; 
       buffer[index] = temp % 10; 
       value = temp/10; 
       index--; 
      } 
     }*/ 


// Driver program to test above functions 
    int main(int argc, char *argv[]) 
    { 
     char filename[50]; 
     string name= argv[1]; 
     string dig; 
     name.erase(0,9);//Parse input to only get input file. 
     ifstream file; 
     int digits; 
     for(int i = 0; i < name.length(); i++){ 
      if(name.at(i) == ';'){ 
      //  dig = name.substr(0,name.length()-i); 
       name = name.substr(0,name.length()-i); 
      } 
     } 
     //cout << dig << endl; 
     //file.open("input.txt"); 
     file.open(name.c_str()); 
     digits = 2; 
     /////// 



     /////////////////////////////////////////////////////////////////////// 
     int words = 0; 
     int numbers = 0; 
     while(!file.eof()) //Goes through whole file until no more entries to input 
      { 
       string word; 
       getline(file,word); //Inputs next element as a string 
//    word << file; 
       //cout << word << '\n'; 
       int x = 0; 
       node *head1 = NULL, *head2 = NULL, *result = NULL; 
       int counter = 0; 
       int t1index = 0; //keep tracks of nodes to multiply 
       int t2index = 0; 
       char operatorX; 
       LinkedList tempList1; 
       LinkedList tempList2; 
       while(x<word.length()) //Loops through each string input 
       { 
        //if(x<word.length()&&isalpha(word.at(x))) //Checks that x is in bounds and that char at position x is a letter 
        if(x<word.length()&&isdigit(word.at(x))) //Checks that x is in bounds and that char at position x is a number/digit 
        { 
         int start = x; 
         while(x<word.length()&&isdigit(word.at(x))) //Loops past the number portion 
         { 
          x++; 
         } 
         string temp = word.substr(start, x).c_str(); 
        // cout << temp << '\n'; 
          for(int i = 0; i < temp.length();i++){ 
          tempList1.addValue(atoi(temp.substr(i, 1).c_str())); 
          // push(&head1, atoi(temp.substr(i, 1).c_str())); 
          counter++; 
          t1index++; 
          } 
          //search for the operator 
          while(x<word.length()){ 
            if(x<word.length()&& (!isspace(word.at(x)) && !isdigit(word.at(x)))) 
            { 
            while(x<word.length()&&(!isspace(word.at(x)) && !isdigit(word.at(x)))) //Loops past the letter portion 
            { 
             // cout << (word.at(x))<< '\n'; 
             operatorX = word.at(x); 
             x++; 
            } 
             //search second value 
             while(x<word.length()){ //second value find 
              //start 
               if(x<word.length()&&isdigit(word.at(x))) //Checks that x is in bounds and that char at position x is a number/digit 
                { 
                 int start = x; 
                 while(x<word.length()&&isdigit(word.at(x))) //Loops past the number portion 
                 { 
                  x++; 
                 } 
                 string temp = word.substr(start, x).c_str(); 

                  for(int i = 0; i < temp.length();i++){ 
                  tempList2.addValue(atoi(temp.substr(i, 1).c_str())); 
                 // push(&head2, atoi(temp.substr(i, 1).c_str())); 
                 //  cout << atoi(temp.substr(i, 1).c_str()); 
                  counter++; 
                  } 
                  //////START READING NUMBERS BACKWARDS 
                  LinkedList finalList; 
                  node* tempA = tempList1.tail; 
                  node* tempB = tempList2.tail; 
                 // multiply(tempA, tempB); 
                    //ADDITION 
                    while(tempA != NULL){ 
                     if(tempA->data != -1){ 
                      push(&head1,tempA->data); 
                     //  cout << tempA->data; 
                     } 
                     tempA = tempA->prev; 

                    } 
                    while(tempB != NULL){ 
                     if(tempB->data != -1){ 
                      push(&head2, tempB->data); 
                    //  cout << tempB->data; 
                     } 
                     tempB = tempB->prev; 

                    } 

                   //   multiply(head1, head2); 
                  //  result = multiply(head1, head2); 


                 //   tempList1.PrintReverse(); 
                  addList(head1, head2, &result); 
                  printList(head1); 
                  cout << operatorX; 
                  printList(head2); 
                  cout << "="; 
                  printList(result); 
                  cout << endl; 

                } 
                else{ 
                 x++; 
                } 
              //end 
             } 
            } 
            else{ 
             x++; 
            } 
            } 
        } 
        else //If char at position x is neither number or letter skip over it 
        { 
         x++; 
        } 
       } 
      } 






} 

回答

2

插入小數點由於你的工作結果在C++中,使用模板/重載運算符。根據需要將您的ints轉換爲浮點類型。請參閱例如: C++ Template problem adding two data types

+0

啊我想我原來的帖子並不清楚。 現在它適用於整數例如。 53020184 + 492881 但我需要它與十進制數以及例如。 53.019283 + 49.2717181 –

+0

不,你已經清楚了 - 它的所有代碼都是顯式類型的int。你需要像'double'來處理十進制數。模板(可以處理多種類型)基本上是C++作爲一種語言的全部存在理由。你的代碼足夠先進,你應該知道/能夠在這一點上做到這一點。 –

+1

Ohh duh!我感到愚蠢,現在感謝 –

相關問題