Прямоугольное / решетчатое умножение - PullRequest
5 голосов
/ 23 января 2011

Я пытаюсь реализовать прямоугольное / решетчатое умножение в Java. Для тех, кто не знает, это краткое руководство.

Я пробовал некоторые методы, в которых я использовал один массив для хранения умножения двух цифр и нулей сигма-добавления. После того, как все числа умножены, я выбираю два элемента из массива, а затем добавляю сигма-значение, извлекаю еще два числа и снова выполняю одну и ту же вещь, пока все числа не будут выбраны.

Логика работает нормально, но я не могу найти точное число нулей, которое мне следует поддерживать, поскольку для каждого различного набора чисел (4 цифры * 3 цифры) я получаю различное количество нулей.

Может ли кто-нибудь помочь, пожалуйста?

Ответы [ 2 ]

1 голос
/ 23 января 2011

Мне понравился урок, очень аккуратно. Поэтому я хотел реализовать это, но не делать работу над вашим проектом. Поэтому я придумал паршивую, быструю и грязную реализацию, нарушающую многие правила проектирования, которые я практикую сам. Я использовал массивы для сохранения результатов умножения цифр на цифры и в значительной степени следовал указаниям учебника. Мне никогда не приходилось считать количество нулей, и я не уверен, что является добавлением сигмы, поэтому я не могу ответить на это. Наконец, в коде есть ошибка, которая появляется, когда 2 числа имеют разное количество цифр. Вот исходный код - не стесняйтесь редактировать и использовать любую часть. Я думаю, что простым решением было бы добавить 0 к меньшему числу, чтобы количество цифр было одинаковым для двух чисел, а не отображать соответствующую строку / столбцы. Больше бухгалтерии, но это зависит от вас.

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 голосов
/ 24 января 2011

это работает для любого набора чисел. 2-значный множитель с 4-значным множителем ... и т. Д.

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