2014-09-04 157 views
0

所以我們的目標是讀取兩個大整數並將它們加在一起,將它們一起減去並乘以一個40個元素的長整數數組,同時還比較初始兩個整數equalTo,notEqualTo等。其中大部分完成,但我堅持了幾點。我的isGreaterThan方法返回與它應該相反的結果,例如:大整數1 = 100和大整數2 = -100。該方法會吐出假,並說巨大的整數1 isLessThan巨大的整數2.下一部分我堅持的是乘法。到目前爲止,我可以將整數相乘,得到一個不超過11​​個元素的新整數。對我來說一些未知的原因,任何更大的將導致錯誤計算。有人建議我多次循環,但我不明白這會有什麼幫助。我的最後一個問題是任何操作的結果等於零,例如100 +(-100),我的add/substract/multiply方法不會返回0.下面是我當前的代碼。數組比較和乘法

import java.util.Scanner; 
import java.util.Arrays; 

// Class that prompts the user to enter two HugeIntegers 
// then compares those integers and performs addition, subtraction, 
// and multiplication on those two HugeIntegers 
public class HugeInteger { 
    private static final int NUM_DIGITS = 40; 
    private int digits[] = new int[NUM_DIGITS]; 
    private boolean positive; 

    // Constructor 
    public HugeInteger (String num){ 
     String parts [] = num.split(" "); 
     digits = new int[parts.length]; 
     for(int n = 0; n < parts.length; n++) { 
      digits[n] = Integer.parseInt(parts[n]); 
     } 
    } 

    // Finds first non-zero position for first HugeInteger 
    public int findFirstNonZeroPosition(){ 
     int position = NUM_DIGITS-1; 
     for (int i = 0; i < digits.length; i++){ 
      if (digits[i] > 0){ 
       position = i; 
       break; 
      } 
     } 
     return position; 
    } 

    // Determines if h1 isEqualTo h2 
    public boolean isEqualTo(HugeInteger hi){ 
     if(Arrays.equals(this.digits, hi.digits)){ 
      return true; 
     }else { 
      return false; 
     } 
    } 

    // Determines if hi isGreaterThan h2 
    public boolean isGreaterThan(HugeInteger hi){ 
     // different signs 
     if (this.positive && (!hi.positive)){ 
      return true; 
     } 
     else if (!this.positive && hi.positive){ 
      return false; 
     } 

     // same sign 
     else { 

      // first number’s length is less than second number’s length 
      if (findFirstNonZeroPosition() > hi.findFirstNonZeroPosition()) { 
       if (positive) 
        return false; 
       else 
        return true; 
      } 

      // first number’s length is larger than that of second number 
      else if (findFirstNonZeroPosition() < hi.findFirstNonZeroPosition()) { 
       if (positive) 
        return true; 
       else 
        return false; 
      } 

      // two numbers have same length 
      else { 
       for (int i = 0; i < digits.length; i++) { 
        if (this.digits[i] > hi.digits[i]) 
         if (positive) 
          return true; 
         else 
          return false; 
       } 
       if (positive) 
        return false; 
       else 
        return true; 
      } 
     } 
    } 

    // Determines if h1 isNotEqualTo h2 
    public boolean isNotEqualTo(HugeInteger hi){ 
     if(Arrays.equals(this.digits, hi.digits)){ 
      return false; 
     }else { 
      return true; 
     } 
    } 

    // Determines if h1 isLessThan h2 
    public boolean isLessThan(HugeInteger hi){ 
     return !(isGreaterThan(hi) || isEqualTo(hi)); 
    } 

    // Determines if h1 isGreaterThanOrEqualTo h2 
    public boolean isGreaterThanOrEqualTo(HugeInteger hi){ 
     return !isLessThan(hi); 
    } 

    // Determines if h1 isLessThanOrEqualTo h2 
    public boolean isLessThanOrEqualTo(HugeInteger hi){ 
     return !isGreaterThan(hi); 
    } 

    // instance variables are digits, NUM_DIGITS, positive 
    // addArrayDigits and subtractArrayDigits 
    // Determines how to add h1 and h2 
    public void add(HugeInteger hi){ 
     if(positive!=hi.positive){ 
      if(this.positive){ 
       // "this" is positive, hi is negative 
       hi.negate(); // negate hi temporarily 

       if(this.isGreaterThan(hi)){ 
        // |this| > |hi| 
        this.digits = subtractArrayDigits(this.digits, hi.digits); 
       }else{ 
        // |this| <= |hi| 
        this.digits = subtractArrayDigits(hi.digits, this.digits); 
        // negate the "this" 
        negate(); 
       } 
       hi.negate(); // restore hi's sign 
      }else{ 
       // "this" is negative, hi is positive 

      } 
     }else{ 
      // same sign :) 
      digits = addArrayDigits(this.digits, hi.digits); 
     } 
    } 

    // instance variables are digits, NUM_DIGITS, positive 
    // addArrayDigits and subtractArrayDigits 
    // Determines how to subtract h1 and h2 
    public void subtract(HugeInteger hi){ 
     if(positive!=hi.positive){ 
      if(this.positive){ 
       // "this" is positive, hi is negative 
       hi.negate(); // negate hi temporarily 

       if(this.isGreaterThan(hi)){ 
        // |this| > |hi| 
        this.digits = addArrayDigits(this.digits, hi.digits); 
       }else{ 
        // |this| <= |hi| 
        this.digits = addArrayDigits(hi.digits, this.digits); 
        // negate the "this" 
        negate(); 
       } 
       hi.negate(); // restore hi's sign 
      }else{ 
       // "this" is negative, hi is positive 
      } 
     }else{ 
      // same sign :) 
      digits = subtractArrayDigits(this.digits, hi.digits); 
     } 
    } 

