2011-01-23 51 views
5

Tôi đang cố gắng thực hiện phép nhân chữ nhật/lưới trong Java. Đối với những người không biết, this is a short tutorial.Nhân bản hình chữ nhật/mạng

Tôi đã thử một số phương pháp trong đó tôi đã sử dụng một mảng duy nhất để lưu trữ phép nhân của hai chữ số và sigma-append zeroes cho nó. Khi tất cả các số được nhân lên, tôi chọn hai phần tử từ mảng và sau đó thêm giá trị sigma và tìm thêm hai số và thực hiện lại cùng một điều cho đến khi tất cả các số được tìm nạp.

Logic hoạt động tốt nhưng tôi không thể tìm số lượng chính xác số 0 mà tôi nên duy trì, vì đối với mỗi tập hợp số khác nhau (4 chữ số * 3 chữ số), tôi nhận được số lượng số 0 khác nhau.

Ai đó có thể giúp bạn?

Trả lời

1

Tôi thích hướng dẫn, rất gọn gàng. Vì vậy, tôi muốn thực hiện nó, nhưng không làm công việc dự án của bạn. Vì vậy, tôi đã đưa ra một triển khai tệ hại, nhanh chóng và dơ bẩn, vi phạm nhiều quy tắc thiết kế mà tôi thực hành. Tôi đã sử dụng mảng để lưu các chữ số bằng các kết quả nhân chữ số, và khá nhiều theo những gì hướng dẫn nói. Tôi chưa bao giờ phải đếm số lượng 0, và tôi không chắc chắn về việc sigma-appending là gì, vì vậy tôi không thể trả lời điều đó. Cuối cùng, có một lỗi trong mã hiển thị khi 2 số có số đếm chữ số khác nhau. Đây là mã nguồn - hãy chỉnh sửa và sử dụng bất kỳ phần nào. Tôi nghĩ rằng một sửa chữa dễ dàng sẽ là để thêm 0 vào số nhỏ hơn để làm cho chữ số đếm giống nhau cho 2 số, và không hiển thị hàng/cột tương ứng. Lưu giữ sổ sách nhiều hơn, nhưng điều đó tùy thuộc vào bạn.

