Java使用Swing生成一個(gè)最大公約數(shù)計(jì)算器
最終的效果如下圖所示

我來說說核心的步驟。
第一步:利用歐幾里得算法計(jì)算最大公約數(shù)
歐幾里得算法是計(jì)算最大公約數(shù)的經(jīng)典算法。如果我們使用 java 中的 BigInteger,那么從理論上講,可以計(jì)算出任意大小的兩個(gè)整數(shù)的最大公約數(shù)(按照定義,這兩個(gè)整數(shù)不能同時(shí)為0)。

歐幾里得算法的證明
對不同時(shí)為0的兩個(gè)非負(fù)整數(shù)a,b 而言,為了討論的方便,我們假≥b 成立。那么會有如下兩種情形
情形 1:b=0
由于a,b 不同時(shí)為 0 而b=0,那么a>0 成立。a∣a 和a∣b 都成立,且 a的最大因子是 a,所以 gcd(a,b)=a 成立。
情形 2:b>0
假設(shè)gcd(a,b)=g1?,由于g1?∣a 且g1?∣b,那么以下判斷都成立
- g1?∣a
- g1?∣(a−b)
- g1?∣(a−2×b)
- g1?∣(a−3×b)
- ...
- g1?∣(amodb)
由此可見g1?∣b 和 g1?∣(amodb) 都成立,那么g1? 是 b 和(amodb) 的 一個(gè) 公約數(shù)。我們記gcd(b,amodb)=g2?,那么g1?≤g2? 成立(因?yàn)槊總€(gè)公約數(shù)都小于等于 最大公約數(shù))。既然gcd(b,amodb)=g2?,那么g2?∣b 且 g2?∣(amodb),這樣可以推知以下的判斷都成立
- g2?∣(amodb)
- g2?∣(b+(amodb))
- g2?∣(2×b+(amodb))
- g2?∣(3×b+(amodb))
- ...
- g2?∣a
所以 g2? 是 a和 b的 一個(gè) 公約數(shù),那么g2?≤g1? (因?yàn)槊總€(gè)公約數(shù)都小于等于 最大公約數(shù))。注意到以下兩者都成立
- g1?≤g2?
- g2?≤g1?
那么g1?=g2?,也就是說 gcd(a,b)=gcd(b,amodb)。
完成相關(guān)代碼
如果用 Swing 來生成用戶界面的話,用戶的輸入會是 String。我們需要寫點(diǎn)將 String 轉(zhuǎn)化為 BigInteger 的代碼。
有了上述的思路后,可以先把計(jì)算最大公約數(shù)和 String -> BigInteger 轉(zhuǎn)化的代碼寫好
class GCDCalculator {
private BigInteger toBigInteger(String num) {
return new BigInteger(num.trim());
}
public BigInteger calculateGCD(String a, String b) {
return calculateGCD(toBigInteger(a).abs(), toBigInteger(b).abs());
}
public BigInteger calculateGCD(BigInteger a, BigInteger b) {
if (a.equals(BigInteger.ZERO) && b.equals(BigInteger.ZERO)) {
throw new IllegalArgumentException("兩個(gè)整數(shù)不能都是0!");
}
return doCalculateGCD(a, b);
}
private BigInteger doCalculateGCD(BigInteger a, BigInteger b) {
if (b.equals(BigInteger.ZERO)) {
return a;
}
return doCalculateGCD(b, a.mod(b));
}
public static void main(String[] args) {
GCDCalculator gcdCalculator = new GCDCalculator();
System.out.println(gcdCalculator.calculateGCD("100", "20")); // should be 20
System.out.println(gcdCalculator.calculateGCD("10", "12")); // should be 2
System.out.println(gcdCalculator.calculateGCD("233", "144")); // should be 1
System.out.println(gcdCalculator.calculateGCD("12345", "67890")); // should be 15
System.out.println(gcdCalculator.calculateGCD("54321", "9876")); // should be 3
System.out.println(gcdCalculator.calculateGCD("1160718174", "316258250")); // should be 1078
}
}
我在 main 方法里寫了幾個(gè)測試用例,計(jì)算的結(jié)果都符合預(yù)期。
第二步:加入和Swing相關(guān)的代碼
既然計(jì)算最大公約數(shù)的部分已經(jīng)寫好了,那么現(xiàn)在只需要把和 Swing 相關(guān)的代碼也加上,就可以和用戶進(jìn)行交互了。因?yàn)?Swing 的知識點(diǎn)比較零碎,我自己知道得也很粗淺,這一部分就不展開說了。完整的代碼如下
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigInteger;
public class MyGCDCalculator {
public static void main(String[] args) {
EventQueue.invokeLater(new CalcGreatestCommonDivisor());
}
}
class CalcGreatestCommonDivisor implements Runnable {
@Override
public void run() {
SimpleFrame frame = new SimpleFrame("最大公約數(shù)計(jì)算器");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
JPanel northPanel = new JPanel();
northPanel.setLayout(new GridLayout(3, 2));
JTextField textField1 = new JTextField();
northPanel.add(new JLabel("請輸入第一個(gè)整數(shù):", SwingConstants.RIGHT));
northPanel.add(textField1);
northPanel.add(new JLabel("請輸入第二個(gè)整數(shù):", SwingConstants.RIGHT));
JTextField textField2 = new JTextField();
northPanel.add(textField2);
northPanel.add(new JLabel("這兩個(gè)整數(shù)的最大公約數(shù)是:", SwingConstants.RIGHT));
JTextField textField3 = new JTextField();
textField3.setEnabled(false);
northPanel.add(textField3);
frame.add(northPanel, BorderLayout.NORTH);
JButton button = new JButton("計(jì)算最大公約數(shù)");
button.addActionListener(new ActionListener() {
private final GCDCalculator calculator = new GCDCalculator();
@Override
public void actionPerformed(ActionEvent e) {
String a = textField1.getText();
String b = textField2.getText();
try {
BigInteger gcd = calculator.calculateGCD(a, b);
textField3.setText(gcd.toString());
} catch (NumberFormatException exception) {
textField3.setText("Exception found " + exception.getMessage());
} catch (IllegalArgumentException exception) {
textField3.setText(exception.getMessage());
}
}
});
frame.add(button, BorderLayout.SOUTH);
}
}
class SimpleFrame extends JFrame {
public SimpleFrame(String title) {
setTitle(title);
setSize(600, 200);
}
}
class GCDCalculator {
private BigInteger toBigInteger(String num) {
return new BigInteger(num.trim());
}
public BigInteger calculateGCD(String a, String b) {
return calculateGCD(toBigInteger(a).abs(), toBigInteger(b).abs());
}
public BigInteger calculateGCD(BigInteger a, BigInteger b) {
if (a.equals(BigInteger.ZERO) && b.equals(BigInteger.ZERO)) {
throw new IllegalArgumentException("兩個(gè)整數(shù)不能都是0!");
}
return doCalculateGCD(a, b);
}
private BigInteger doCalculateGCD(BigInteger a, BigInteger b) {
if (b.equals(BigInteger.ZERO)) {
return a;
}
return doCalculateGCD(b, a.mod(b));
}
public static void main(String[] args) {
GCDCalculator gcdCalculator = new GCDCalculator();
System.out.println(gcdCalculator.calculateGCD("100", "20")); // should be 20
System.out.println(gcdCalculator.calculateGCD("10", "12")); // should be 2
System.out.println(gcdCalculator.calculateGCD("233", "144")); // should be 1
System.out.println(gcdCalculator.calculateGCD("12345", "67890")); // should be 15
System.out.println(gcdCalculator.calculateGCD("54321", "9876")); // should be 3
System.out.println(gcdCalculator.calculateGCD("1160718174", "316258250")); // should be 1078
}
}
請將以上代碼保存為 MyGCDCalculator.java。使用以下命令可以編譯 MyGCDCalculator.java 并運(yùn)行 MyGCDCalculator 類中的 main 方法。
javac MyGCDCalculator.java java MyGCDCalculator
效果展示
異常情況 1:兩個(gè)整數(shù)都是 0

