查找给定整数的因子
我有这样的事情:
int f = 120; for(int ff = 1; ff <= f; ff++){ while (f % ff != 0){ }
我的循环找到因素有什么问题吗? 我对for和while语句的工作方式感到困惑,所以很可能它们完全错了。
在此之后,我将如何为所述因素分配变量?
public class Solution { public ArrayList allFactors(int a) { int upperlimit = (int)(Math.sqrt(a)); ArrayList factors = new ArrayList (); for(int i=1;i <= upperlimit; i+= 1){ if(a%i == 0){ factors.add(i); if(i != a/i){ factors.add(a/i); } } } Collections.sort(factors); return factors; } }
上述解决方案就像计算素因子一样。 不同的是每个素数因子我们一直在计算产品的其他部分,即reqd数。
以下是如何获得给定数字的所有因子。
public class Factors { public static void main(String[] args){ int n = 420; for(int i=2; i<=n; i++){ while(n%i==0){ System.out.println(i + "| " + n); System.out.println(" -----"); n = n/i; } } } }
输出:
2| 420 ----- 2| 210 ----- 3| 105 ----- 5| 35 ----- 7| 7 -----
以下代码将返回给定数字的所有因子的列表:
public ArrayList findFactors(int num) { ArrayList factors = new ArrayList (); // Skip two if the number is odd int incrementer = num % 2 == 0 ? 1 : 2; for (int i = 1; i <= Math.sqrt(num); i += incrementer) { // If there is no remainder, then the number is a factor. if (num % i == 0) { factors.add(i); // Skip duplicates if (i != num / i) { factors.add(num / i); } } } // Sort the list of factors Collections.sort(factors); return factors; }
这个答案以两种方式改善了Sharad Dargan的答案 :
-
根据本答案中使用的想法,您可以根据数字是偶数还是奇数来确定要递增的值,以加快解决方案的速度。
在for循环之前添加以下代码行:
int incrementer = num % 2 == 0 ? 1 : 2;
然后将循环的最后一部分更改为:
i += incrementer
如果数字是奇数,那么它将跳过所有偶数,而不是总是递增1,无论如何。
-
Sharad将上限值存储在变量中,然后在for循环中使用该变量:
int upperlimit = (int)(Math.sqrt(a)); ... for(int i = 1; i <= upperlimit; i+= 1)
而是将
Math.sqrt(num)
直接放在for循环中并跳过上限变量:for (int i = 1; i <= Math.sqrt(num); i += incrementer) {
这将允许您跳过代码的转换部分,创建更清晰的代码。
然后可以使用一些JUnit测试用例:
@Test public void test12() { FindFactors find = new FindFactors(); int num = 12; List factors = Arrays.asList(1, 2, 3, 4, 6, 12); assertEquals(factors, find.findFactors(num)); } @Test public void test1000000() { FindFactors find = new FindFactors(); int num = 1000000; List factors = Arrays.asList(1, 2, 4, 5, 8, 10, 16, 20, 25, 32, 40, 50, 64, 80, 100, 125, 160, 200, 250, 320, 400, 500, 625, 800, 1000, 1250, 1600, 2000, 2500, 3125, 4000, 5000, 6250, 8000, 10000, 12500, 15625, 20000, 25000, 31250, 40000, 50000, 62500, 100000, 125000, 200000, 250000, 500000, 1000000); assertEquals(factors, find.findFactors(num)); } @Test public void test1() { FindFactors find = new FindFactors(); int num = 1; List factors = Arrays.asList(1); assertEquals(factors, find.findFactors(num)); } @Test public void test0() { FindFactors find = new FindFactors(); int num = 0; List factors = new ArrayList (); assertEquals(factors, find.findFactors(num)); }
为了找到给定数字的因子,您只需要检查给定数字的平方根。
例如,为了找到6的因子,你只需要检查到2.45(√6)。 因子6将是1和2,以及它们的相反数字,即3和6。
我制作了一个程序来确定给定数字的因子并显示它们。 这是必要的代码:
Scanner input = new Scanner(System.in); System.out.print("Enter integer: "); long num = input.nextLong(); for(long i = 1; i <= Math.sqrt(num); i++) { if(num % i == 0) { System.out.println(i); if(i != num/i) { System.out.println(num/i); } } }
您只需要此程序即可找到给定数字的因子。 但是,如果您想更进一步并显示按升序排列的因子,则必要的代码如下:
Scanner input = new Scanner(System.in); System.out.print("Enter integer: "); long num = input.nextLong(); ArrayList list1 = new ArrayList<>(), list2 = new ArrayList<>(); long currentTime = System.currentTimeMillis(); for(long i = 1; i <= Math.sqrt(num); i++) { if(num % i == 0) { list1.add(i); if(i != num/i) { list2.add(num/i); } } } int n1 = list1.size() - 1; int n2 = list2.size() - 1; for(int i = 0; i <= n1; i++) { System.out.println(list1.get(i)); } for(int i = n2; i >= 0; i--) { System.out.println(list2.get(i)); }
这样做:该程序将数字的因子存储在一个列表(list1)中的数字的平方根,并将这些数字的反转存储在另一个列表(list2)中。 然后打印两个列表的元素(如图所示)。
你的for
循环没有任何问题,但是while
这里使用while
循环是错误的。 你的for
循环的逻辑是:
- 将
ff
设置为1。 - 在
ff <= f
继续前进。 - 在
for
循环中完成所有操作后,将1添加到ff
。
这看起来就像你想要的那样。
但是, while
循环是不对的。 只要ff
是f
的因子,它将继续执行你在那里编写的任何代码,所以除非你在while
代码中更改它们,否则你将获得无限循环。 但是,将其更改为if
语句将为您提供所需的内容。
由于您正在检查因子,因此实际上您不需要检查最多f的所有可能性 - 仅高达f的平方根。 每当你发现ff
是一个因子时,输出ff
和f/ff
作为因子,除非f
是sqare数。
这就是你像老板一样自己写的。 需要添加if语句来处理一个和两个,但除此之外; 这种方法既性感又好看
public static void primerize(int n){ boolean reduced = false; while(n > 2){ if(n%2 == 0){ System.out.println(2 + "," + n/2); n /= 2; } else{ int i = isPrime(n); if(i == n && reduced == false){ System.out.println(1 + "," + n); n /= n; } else if(i == n){ n/= n; } else{ System.out.println(i + "," + n/i); n = i; reduced = true; } } }} public static int isPrime(int n){ for(int i = (n/3); i > 0; i--){ if(i == 1){ return n; } else if(n%i == 0){ return i; } } return 0;}
看起来你不会在你的while循环中用f
或ff
做某事吗? 如果是这样,表达式f%ff != 0
要么为假(然后它将转到for循环中的下一个),要么为真,它将以无限循环结束。
你确定你需要这样的时间吗?
稍微修改过的解决方案:您可以先检查变量x是否可被变量y整除。 如果是,我们将计算1并将重复此过程。 对于循环计数器,使用x / y,你应检查x> 0,以避免在x变为零但循环尚未完成时重复。
public class Factor { public static void main(String[] args) { int x = 48; int x1 = x; int y = 2; int k = x / y; int j = 0; for (int i = 1; i < k; i++) { if ((x % y) == 0 && x > 0) j++; x = x / 2; } System.out.println(+x1 + " is a factor of " + y + " for " + j + " times."); } }
我得到了所有这些因素(我刚刚在问题中修改了算法)。
int num1 = 120; for(int num2=1;num2<=num1;num2++) { if (num1%num2 != 0) System.out.println(num2); }
import java.util.Scanner; public class Factors { Scanner scn=new Scanner(System.in); int num=scn.nextInt(); public void findFactor() { System.out.println("Factors are"); System.out.println("1"); for(int i=2;i<=num;i++) { if(num%i==0) { num=num/i; System.out.println(i); i=2; } } } public static void main(String[] args) { while(1==1) { System.out.println("Enter a Number"); Factors fct=new Factors(); fct.findFactor(); } }
}
利用Java 8中引入的Streams,下面将打印给定数字的因子。
int input = 1500; IntStream.rangeClosed(1, input) .filter(e -> input % e == 0) .forEach(System.out::println);
此代码将为您提供因素。
ArrayList arr = new ArrayList<>(); int x=48; int y=1; while(x!=1) { if(x%y==0) { x=x/y; arr.add(y); if(y==1) { y++; } } else { y+=1; } } System.out.println(arr);
使用递归函数的最简单方法
public static int factorial(int n){ if(n!=1) return n*factorial(n-1); return 1; }