    // Multiplies h1 and h2 
    public void multiply(HugeInteger hi){ 
     for (int i = 0; i < digits.length; ++i) { 
      digits[i] = this.digits[i] * hi.digits[i]; 
     } 
    } 

    // Flips the sign 
    public void negate(){ 
     positive =! positive; 
    } 

    // Determines if an element is zero 
    public boolean isZero(){ 
     for(int i = 0; i < digits.length; i++) 
     if(digits[i]!= 0) 
      return false; 
     return true; 
    } 

    // Puts HugeInteger into a String in LSD format 
    public String toString() { 
     String str = ""; 
     int i; 
     for(i = digits.length -1; i >= 0; i--) { 
      if(digits[i] != 0) 
      break; 
     } 
     for(int j = i; j >= 0; j--) { 
      str = digits[j] + str; 
     } 
     return str; 
    } 

    // Subtracts h2 from h1 
    private static int[] subtractArrayDigits(int[] array1, int[] array2){ 
     for (int i = 0; i < array1.length; ++i) { 
      array1[i] = array1[i] - array2[i]; 
     } 
     return array1; 
    } 

    // Adds h2 to h1 
    private static int[] addArrayDigits(int[] array1, int[] array2){ 
     //int i = 0; 
     for (int i = 0; i < array1.length; ++i) { 
      array1[i] = array1[i] + array2[i]; 
     } 
     return array1; 
    } 

    // Main method 
    public static void main(String args[]){ 
     HugeInteger h1, h2; 
     String num; 
     Scanner scan=new Scanner(System.in); 

     System.out.print("Please enter the first huge integer (h1): "); 
     num=scan.nextLine(); 
     h1=new HugeInteger(num); 

     System.out.print("Please enter the second huge integer (h2): "); 
     num=scan.nextLine(); 
     h2=new HugeInteger(num); 

     if(h1.isEqualTo(h2)){ 
      System.out.println("h1 is equal to h2."); 
     } 
     if(h1.isNotEqualTo(h2)){ 
      System.out.println("h1 is not equal to h2."); 
     } 
     if(h1.isGreaterThan(h2)){ 
      System.out.println("h1 is greater than h2."); 
     } 
     if(h1.isLessThan(h2)){ 
      System.out.println("h1 is less than to h2."); 
     } 
     if(h1.isGreaterThanOrEqualTo(h2)){ 
      System.out.println("h1 is greater than or equal to h2."); 
     } 
     if(h1.isLessThanOrEqualTo(h2)){ 
      System.out.println("h1 is less than or equal to h2."); 
     } 

     h1.add(h2); 
     System.out.printf("h1 + h2 = %s\n",h1); 
     h1.subtract(h2); 
     h1.subtract(h2); 
     System.out.printf("h1 - h2 = %s\n",h1); 
     h1.add(h2); 
     h1.multiply(h2); 
     System.out.printf("h1 * h2 = %s\n",h1); 
    } 
} 

回答

1

您的代碼有很多問題。

首先,它代表巨大值的內部形式沒有記錄(除了通過代碼分析)並且看起來不一致。它似乎是某種形式的符號/數量,這很好,但數字出現的順序是什麼?這實際上非常重要。

對於大多數目的而言,數字數組從最低位運行到最高位將會更簡單,最低位數字位於索引零,但這與編寫數字的方式相反(至少在英文語言環境)。它也可以運行從最重要到最不重要,但在這種情況下,最低有效位數的唯一合理索引是MAX_DIGITS - 1。在你的構造函數中,我認爲你的數字是從最高位到最低位數字,最低位數字位於數組中間的某個隨機點。不過,我認爲你的意思是要做到這一點。

其次,您的構造函數從不設置positive字段。 (事實上​​,它根本不檢查負數字)。

三,您的add()subtract()方法不應該修改他們的論點,即使是暫時的。這是非常糟糕的形式,沒有必要,除非修改是方法目的的一部分。

四,對於某些符號組合,您的add()subtract()方法什麼也不做。

但是你真的很感興趣,爲什麼你的算術方法產生錯誤的結果。讓我從這裏開始說,除非你知道哪個數字是每個Huge的最不重要,否則絕對不能正確算術。至於你的實際算法,你應該基本上實現你用來在紙上做十進制算術的相同程序。非常重要的是,在必要的情況下,你不能忽視從一個數字位置到下一個數字位置(或者在減去的情況下從更重要的位置借用)。你的代碼不會那樣做。

還要注意,您的算術結果可能有不同於任一操作數的非零數字。特別是,通過一個Ñ位數字號碼的 - 數位數目的乘法可以產生高達一個(Ñ) - 數位數目。增加可能需要一個額外的數字。當然,減法可以減少重要的非零數字的數量。

+0

我加了positive = true;到構造函數,我所有的比較邏輯都工作得很好。唯一不起作用的是大整數的乘法,並得到等於零的操作的結果以顯示零。我認爲這是錯誤的,因爲,您如何指出,我的操作數可能位於數組中間的某個位置。如果我有這樣的錯誤,我該如何去對齊LSD到陣列的右側? – 2014-09-04 23:42:49

+0

由於你的算法似乎假定LSD在索引零,我建議你離開它。當你給數字賦值時,使用'digits [n] = Integer.parseInt(parts [part.length - n - 1])''。 – 2014-09-05 15:15:07

+0

如果您的算法似乎現在正在工作,那麼很可能是因爲您測試的數字與int可容納的值範圍相比較小。嘗試添加2000000000和2000000000這兩個單數(大數)數字。'multiply()'方法更糟糕:即使在考慮數字值之前,當任一操作數具有多個(巨大)數字時,它也會失敗。嘗試乘以1(== 2147483649十進制)乘以2 - 甚至減去1. – 2014-09-05 15:25:54