異常情況 2:輸入的整數(shù)中有不合法字符

正常情況 1:一個(gè)整數(shù)是 0,另一個(gè)是比較小的正整數(shù)

正常情況 2:一個(gè)整數(shù)是負(fù)數(shù),另一個(gè)是正數(shù)(且有顯式的+)

正常情況 3:兩個(gè)比較大的 2 的冪次
這兩個(gè)整數(shù)分別是236和237,它們的最大公約數(shù)是236

正常情況 4:一個(gè)比較大的 2 的冪次,一個(gè)比較大的 3 的冪次
這兩個(gè)整數(shù)分別是250 和340,它們的最大公約數(shù)是1(因?yàn)閮烧邲]有任何共同的質(zhì)因子)

說明
本文所展示的 java 代碼是我自己寫的(Intellij IDEA 會幫忙填充一些內(nèi)容),讀者朋友可以自由修改和使用。
到此這篇關(guān)于Java使用Swing生成一個(gè)最大公約數(shù)計(jì)算器的文章就介紹到這了,更多相關(guān)Java計(jì)算器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring數(shù)據(jù)庫事務(wù)的實(shí)現(xiàn)機(jī)制講解
這篇文章主要介紹了Spring數(shù)據(jù)庫事務(wù)的實(shí)現(xiàn)機(jī)制講解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
JAVA中數(shù)組插入與刪除指定元素的實(shí)例代碼
下面小編就為大家分享一篇JAVA中數(shù)組插入與刪除指定元素的實(shí)例代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02
解決javaBean規(guī)范導(dǎo)致json傳參首字母大寫將永遠(yuǎn)獲取不到問題
這篇文章主要介紹了解決javaBean規(guī)范導(dǎo)致json傳參首字母大寫將永遠(yuǎn)獲取不到問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
springboot jasypt2.x與jasypt3.x的使用方式
在軟件開發(fā)中,將配置文件中的敏感信息(如數(shù)據(jù)庫密碼)進(jìn)行加密是保障安全的有效手段,jasypt框架提供了這一功能,支持通過加密工具類或命令行工具生成密文,并通過修改配置文件和啟動(dòng)參數(shù)的方式使用密文和密鑰,這樣即便配置文件被泄露2024-09-09