import java.util.*; 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class Lattice extends JPanel implements ActionListener { 

protected Font axisFont, rectFont, carrFont; 

protected Color boxColor = new Color (25, 143, 103), gridColor = new Color (78, 23, 211), 
     diagColor = new Color (93, 192, 85), fontColor = new Color (23, 187, 98), 
     carrColor = new Color (162, 34, 19); 

protected int nDigitP, nDigitQ, dSize = 60, 
     m1, m2, lastCarry, iResult[], 
     xDigits[], yDigits[], prodTL[][], prodBR[][]; 

public Lattice (int p, int q, Font font) { 
    nDigitP = (int) Math.ceil (Math.log10 (p)); xDigits = new int[nDigitP]; 
    nDigitQ = (int) Math.ceil (Math.log10 (q)); yDigits = new int[nDigitQ]; 

    prodTL = new int[nDigitP][nDigitQ];  prodBR = new int[nDigitP][nDigitQ]; 

    m1 = p; m2 = q;     // To display in report 
    int np = p, nq = q, size = font.getSize(); // Save the digits in array 

    for (int i = 0 ; i < nDigitP ; i++) { 
     xDigits[i] = np % 10; 
     np /= 10; 
    } 
    for (int i = 0 ; i < nDigitQ ; i++) { 
     yDigits[i] = nq % 10; 
     nq /= 10; 
    } 

    for (int i = 0 ; i < nDigitP ; i++) {  // Cell products as upper/lower matrix 
     for (int j = 0 ; j < nDigitQ ; j++) { 
      int prod = xDigits[i] * yDigits[j]; 
      prodTL[i][j] = prod/10; 
      prodBR[i][j] = prod % 10; 
    }} 

    axisFont = font.deriveFont (Font.PLAIN, size+8.0f); 
    rectFont = font.deriveFont (Font.PLAIN, size+4.0f); 
    carrFont = font.deriveFont (Font.PLAIN); 

    setPreferredSize (new Dimension ((nDigitP+2)*dSize, (nDigitQ+2)*dSize)); 
} 

public void paint (Graphics g) { 
    int w = getWidth(), h = getHeight(); 
    Graphics2D g2 = (Graphics2D) g;   // To make diagonal lines smooth 
    g2.setPaint (Color.white); 
    g2.fillRect (0,0,w,h); 

    int dx = (int) Math.round (w/(2.0+nDigitP)), // Grid spacing to position 
     dy = (int) Math.round (h/(2.0+nDigitQ)); // the lines and the digits 

    g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, 
              RenderingHints.VALUE_ANTIALIAS_ON); 
    g2.setRenderingHint (RenderingHints.KEY_INTERPOLATION, 
            RenderingHints.VALUE_INTERPOLATION_BILINEAR); 

    g2.setFont (axisFont); 
    FontMetrics fm = g2.getFontMetrics(); 
    for (int i = 0 ; i < nDigitP ; i++) {  // Grid || Y-axis and labels on axis 
     int px = w - (i+1)*dx; 
     g2.setPaint (gridColor); 
     if (i > 0) 
      g2.drawLine (px, dy, px, h-dy); 
     String str = /*i + */"" + xDigits[i]; 
     int strw = fm.stringWidth (str); 
     g2.setPaint (fontColor); 
     g2.drawString (str, px-dx/2-strw/2, 4*dy/5); 
    } 

    for (int i = 0 ; i < nDigitQ ; i++) {  // Grid || X-axis and labels on axis 
     int py = h - (i+1)*dy; 
     g2.setPaint (gridColor); 
     if (i > 0) 
      g2.drawLine (dx, py, w-dx, py); 
     String str = /*i + */"" + yDigits[i]; 
     int strw = fm.stringWidth (str); 
     g2.setPaint (fontColor); 
     g2.drawString (str, w-dx+2*dx/5-strw/2, py-dy/2+10); 
    } 

    g2.setFont (rectFont); 
    fm = g2.getFontMetrics();   // Upper/Lower traingular product matrix 
    for (int i = 0 ; i < nDigitP ; i++) { 
     for (int j = 0 ; j < nDigitQ ; j++) { 
      int px = w - (i+1)*dx; 
      int py = h - (j+1)*dy; 

      String strT = "" + prodTL[i][j]; 
      int strw = fm.stringWidth (strT); 
      g2.drawString (strT, px-3*dx/4-strw/2, py-3*dy/4+5); 

      String strB = "" + prodBR[i][j]; 
      strw = fm.stringWidth (strB); 
      g2.drawString (strB, px-dx/4-strw/2, py-dy/4+5); 
    }} 

    g2.setFont (axisFont); 
    fm = g2.getFontMetrics(); 
    int carry = 0; 
    Vector cVector = new Vector(), iVector = new Vector(); 
    for (int k = 0 ; k < 2*Math.max (nDigitP, nDigitQ) ; k++) { 
     int dSum = carry, i = k/2, j = k/2; 
     //System.out.println ("k="+k); 
     if ((k % 2) == 0) {    // even k 
      if (k/2 < nDigitP && k/2 < nDigitQ) 
       dSum += prodBR[k/2][k/2]; 
      // go right and top 
      for (int c = 0 ; c < k ; c++) { 
       if (--i < 0) 
        break; 
       if (i < nDigitP && j < nDigitQ) 
        dSum += prodTL[i][j]; 
        //System.out.println (" >> TL (i,j) = (" + i+","+j+")"); 
       if (++j == nDigitQ) 
        break; 
       if (i < nDigitP && j < nDigitQ) 
        dSum += prodBR[i][j]; 
        //System.out.println (" >> BR (i,j) = (" + i+","+j+")"); 
      } 
      // go bottom and left 
      i = k/2; j = k/2; 
      for (int c = 0 ; c < k ; c++) { 
       if (--j < 0) 
        break; 
       if (i < nDigitP && j < nDigitQ) 
        dSum += prodTL[i][j]; 
        //System.out.println (" >> TL (i,j) = (" + i+","+j+")"); 
       if (++i == nDigitP) 
        break; 
       if (i < nDigitP && j < nDigitQ) 
        dSum += prodBR[i][j]; 
        //System.out.println (" >> BR (i,j) = (" + i+","+j+")"); 
     }} else {     // odd k 
      if (k/2 < nDigitP && k/2 < nDigitQ) 
       dSum += prodTL[k/2][k/2]; 
      // go top and right 
      for (int c = 0 ; c < k ; c++) { 
       if (++j == nDigitQ) 
        break; 
       if (i < nDigitP && j < nDigitQ) 
        dSum += prodBR[i][j]; 
        //System.out.println (" >> BR (i,j) = (" + i+","+j+")"); 
       if (--i < 0) 
        break; 
       if (i < nDigitP && j < nDigitQ) 
        dSum += prodTL[i][j]; 
        //System.out.println (" >> TL (i,j) = (" + i+","+j+")"); 
      } 
      i = k/2; j = k/2; 
      // go left and bottom 
      for (int c = 0 ; c < k ; c++) { 
       if (++i == nDigitP) 
        break; 
       if (i < nDigitP && j < nDigitQ) 
        dSum += prodBR[i][j]; 
        //System.out.println (" >> BR (i,j) = (" + i+","+j+")"); 
       if (--j < 0) 
        break; 
       if (i < nDigitP && j < nDigitQ) 
        dSum += prodTL[i][j]; 
        //System.out.println (" >> TL (i,j) = (" + i+","+j+")"); 
     }} 

     int digit = dSum % 10; carry = dSum/10; 
     cVector.addElement (new Integer (carry)); 
     iVector.addElement (new Integer (digit)); 
     String strD = "" + digit; 
     int strw = fm.stringWidth (strD); 
     if (k < nDigitP) { 
      int px = w - (k+1)*dx - 4*dx/5, py = h-dy + fm.getHeight(); 
      g2.drawString (strD, px-strw/2, py); 
     } else { 
      int px = dx - 12, py = h - (k-nDigitP+1)*dy - dy/4; 
      g2.drawString (strD, px-strw/2, py+5); 
    }} // End k-loop 

    g2.setPaint (diagColor); 
    for (int i = 0 ; i < nDigitP ; i++) { 
     int xt = (i+1) * dx, 
      yb = (i+2) * dy; 
     g2.drawLine (xt, dy, 0, yb); 
    } 
    for (int i = 0 ; i < nDigitQ ; i++) { 
     int xb = (i + nDigitP - nDigitQ) * dx, 
      yr = (i+1) * dy; 
     g2.drawLine (w-dx, yr, xb, h); 
    } 

    // System.out.println ("carry Vector has " + cVector.size() + " elements"); 
    g2.setFont (carrFont); 
    g2.setPaint (carrColor); 
    fm = g2.getFontMetrics(); 
    for (int k = 0 ; k < 2*Math.max (nDigitP, nDigitQ) ; k++) { 
     carry = ((Integer) cVector.elementAt (k)).intValue(); 
     lastCarry = carry; // To display 
     if (carry == 0) 
      continue; 
     String strC = "" + carry; 
     int strw = fm.stringWidth (strC), 
      px = w-dx-5-strw/2,   // Const X while going Up 
      py = dy + fm.getHeight();  // Const Y while going Left 
     if (k < (nDigitQ-1)) 
      py = h-(k+3)*dy + dy/5 + fm.getHeight(); 
     else 
      px = w - (k-nDigitQ+2) * dx - dx/2 - strw/2; 
     g2.drawString (strC, px, py); 
    } 

    int n = iVector.size();  // Save the vector content to display later 
    iResult = new int[n]; 
    for (int i = 0 ; i < n ; i++) 
     iResult[i] = ((Integer) iVector.elementAt (n-i-1)).intValue(); 
    g2.setPaint (boxColor);  g2.drawRect (dx, dy, w-2*dx, h-2*dy); 
} 

