2011-01-23 17 views
5

Estoy tratando de implementar la multiplicación rectangular/reticular en Java. Para aquellos que no saben, this is a short tutorial.Rectángulo/multiplicación de celosía

Intenté algunos métodos en los que utilicé una sola matriz para almacenar la multiplicación de dos dígitos y sigma-añadirle ceros. Una vez que todos los números se multiplican, selecciono dos elementos de la matriz y luego agrego el valor de sigma y obtengo dos números más y nuevamente realizo la misma operación hasta que se hayan obtenido todos los números.

La lógica funciona bien, pero no puedo encontrar el número exacto de ceros que debo mantener, ya que para cada conjunto diferente de números (4 dígitos * 3 dígitos) obtengo un número diferente de ceros.

¿Podría alguien ayudarme?

Respuesta

1

Me gustó el tutorial, muy limpio. Entonces quería implementarlo, pero no hacer su trabajo de proyecto. Así que se me ocurrió una implementación pésima, rápida y sucia, violando muchas de las reglas de diseño que practico. Usé matrices para guardar los resultados de multiplicación de dígito por dígito, y prácticamente seguí lo que decía el tutorial. Nunca tuve que contar la cantidad de 0, y no estoy seguro de qué es sigma, así que no puedo responderlo. Por último, hay un error en el código que aparece cuando los 2 números tienen un conteo de dígitos diferente. Aquí está el código fuente: siéntete libre de editar y usar cualquier parte. Creo que una solución fácil sería anteponer 0 al número menor para que el dígito cuente lo mismo para los 2 números, y no para mostrar la fila/columnas correspondientes. Más contabilidad, pero eso depende de usted.

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

agradecimiento tomando el esfuerzo por ayudarme ... Me gustó esta frase de los suyos "anteponga 0's al número más pequeño para hacer que el dígito cuente igual para los 2 números" ... no estoy seguro si lo que he codificado es similar al suyo ... pero por favor eche un vistazo .. –

+0

Sí, Creo que has hecho algo similar. Las diferencias se deben a que no hice el preajuste 0 y no has puesto nada en los gráficos. Al primer vistazo, (1) creo que debe asignar el resultado ... nuevo int [2 * Math.max (númeroM, númeroN)], o se encontrará con ArrayIndexOutOfBoundsException mientras multiplica los dígitos, y (2) Cuando invierta los números en n [] y m [], el tamaño de uno de los araays podría haber cambiado ya (use el máximo, nuevamente). Ahora, si quieres que descubra dónde está yendo la lógica, envía un código que pueda copiar/pegar/compilar/ejecutar. Gracias, - M.S. –

0

esto funciona para cualquier conjunto de dígitos multiplicando numbers..2 con multiplier..etc 4 dígitos ..

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(""); 
    } 
Cuestiones relacionadas