在一组数字上计算最大公除数和最小公倍数的最简单方法是什么?哪些数学函数可用于查找此信息?
Answers:
我已经使用Euclid算法找到了两个数字的最大公约数。可以迭代以获得更大数量的GCD。
private static long gcd(long a, long b)
{
while (b > 0)
{
long temp = b;
b = a % b; // % is remainder
a = temp;
}
return a;
}
private static long gcd(long[] input)
{
long result = input[0];
for(int i = 1; i < input.length; i++) result = gcd(result, input[i]);
return result;
}
最小公倍数有些棘手,但最好的方法可能是通过GCD进行减少,可以类似地进行迭代:
private static long lcm(long a, long b)
{
return a * (b / gcd(a, b));
}
private static long lcm(long[] input)
{
long result = input[0];
for(int i = 1; i < input.length; i++) result = lcm(result, input[i]);
return result;
}
a * b
首先被评估,则结果临时肯定几乎大于结果,因此更有可能溢出long
。根据定义,gcd(a, b)
将a
和b
均分,因此我们可以在相乘之前进行除法并避免这种情况。如果使用BigInteger
,则采用相同的逻辑,除了避免溢出以外,您通过使数字更小来减少计算开销。
long
是基元而不是类,因此不能有堆分配。像样的运行时会自动重用局部变量空间,就像在循环外声明它一样,甚至在短暂的生存期内将其填充到寄存器中,而不是分配局部变量空间。在循环内声明它(至少对读者而言)也表明,它的值不需要在迭代中保留。
没有内置功能。您可以使用Euclid算法找到两个数字的GCD 。
对于一组数字
GCD(a_1,a_2,a_3,...,a_n) = GCD( GCD(a_1, a_2), a_3, a_4,..., a_n )
递归地应用它。
与LCM相同:
LCM(a,b) = a * b / GCD(a,b)
LCM(a_1,a_2,a_3,...,a_n) = LCM( LCM(a_1, a_2), a_3, a_4,..., a_n )
如果您可以使用Java 8(并且确实愿意),则可以使用lambda表达式从功能上解决此问题:
private static int gcd(int x, int y) {
return (y == 0) ? x : gcd(y, x % y);
}
public static int gcd(int... numbers) {
return Arrays.stream(numbers).reduce(0, (x, y) -> gcd(x, y));
}
public static int lcm(int... numbers) {
return Arrays.stream(numbers).reduce(1, (x, y) -> x * (y / gcd(x, y)));
}
我以Jeffrey Hantin的回答为导向,但是
numbers
-Array的gcd转换为函数语法,该语法更紧凑并且IMO更易于阅读(至少如果您习惯于函数编程)由于额外的函数调用,这种方法可能会稍微慢一些,但是对于大多数用例而言,这可能根本不重要。
int gcf(int a, int b)
{
while (a != b) // while the two numbers are not equal...
{
// ...subtract the smaller one from the larger one
if (a > b) a -= b; // if a is larger than b, subtract b from a
else b -= a; // if b is larger than a, subtract a from b
}
return a; // or return b, a will be equal to b either way
}
int lcm(int a, int b)
{
// the lcm is simply (a * b) divided by the gcf of the two
return (a * b) / gcf(a, b);
}
gcf
。使用%
会使事情变得更快(并使这与其他两个答案没有什么不同)。
使用Java 8,有更多优雅且实用的方法可以解决此问题。
LCM:
private static int lcm(int numberOne, int numberTwo) {
final int bigger = Math.max(numberOne, numberTwo);
final int smaller = Math.min(numberOne, numberTwo);
return IntStream.rangeClosed(1,smaller)
.filter(factor -> (factor * bigger) % smaller == 0)
.map(factor -> Math.abs(factor * bigger))
.findFirst()
.getAsInt();
}
GCD:
private static int gcd(int numberOne, int numberTwo) {
return (numberTwo == 0) ? numberOne : gcd(numberTwo, numberOne % numberTwo);
}
当然,如果一个参数为0,则这两种方法均无效。
public class HcfLcm {
public static void main(String[] args) {
System.out.println("HCF: "+ getHcf(20, 15)); //5
System.out.println("LCM: "+ getLcm2(20, 15)); //60
}
private static Integer getLcm2(int n1, int n2) {
int lcm = Math.max(n1, n2);
// Always true
while (true) {
if (lcm % n1 == 0 && lcm % n2 == 0) {
break;
}
++lcm;
}
return lcm;
}
private static Integer getLcm(int i, int j) {
int hcf = getHcf(i, j);
return hcf * i/hcf * j/hcf; // i*j*hcf
}
private static Integer getHcf(int i, int j) {
while(i%j != 0) {
int temp = i%j;
i = j;
j = temp;
}
return j;
}
}
导入java.util.Scanner; 公共课程Lcmhcf {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Scanner scan = new Scanner(System.in);
int n1,n2,x,y,lcm,hcf;
System.out.println("Enter any 2 numbers....");
n1=scan.nextInt();
n2=scan.nextInt();
x=n1;
y=n2;
do{
if(n1>n2){
n1=n1-n2;
}
else{
n2=n2-n1;
}
} while(n1!=n2);
hcf=n1;
lcm=x*y/hcf;
System.out.println("HCF IS = "+hcf);
System.out.println("LCM IS = "+lcm);
}
}
//## Heading ##By Rajeev Lochan Sen
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n0 = input.nextInt(); // number of intended input.
int [] MyList = new int [n0];
for (int i = 0; i < n0; i++)
MyList[i] = input.nextInt();
//input values stored in an array
int i = 0;
int count = 0;
int gcd = 1; // Initial gcd is 1
int k = 2; // Possible gcd
while (k <= MyList[i] && k <= MyList[i]) {
if (MyList[i] % k == 0 && MyList[i] % k == 0)
gcd = k; // Update gcd
k++;
count++; //checking array for gcd
}
// int i = 0;
MyList [i] = gcd;
for (int e: MyList) {
System.out.println(e);
}
}
}
import java.util.*;
public class lcm {
public static void main(String args[])
{
int lcmresult=1;
System.out.println("Enter the number1: ");
Scanner s=new Scanner(System.in);
int a=s.nextInt();
System.out.println("Enter the number2: ");
int b=s.nextInt();
int max=a>b?a:b;
for(int i=2;i<=max;i++)
{
while(a%i==0||b%i==0)
{
lcmresult=lcmresult*i;
if(a%i==0)
a=a/i;
if(b%i==0)
b=b/i;
if(a==1&&b==1)
break;
}
}
System.out.println("lcm: "+lcmresult);
}
}
int lcm = 1;
int y = 0;
boolean flag = false;
for(int i=2;i<=n;i++){
if(lcm%i!=0){
for(int j=i-1;j>1;j--){
if(i%j==0){
flag =true;
y = j;
break;
}
}
if(flag){
lcm = lcm*i/y;
}
else{
lcm = lcm*i;
}
}
flag = false;
}
在这里,第一个for循环用于获取从“ 2”开始的每个数字。如果语句检查数字(i)是否除以lcm,则跳过该数字。如果没有,那么下一个for循环就是寻找一个no。如果发生这种情况,可以将数字除以(i),我们不需要否。我们只想要它的额外因素。所以在这里,如果该标志为真,则意味着已经存在一些否定因素。以厘米为单位的“ i”。因此我们将这些因子相除,然后将多余的因子乘以lcm。如果该数字不能被其先前的任何数字整除。然后只需将其乘以lcm。