private void displayResults() { 
    StringBuffer sb = new StringBuffer ("Lattice: " + m1 + " \u00D7 " + m2 + " = " + 
         ((lastCarry == 0) ? "" : (""+lastCarry))); 
    for (int k = 0 ; k < iResult.length ; k++) 
     sb.append ("" + iResult[k]); 
    // System.out.println (sb.toString()); 
    JOptionPane.showMessageDialog (null, sb.toString(), "Lattice Multiplier", 
          JOptionPane.INFORMATION_MESSAGE); 
} 

public JPanel getButtonPanel() { 
    JPanel bp = new JPanel(new GridLayout (1,bNames.length)); 
    for (int i = 0 ; i < bNames.length ; i++) { 
     JButton b = new JButton (bNames[i]); 
     b.addActionListener (this); 
     bp.add (b); 
    } 
    return bp; 
} 

private final static String[] bNames = {"Close", "Result"}; 

public void actionPerformed (ActionEvent e) { 
    String cmd = e.getActionCommand(); 
    if (cmd.equals (bNames[0]))  System.exit (0); 
    else if (cmd.equals (bNames[1])) displayResults(); 
} 

public static void main (String[] args) { 
    JTextField tf1 = new JTextField(), tf2 = new JTextField(); 
    JPanel num2m = new JPanel(new GridBagLayout()); 
    GridBagConstraints gbc = new GridBagConstraints(); 
    gbc.insets = new Insets (2,2,2,2); 

    gbc.fill = GridBagConstraints.HORIZONTAL; 
    gbc.gridx = 0; 
    gbc.gridy = GridBagConstraints.RELATIVE; 
    gbc.anchor = GridBagConstraints.EAST; 

    JLabel 
    label = new JLabel ("Multiplicand", JLabel.TRAILING); num2m.add (label, gbc); 
    label = new JLabel ("Multiplier", JLabel.TRAILING); num2m.add (label, gbc); 
    gbc.gridx++; 
    gbc.weightx = 1.0f;  num2m.add (tf1, gbc); num2m.add (tf2, gbc); 

    JFrame lf = new JFrame ("Lattice Multiplication"); 
    if (JOptionPane.showConfirmDialog (lf, num2m, "Enter numbers to multiply", 
       JOptionPane.OK_CANCEL_OPTION, 
       JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { 
     try { 
      int m = Integer.parseInt (tf1.getText()), n = Integer.parseInt (tf2.getText()); 
      Lattice lattice = new Lattice (m, n, label.getFont()); 
      lf.add (lattice.getButtonPanel(), "South"); 
      lf.add (lattice, "Center"); 
      lf.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
      lf.pack(); 
      lf.setVisible (true); 
     } catch (NumberFormatException nex) { 
      JOptionPane.showMessageDialog (lf, "Invalid numbers to multiply", 
        "Lattice Multiplier Error", JOptionPane.ERROR_MESSAGE); 
      System.exit (1); 
    }} else { System.exit (2); 
}}} 
+0

cảm ơn bạn tham gia các nỗ lực đã giúp tôi ra ... tôi thích câu này của bạn "prepend 0 của số nhỏ hơn để làm cho chữ số đếm giống nhau cho 2 số" ... tôi không chắc chắn nếu những gì tôi đã mã hóa là tương tự như của bạn .. nhưng xin vui lòng có một cái nhìn .. –

+0

Có, Tôi nghĩ bạn đã làm một cái gì đó tương tự. Sự khác biệt là tôi đã không làm điều 0-prepend và bạn đã không đặt bất cứ điều gì trong đồ họa. Trên cái nhìn đầu tiên, (1) Tôi nghĩ rằng bạn cần phải gán cho kết quả .. int mới [2 * Math.max (numberM, numberN)], hoặc bạn sẽ chạy vào ArrayIndexOutOfBoundsException trong khi nhân các chữ số, và (2) Khi bạn đảo ngược các số trong n [] và m [], kích thước của một trong các araays có thể đã thay đổi (sử dụng max, một lần nữa). Bây giờ, nếu bạn muốn tôi để tìm ra nơi logic là đi sai, xin vui lòng gửi mã mà tôi có thể sao chép/dán/biên dịch/chạy. Cảm ơn, - M.S. –

0

làm việc này cho bất kỳ bộ numbers..2 chữ số bị nhơn với 4 chữ số multiplier..etc ..

if(numberM.length()!=numberN.length()){ 
      int mLen = numberM.length(); 
      int nLen = numberN.length(); 

      if(numberM.length()>numberN.length()){ 
       for(int i=0;i<mLen-nLen;i++){ 
        numberN = "0" + numberN; 
       } 
      } 
      else 
      { 
       for(int i=0;i<nLen-mLen;i++){ 
        numberM = "0" + numberM; 
       } 

      } 

     } 



int result[] = new int[numberN.length()+numberM.length()]; 

     String numberRN = new StringBuffer(numberN).reverse().toString(); 
     String numberRM = new StringBuffer(numberM).reverse().toString(); 

     //reversing the number 
     int n[] = new int[numberN.length()]; 
     int m[] = new int[numberM.length()]; 
     int size_of_array = 0; 
     for(int i=0;i<numberN.length();i++){ 
      n[i] = Integer.parseInt((new Character(numberRN.charAt(i))).toString()); 
      m[i] = Integer.parseInt((new Character(numberRM.charAt(i))).toString()); 

     } 
     //System.out.println("Numbers are:"); 
     //displayArray(n,"n"); 
     //displayArray(m,"m"); 
     size_of_array = (m.length*2)*2; 
     int soa = size_of_array; 
     int tempArray[] = new int[size_of_array*m.length]; 
     //System.out.println("Size of tempArray ="+tempArray.length); 

     //placing the numbers in a single array 
     int oddValue =3; 
     int index = 0; 
     tempArray[index++] = 0; 
     for(int i=0;i<m.length;i++){ 
      for(int j=0;j<n.length;j++){ 
       //System.out.println("n["+j+"]="+n[j]+" and m["+i+"]="+m[i]); 
       tempArray[index++] = (n[j] * m[i]) % 10; 
       tempArray[index] = (n[j] * m[i])/10; 
       //System.out.println("tempArray["+(index-1)+"]="+tempArray[index-1]+" tempArray["+(index)+"]="+tempArray[index]); 
       index++; 
      } 
      //System.out.println("index before appending zero="+index); 
      size_of_array=(i+1)*soa; 
      index = size_of_array; 

      //System.out.println("index after appending zero="+index); 
      //index+=i+oddArray[i]; 
      index+=i+oddValue; 
      oddValue++; 
      //System.out.println("After move index="+index); 

     } 
     //System.out.println("tempArray full"); 
     //displayArray(tempArray,"tempArray"); 

     //adding the numbers and also dealing with carry 
     int count=0;int ind = 0;int res = 0;int carry =0;int tempInd = 0; 
     for(int i=0;i<m.length*2;i++){ 
      tempInd = ind; 
      for(int k=0;k<m.length;k++){ 
       //System.out.println(tempArray[ind]+"---"+tempArray[ind+1]); 
       res = tempArray[ind] + tempArray[ind+1] + res + carry; 

       ind = ind + soa ; 
       carry = 0; 
       //System.out.println("res="+res+" ind="+ind+" soa="+soa); 
      } 
      //System.out.println("----------------"); 
      result[count++] = res %10; 
      carry = res /10; 
      res = 0; 
      ind = tempInd+2; 

     } 

     //displayArray(result,"result"); 
     displayResult(result,sign); 

    } 
    private static void displayResult(int[] result,String sign) { 
     System.out.print("The result is "+sign); 
     for(int i=result.length-1;i>=0;i--){ 
      System.out.print(result[i]); 
     } 

    } 
    static void displayArray(int tempArray[],String name){ 
     for(int k =0;k<tempArray.length;k++) 
      System.out.print(" "+name+"["+k+"]-"+tempArray[k]); 
     System.out.println(""); 
    } 
Các vấn đề liên quan