Related
I want to get an arraylist of all the numbers that are powers of primes below or equal to the upperbound.
this is what I got:
public class PrimePowers {
public static void main(String[] args) {
System.out.println(getPrimePowers(10));
}
public static List<Integer> getPrimePowers(int upperBound) {
ArrayList<Integer> primePower = new ArrayList<>();
for (int flag = 2; flag <= upperBound; flag++){
}
return ;
}
public static List<Integer> getPrimeNumbers(int upperBound){
ArrayList<Integer> primeNumber = new ArrayList<>();
for (int i = 2; i <=upperBound; i++){
if (!isPrime(i)) {
if(i != 1) {
primeNumber.add(i);
}
}
}
return primeNumber;
}
public static boolean isPrime(int num){
boolean flag = false;
for (int i = 2; i <= num / 2; ++i) {
// condition for nonPrime number
if (num % i == 0) {
flag = true;
break;
}
}
return flag;
}
}
so I have all the primenumbers, now I have to get all their powers below the upperbound.
my first question: how do I get all their powers, without getting 2 of the same in the list? or is that not an issue?
my second question: how do I program it such that I can get the power to also keep continuing going up, until the upper bound? i.e. if the upper bound is 10, with prime number 2 I should get 2^2 = 4 and 2^3 = 8.
an example:
program is called as getPrimePowers(50)
return: [4, 8, 9, 16, 25, 27, 32, 49]
sorry if this is really confusion, but I really appreciate the help
You can use IntStream:
Create an IntStream with values between 2 and the square root of
the upper bound.
Filter the stream prime numbers.
Flat map the stream for the powers using an IntStream mapper, map it to the power and filter values that are lower than the upper bound.
Finally, sort the resulting stream and collect it to a List.
Summaraizing in a method:
public static List<Integer> primePower(int upperBound) {
return IntStream.rangeClosed(2, (int) Math.sqrt(upperBound))
.filter(i -> isPrime(i))
.flatMap(i -> IntStream.rangeClosed(2,
(int) Math.rint(Math.pow(upperBound, 1d / i)))
.map(j -> (int) Math.pow(i, j))
.filter(j -> j <= upperBound))
.distinct().sorted()
.boxed().toList();
}
private static boolean isPrime(int value) {
return IntStream.rangeClosed(2, (int) Math.sqrt(value))
.allMatch(i -> value % i != 0);
}
Test:
List<Integer> primePower = primePower(50);
System.out.println(primePower);
Output:
[4, 8, 9, 16, 25, 27, 32, 49]
First, to calculate all the primes that are smaller then the upper bound, use isProbablePrime, which is way faster than any implementation you will write.
Secondly, after you collected all the primes, for each one of them you can calculate all their power by:
prime = ...
int max_power = (int)Math.floor(Math.log(upperBound) / Math.log(prime));
for (int p = 1, val = 1; p <= max_power; p++)
result.add(val *= prime);
Thirdly, you can't get any duplication (except the number 1), because each number can be factorized into primes in exactly one way, so don't worry about it.
I have numbers like 1100, 1002, 1022 etc. I would like to have the individual digits, for example for the first number 1100 I want to have 1, 1, 0, 0.
How can I get it in Java?
To do this, you will use the % (mod) operator.
int number; // = some int
while (number > 0) {
print( number % 10);
number = number / 10;
}
The mod operator will give you the remainder of doing int division on a number.
So,
10012 % 10 = 2
Because:
10012 / 10 = 1001, remainder 2
Note: As Paul noted, this will give you the numbers in reverse order. You will need to push them onto a stack and pop them off in reverse order.
Code to print the numbers in the correct order:
int number; // = and int
LinkedList<Integer> stack = new LinkedList<Integer>();
while (number > 0) {
stack.push( number % 10 );
number = number / 10;
}
while (!stack.isEmpty()) {
print(stack.pop());
}
Convert it to String and use String#toCharArray() or String#split().
String number = String.valueOf(someInt);
char[] digits1 = number.toCharArray();
// or:
String[] digits2 = number.split("(?<=.)");
In case you're already on Java 8 and you happen to want to do some aggregate operations on it afterwards, consider using String#chars() to get an IntStream out of it.
IntStream chars = number.chars();
How about this?
public static void printDigits(int num) {
if(num / 10 > 0) {
printDigits(num / 10);
}
System.out.printf("%d ", num % 10);
}
or instead of printing to the console, we can collect it in an array of integers and then print the array:
public static void main(String[] args) {
Integer[] digits = getDigits(12345);
System.out.println(Arrays.toString(digits));
}
public static Integer[] getDigits(int num) {
List<Integer> digits = new ArrayList<Integer>();
collectDigits(num, digits);
return digits.toArray(new Integer[]{});
}
private static void collectDigits(int num, List<Integer> digits) {
if(num / 10 > 0) {
collectDigits(num / 10, digits);
}
digits.add(num % 10);
}
If you would like to maintain the order of the digits from least significant (index[0]) to most significant (index[n]), the following updated getDigits() is what you need:
/**
* split an integer into its individual digits
* NOTE: digits order is maintained - i.e. Least significant digit is at index[0]
* #param num positive integer
* #return array of digits
*/
public static Integer[] getDigits(int num) {
if (num < 0) { return new Integer[0]; }
List<Integer> digits = new ArrayList<Integer>();
collectDigits(num, digits);
Collections.reverse(digits);
return digits.toArray(new Integer[]{});
}
I haven't seen anybody use this method, but it worked for me and is short and sweet:
int num = 5542;
String number = String.valueOf(num);
for(int i = 0; i < number.length(); i++) {
int j = Character.digit(number.charAt(i), 10);
System.out.println("digit: " + j);
}
This will output:
digit: 5
digit: 5
digit: 4
digit: 2
I noticed that there are few example of using Java 8 stream to solve your problem but I think that this is the simplest one:
int[] intTab = String.valueOf(number).chars().map(Character::getNumericValue).toArray();
To be clear:
You use String.valueOf(number) to convert int to String, then chars() method to get an IntStream (each char from your string is now an Ascii number), then you need to run map() method to get a numeric values of the Ascii number. At the end you use toArray() method to change your stream into an int[] array.
I see all the answer are ugly and not very clean.
I suggest you use a little bit of recursion to solve your problem. This post is very old, but it might be helpful to future coders.
public static void recursion(int number) {
if(number > 0) {
recursion(number/10);
System.out.printf("%d ", (number%10));
}
}
Output:
Input: 12345
Output: 1 2 3 4 5
simple solution
public static void main(String[] args) {
int v = 12345;
while (v > 0){
System.out.println(v % 10);
v /= 10;
}
}
// could be any num this is a randomly generated one
int num = (int) (Math.random() * 1000);
// this will return each number to a int variable
int num1 = num % 10;
int num2 = num / 10 % 10;
int num3 = num /100 % 10;
// you could continue this pattern for 4,5,6 digit numbers
// dont need to print you could then use the new int values man other ways
System.out.print(num1);
System.out.print("\n" + num2);
System.out.print("\n" + num3);
Since I don't see a method on this question which uses Java 8, I'll throw this in. Assuming that you're starting with a String and want to get a List<Integer>, then you can stream the elements like so.
List<Integer> digits = digitsInString.chars()
.map(Character::getNumericValue)
.boxed()
.collect(Collectors.toList());
This gets the characters in the String as a IntStream, maps those integer representations of characters to a numeric value, boxes them, and then collects them into a list.
Java 9 introduced a new Stream.iterate method which can be used to generate a stream and stop at a certain condition. This can be used to get all the digits in the number, using the modulo approach.
int[] a = IntStream.iterate(123400, i -> i > 0, i -> i / 10).map(i -> i % 10).toArray();
Note that this will get the digits in reverse order, but that can be solved either by looping through the array backwards (sadly reversing an array is not that simple), or by creating another stream:
int[] b = IntStream.iterate(a.length - 1, i -> i >= 0, i -> i - 1).map(i -> a[i]).toArray();
or
int[] b = IntStream.rangeClosed(1, a.length).map(i -> a[a.length - i]).toArray();
As an example, this code:
int[] a = IntStream.iterate(123400, i -> i > 0, i -> i / 10).map(i -> i % 10).toArray();
int[] b = IntStream.iterate(a.length - 1, i -> i >= 0, i -> i - 1).map(i -> a[i]).toArray();
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
Will print:
[0, 0, 4, 3, 2, 1]
[1, 2, 3, 4, 0, 0]
Easier way I think is to convert the number to string and use substring to extract and then convert to integer.
Something like this:
int digits1 =Integer.parseInt( String.valueOf(201432014).substring(0,4));
System.out.println("digits are: "+digits1);
ouput is
2014
I wrote a program that demonstrates how to separate the digits of an integer using a more simple and understandable approach that does not involve arrays, recursions, and all that fancy schmancy. Here is my code:
int year = sc.nextInt(), temp = year, count = 0;
while (temp>0)
{
count++;
temp = temp / 10;
}
double num = Math.pow(10, count-1);
int i = (int)num;
for (;i>0;i/=10)
{
System.out.println(year/i%10);
}
Suppose your input is the integer 123, the resulting output will be as follows:
1
2
3
Here is my answer, I did it for myself and I hope it's simple enough for those who don't want to use the String approach or need a more math-y solution:
public static void reverseNumber2(int number) {
int residual=0;
residual=number%10;
System.out.println(residual);
while (residual!=number) {
number=(number-residual)/10;
residual=number%10;
System.out.println(residual);
}
}
So I just get the units, print them out, substract them from the number, then divide that number by 10 - which is always without any floating stuff, since units are gone, repeat.
Java 8 solution to get digits as int[] from an integer that you have as a String:
int[] digits = intAsString.chars().map(i -> i - '0').toArray();
neither chars() nor codePoints() — the other lambda
String number = Integer.toString( 1100 );
IntStream.range( 0, number.length() ).map( i -> Character.digit( number.codePointAt( i ), 10 ) ).toArray(); // [1, 1, 0, 0]
Why don't you do:
String number = String.valueOf(input);
char[] digits = number.toCharArray();
Try this one.
const check = (num) => {
let temp = num
let result = []
while(temp > 0){
let a = temp%10;
result.push(a);
temp = (temp-a)/10;
}
return result;
}
check(98) //[ 8, 9 ]
public int[] getDigitsOfANumber(int number) {
String numStr = String.valueOf(number);
int retArr[] = new int[numStr.length()];
for (int i = 0; i < numStr.length(); i++) {
char c = numStr.charAt(i);
int digit = c;
int zero = (char) '0';
retArr[i] = digit - zero;
}
return retArr;
}
Integer.toString(1100) gives you the integer as a string. Integer.toString(1100).getBytes() to get an array of bytes of the individual digits.
Edit:
You can convert the character digits into numeric digits, thus:
String string = Integer.toString(1234);
int[] digits = new int[string.length()];
for(int i = 0; i<string.length(); ++i){
digits[i] = Integer.parseInt(string.substring(i, i+1));
}
System.out.println("digits:" + Arrays.toString(digits));
This uses the modulo 10 method to figure out each digit in a number greater than 0, then this will reverse the order of the array. This is assuming you are not using "0" as a starting digit.
This is modified to take in user input.
This array is originally inserted backwards, so I had to use the Collections.reverse() call to put it back into the user's order.
Scanner scanNumber = new Scanner(System.in);
int userNum = scanNumber.nextInt(); // user's number
// divides each digit into its own element within an array
List<Integer> checkUserNum = new ArrayList<Integer>();
while(userNum > 0) {
checkUserNum.add(userNum % 10);
userNum /= 10;
}
Collections.reverse(checkUserNum); // reverses the order of the array
System.out.print(checkUserNum);
Just to build on the subject, here's how to confirm that the number is a palindromic integer in Java:
public static boolean isPalindrome(int input) {
List<Integer> intArr = new ArrayList();
int procInt = input;
int i = 0;
while(procInt > 0) {
intArr.add(procInt%10);
procInt = procInt/10;
i++;
}
int y = 0;
int tmp = 0;
int count = 0;
for(int j:intArr) {
if(j == 0 && count == 0) {
break;
}
tmp = j + (tmp*10);
count++;
}
if(input != tmp)
return false;
return true;
}
I'm sure I can simplify this algo further. Yet, this is where I am. And it has worked under all of my test cases.
I hope this helps someone.
int number = 12344444; // or it Could be any valid number
int temp = 0;
int divider = 1;
for(int i =1; i< String.valueOf(number).length();i++)
{
divider = divider * 10;
}
while (divider >0) {
temp = number / divider;
number = number % divider;
System.out.print(temp +" ");
divider = divider/10;
}
Try this:
int num= 4321
int first = num % 10;
int second = ( num - first ) % 100 / 10;
int third = ( num - first - second ) % 1000 / 100;
int fourth = ( num - first - second - third ) % 10000 / 1000;
You will get first = 1, second = 2, third = 3 and fourth = 4 ....
Something like this will return the char[]:
public static char[] getTheDigits(int value){
String str = "";
int number = value;
int digit = 0;
while(number>0){
digit = number%10;
str = str + digit;
System.out.println("Digit:" + digit);
number = number/10;
}
return str.toCharArray();
}
As a noob, my answer would be:
String number = String.valueOf(ScannerObjectName.nextInt());
int[] digits = new int[number.length()];
for (int i = 0 ; i < number.length() ; i++)
int[i] = Integer.parseInt(digits.substring(i,i+1))
Now all the digits are contained in the "digits" array.
if digit is meant to be a Character
String numstr = Integer.toString( 123 );
Pattern.compile( "" ).splitAsStream( numstr ).map(
s -> s.charAt( 0 ) ).toArray( Character[]::new ); // [1, 2, 3]
and the following works correctly
numstr = "000123" gets [0, 0, 0, 1, 2, 3]
numstr = "-123" gets [-, 1, 2, 3]
A .NET solution using LINQ.
List<int> numbers = number.ToString().Select(x => x - 48).ToList();
I think this will be the most useful way to get digits:
public int[] getDigitsOf(int num)
{
int digitCount = Integer.toString(num).length();
if (num < 0)
digitCount--;
int[] result = new int[digitCount];
while (digitCount-- >0) {
result[digitCount] = num % 10;
num /= 10;
}
return result;
}
Then you can get digits in a simple way:
int number = 12345;
int[] digits = getDigitsOf(number);
for (int i = 0; i < digits.length; i++) {
System.out.println(digits[i]);
}
or more simply:
int number = 12345;
for (int i = 0; i < getDigitsOf(number).length; i++) {
System.out.println( getDigitsOf(number)[i] );
}
Notice the last method calls getDigitsOf method too much time. So it will be slower. You should create an int array and then call the getDigitsOf method once, just like in second code block.
In the following code, you can reverse to process. This code puts all digits together to make the number:
public int digitsToInt(int[] digits)
{
int digitCount = digits.length;
int result = 0;
for (int i = 0; i < digitCount; i++) {
result = result * 10;
result += digits[i];
}
return result;
}
Both methods I have provided works for negative numbers too.
see bellow my proposal with comments
int size=i.toString().length(); // the length of the integer (i) we need to split;
ArrayList<Integer> li = new ArrayList<Integer>(); // an ArrayList in whcih to store the resulting digits
Boolean b=true; // control variable for the loop in which we will reatrive step by step the digits
String number="1"; // here we will add the leading zero depending on the size of i
int temp; // the resulting digit will be kept by this temp variable
for (int j=0; j<size; j++){
number=number.concat("0");
}
Integer multi = Integer.valueOf(number); // the variable used for dividing step by step the number we received
while(b){
multi=multi/10;
temp=i/(multi);
li.add(temp);
i=i%(multi);
if(i==0){
b=false;
}
}
for(Integer in: li){
System.out.print(in.intValue()+ " ");
}
import java.util.Scanner;
class Test
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int num=sc.nextInt();
System.out.println("Enter a number (-1 to end):"+num);
int result=0;
int i=0;
while(true)
{
int n=num%10;
if(n==-1){
break;
}
i++;
System.out.println("Digit"+i+" = "+n);
result=result*10+n;
num=num/10;
if(num==0)
{
break;
}
}
}
}
Consider the following:
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.DoubleStream;
public class Test {
public static double sum(double[] x, int i, int L) {
double s = 0;
int hi = i + L;
while (i < hi) {
s += x[i - 1];
i++;
}
return s;
}
/*public static double streamSum(double[] x, int i, int L) {
return IntStream.range(0, x.length)
.parallel()
.filter(j -> (j < i + L))
.mapToObj(j -> x[j - 1])
.sum();
}*/
public static void main(String[] argv) {
double[] x = {1, 2, 3, 4};
System.out.println(sum(x, 1, 3));
}
}
sum above takes the array x and (based on 1-indexing - don't ask why, it has to be that way) takes a starting index i and obtains a subset of length L, summing over said subset. An example is given in main above.
How do I fix streamSum above so that I get the same output as sum except using a parallel stream?
You said you wanted to sum a sub array starting at i for length L. You should do it like this.
double r = IntStream.range(i, L+i)
.parallel()
.mapToDouble(id -> x[id-1])
.sum();
System.out.println(r);
The reason to subtract 1 is to account for the 1 based index requirement.
Here is a fix for the code in your question. You should take note of this answer though.
double r = IntStream.range(i, j)
.parallel()
.mapToDouble(idx -> x[idx])
.sum();
An even simpler way to achieve the same result would be:
Arrays.stream(x, i, j).parallel().sum();
Note: if you want to sum by length (L) rather than an upper bound, just replace j with i + L in the above code. Your criteria that it should be 1-based is problematic as written, since Java arrays are 0-based by default; working with them as if they are 1-based will eventually cause an IndexOutOfBoundException.
I am relatively new in Java 8 and lambda expressions as well as Stream, i can calculate factorial using for loop or recursion. But is there a way to use IntStream to calculate factorial of a number ? I am fine even with factorial in integer range.
I read through IntStream docs here, http://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html and i can see so many methods but not sure which one I can use to calculate factorial.
for example, there is rang method that says,
range(int startInclusive, int endExclusive) Returns a sequential
ordered IntStream from startInclusive (inclusive) to endExclusive
(exclusive) by an incremental step of 1.
so I can use it to provide the range of numbers to IntStream to be multiplied to calculate factorial.
number = 5;
IntStream.range(1, number)
but how to multiply those numbers to get the factorial ?
You can use IntStream::reduce for this job,
int number = 5;
IntStream.rangeClosed(2, number).reduce(1, (x, y) -> x * y)
To get a stream of all infinite factorials, you can do:
class Pair{
final int num;
final int value;
Pair(int num, int value) {
this.num = num;
this.value = value;
}
}
Stream<Pair> allFactorials = Stream.iterate(new Pair(1,1),
x -> new Pair(x.num+1, x.value * (x.num+1)));
allFactorials is a stream of factorials of number starting from 1 to ..... To get factorials of 1 to 10:
allFactorials.limit(10).forEach(x -> System.out.print(x.value+", "));
It prints:
1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800,
Now say you only wish to have a factorial of a particular number then do:
allFactorials.limit(number).reduce((previous, current) -> current).get()
The best part is that you dont recompute again for new numbers but build on history.
With LongStream.range() you can calculate factorial for number less 20. If you need calculate for larger number create stream with BigInteger:
public BigInteger factorial(int number) {
if (number < 20) {
return BigInteger.valueOf(
LongStream.range(1, number + 1).reduce((previous, current) -> previous * current).getAsLong()
);
} else {
BigInteger result = factorial(19);
return result.multiply(Stream.iterate(BigInteger.valueOf(20), i -> i.add(BigInteger.ONE)).limit(number - 19)
.reduce((previous, current) -> previous.multiply(current)).get()
);
}
}
We can solve the question with AtomicInteger like this:
int num = 5;
AtomicInteger sum = new AtomicInteger(1);
IntStream.rangeClosed(2, num).forEach(i -> {
sum.updateAndGet(v -> v * i);
if (i == num) {
System.out.println(sum.get());
}
});
I think we can change the main condition to:
1,vv-1,st with the function reduce.
Maybe we can filter before we did the main rule
Does Java have an equivalent to Python's range(int, int) method?
Old question, new answer (for Java 8)
IntStream.range(0, 10).forEach(n -> System.out.println(n));
or with method references:
IntStream.range(0, 10).forEach(System.out::println);
Guava also provides something similar to Python's range:
Range.closed(1, 5).asSet(DiscreteDomains.integers());
You can also implement a fairly simple iterator to do the same sort of thing using Guava's AbstractIterator:
return new AbstractIterator<Integer>() {
int next = getStart();
#Override protected Integer computeNext() {
if (isBeyondEnd(next)) {
return endOfData();
}
Integer result = next;
next = next + getStep();
return result;
}
};
I'm working on a little Java utils library called Jools, and it contains a class Range which provides the functionality you need (there's a downloadable JAR).
Constructors are either Range(int stop), Range(int start, int stop), or Range(int start, int stop, int step) (similiar to a for loop) and you can either iterate through it, which used lazy evaluation, or you can use its toList() method to explicitly get the range list.
for (int i : new Range(10)) {...} // i = 0,1,2,3,4,5,6,7,8,9
for (int i : new Range(4,10)) {...} // i = 4,5,6,7,8,9
for (int i : new Range(0,10,2)) {...} // i = 0,2,4,6,8
Range range = new Range(0,10,2);
range.toList(); // [0,2,4,6,8]
Since Guava 15.0, Range.asSet() has been deprecated and is scheduled to be removed in version 16. Use the following instead:
ContiguousSet.create(Range.closed(1, 5), DiscreteDomain.integers());
You can use the following code snippet in order to get a range set of integers:
Set<Integer> iset = IntStream.rangeClosed(1, 5).boxed().collect
(Collectors.toSet());
public int[] range(int start, int stop)
{
int[] result = new int[stop-start];
for(int i=0;i<stop-start;i++)
result[i] = start+i;
return result;
}
Forgive any syntax or style errors; I normally program in C#.
public int[] range(int start, int length) {
int[] range = new int[length - start + 1];
for (int i = start; i <= length; i++) {
range[i - start] = i;
}
return range;
}
(Long answer just to say "No")
Java 9 - IntStream::iterate
Since Java 9 you can use IntStream::iterate and you can even customize the step. For example if you want int array :
public static int[] getInRange(final int min, final int max, final int step) {
return IntStream.iterate(min, i -> i < max, i -> i + step)
.toArray();
}
or List :
public static List<Integer> getInRange(final int min, final int max, final int step) {
return IntStream.iterate(min, i -> i < max, i -> i + step)
.boxed()
.collect(Collectors.toList());
}
And then use it :
int[] range = getInRange(0, 10, 1);
IntStream.range(0, 10).boxed().collect(Collectors.toUnmodifiableList());
Groovy's nifty Range class can be used from Java, though it's certainly not as groovy.
The "Functional Java" library allows to program in such a way to a limited degree, it has a range() method creating an fj.data.Array instance.
See:
http://functionaljava.googlecode.com/svn/artifacts/3.0/javadoc/fj/data/Array.html#range%28int,%20int%29
Similarly the "Totally Lazy" library offers a lazy range method:
http://code.google.com/p/totallylazy/
I know this is an old post but if you are looking for a solution that returns an object stream and don't want to or can't use any additional dependencies:
Stream.iterate(start, n -> n + 1).limit(stop);
start - inclusive
stop - exclusive
If you mean to use it like you would in a Python loop, Java loops nicely with the for statement, which renders this structure unnecessary for that purpose.
Java 8
private static int[] range(int start, int stop, int step) {
int[] result = new int[(stop-start)%step == 0 ? (stop-start)/step : (stop-start)/step+1];
int count = 0;
Function<Integer, Boolean> condition = step > 0 ? (x) -> x < stop : (x) -> x > stop;
for (int i = start; condition.apply(i); i += step) {
result[count] = i;
count++;
}
return result;
}