这是扩展欧几里德算法的实现:
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.math.*;
import javax.swing.*;
public class euclid extends JFrame implements ActionListener
{
public static JPanel p1 = new JPanel ();
public static JTextField t1 = new JTextField (20);
public static JTextField t2 = new JTextField (20);
public static JButton OK = new JButton ("OK");
public static JFrame result = new JFrame ("Results of Division");
public static JPanel pResult = new JPanel ();
public static JTextArea area = new JTextArea (24, 80);
public euclid()
{
result.setContentPane (pResult);
result.setSize (Toolkit.getDefaultToolkit().getScreenSize());
pResult.add (area);
OK.addActionListener (this);
setSize (250, 250);
setContentPane (p1);
p1.add (new JLabel ("a"));
p1.add (t1);
p1.add (new JLabel ("b"));
p1.add (t2);
p1.add (OK);
setVisible (true);
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource () == OK)
{
int i = 2;
BigInteger a = new BigInteger (t1.getText ());
BigInteger b = new BigInteger (t2.getText ());
if (a.compareTo (b) == -1)
{
BigInteger temp = new BigInteger (b.toString ());
b = a;
a = temp;
}
if (b.compareTo (BigInteger.ZERO) == -1)
{
b = b.abs ();
}
LinkedList<BigInteger> quotients = new LinkedList<BigInteger> ();
LinkedList<BigInteger> remainders = new LinkedList<BigInteger> ();
LinkedList<BigInteger> x = new LinkedList<BigInteger> ();
LinkedList<BigInteger> y = new LinkedList<BigInteger> ();
quotients.add (BigInteger.ZERO);
quotients.add (BigInteger.ZERO);
remainders.add (a);
remainders.add (b);
x.add (BigInteger.ONE);
x.add (BigInteger.ZERO);
y.add (BigInteger.ZERO);
y.add (BigInteger.ONE);
try
{
while (remainders.get (i - 2).compareTo (BigInteger.ZERO) == 1)
{
area.append (quotients.get (i - 2) + "\t" + remainders.get (i - 2) + "\t" + x.get (i - 2) + "\t" + y.get (i - 2) + "\n");
quotients.add (remainders.get (i - 2).divide (remainders.get (i - 1)));
remainders.add (remainders.get (i - 2).remainder (remainders.get (i - 1)));
x.add (x.get (i - 2).subtract (quotients.get (i).multiply (x.get (i - 1))));
y.add (y.get (i - 2).subtract (quotients.get (i).multiply (y.get (i - 1))));
i++;
}
}
catch (Throwable t)
{
t.printStackTrace ();
}
finally
{
result.setVisible (true);
}
JOptionPane.showMessageDialog (null, "gcd (" + a + ", " + b + ") = " + remainders.get (i - 1)
+ "\nFor the Linear Diophantine Equation ax + by = gcd (a, b), x = " + x.get (i - 1) + " and y = " +
y.get (i + 1));
}
}
public static void main (String args[])
{
new euclid ();
}
}
这段代码本身“有效”,但它会抛出一些奇怪的异常(即我放置finally
块,以便尽管该程序可能抛出任何异常或错误,仍然可以显示数据。
有没有办法摆脱这些例外?我不知道怎么做。
注意:这不是作业问题。我的学校不会将Java用于一年级学生。这是解决代数课程中问题的工具。
java.lang.ArithmeticException: BigInteger divide by zero
at java.math.MutableBigInteger.divide(MutableBigInteger.java:883)
at java.math.BigInteger.divide(BigInteger.java:1342)
at euclid.actionPerformed(euclid.java:64)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener$Actions.actionPerformed(BasicButtonListener.java:303)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1664)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2878)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2925)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2841)
at java.awt.Component.processEvent(Component.java:6282)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:762)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1027)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:899)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:727)
at java.awt.Component.dispatchEventImpl(Component.java:4731)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 6, Size: 5
at java.util.LinkedList.checkElementIndex(LinkedList.java:553)
at java.util.LinkedList.get(LinkedList.java:474)
at euclid.actionPerformed(euclid.java:80)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener$Actions.actionPerformed(BasicButtonListener.java:303)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1664)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2878)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2925)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2841)
at java.awt.Component.processEvent(Component.java:6282)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:762)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1027)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:899)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:727)
at java.awt.Component.dispatchEventImpl(Component.java:4731)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
答案 0 :(得分:0)
在actionPerformed
方法的某处,您将BigInteger除以零,这在数学上是未定义的(因此实现会抛出异常)。我的猜测在这里:
quotients.add (remainders.get (i - 2).divide (remainders.get (i - 1)));
因此remainders.get (i - 1)
是BigInteger,其值为零。
虽然这可能代表了代码中的一个更深层次的问题,但这里有一个快速修复来防止异常并帮助您调试:
BigInteger denominator = remainders.get (i - 1);
if (denominator.equals(BigInteger.ZERO)
{
//show error message w/ System.out or JOptionPane
}
else
{
quotients.add (remainders.get (i - 2).divide (denominator));
}
答案 1 :(得分:0)
根据http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm我想循环条件应改为:
while (remainders.get (i - 1).compareTo (BigInteger.ZERO) == 1)
因为在循环开始时,remainingders.get(i - 1)指的是最后计算的余数,而不是remainingders.get(i - 2)。