I have two arrays of integers and I want to multiply them together like the following:
int[] arr1 = {6, 1}; // This represents the number 16
int[] arr2 = {4, 2}; // This represents the number 24
I want to store them in a new array so that the product appears as:
int[] productArray = {4, 8, 3};
I get how to do it with multiplying numbers like 2 x 24 since I can just push those into values into the product array. But when it comes to expanding beyond a single digit I am lost.
Why do you need to do this? Regardless, here is an example:
int total1; // to find what the array represents in #
for (int c = 0; c < arr1.length() - 1; c++) {
total1 += arr1[c] * Math.pow(10, (c+1)); // takes the number and adds it to the decimal number it should be
}
int total2;
for (int c = 0; c < arr2.length() - 1; c++) {
total1 += arr2[c] * Math.pow(10, (c+1));
}
String s = Integer.toString(total2*total1);
for (int c = s.length()-1; c >= 0; c--) { // adds int to array backwards
productArray.add(Integer.parseInt(s.atIndex(c)));
}
Notes: I have not bug tested this or run it through the JVM. Java isn't my usual programming language so I may have made a few mistakes. the "productArray" needs to be an ArrayList<> instead. I suspect that Integer.parseInt() is only for strings, so you may have to search for the char version of the function. Also, you need include Math...
int arr1num, arr2num, product;
multiplier = 1;
for (i = arr1.size();i>0;i--){
arr1num = arr1num + (arr1[i] * multiplier);
multiplier = multiplier * 10;
}
--do this also for the second array
-- now we have arr1num and arr2num as the numbers of both arrays and
just get the product
product = arr1num * arr2num;
-- now store it in an array
int divisor = 10;
int number;
for(i=0;i<int.length();i++){
number = product % divisor;
productArray.add(number);
divisor = divisor * 10;
}
You could use this (although it's not the best algorithm you could use to do this):
public static int[] multiplyArrays(int[] a, int[] b){
//turns arrays into integers
String num1 = "";
for (int i = a.length - 1; i > -1; i--){
num1 += a[i];
}
String num2 = "";
for (int i = b.length - 1; i > -1; i--){
num2 += b[i];
}
//does calculation
char[] answer = Integer.toString(Integer.parseInt(num1) * Integer.parseInt(num2)).toCharArray();
//converts char array into int array
int[] answer2 = new int[answer.length];
for (int i = 0; i < answer.length; i++){
answer2[answer.length - i - 1] = Integer.parseInt(String.valueOf(answer[i]));
}
return answer2;
}
Related
A PDDI is a number such the the sum of all the digits raised to themselves is equal to the number itself.
For example, 3435 = (3^3) + (4^4) + (3^3) + (5^5)
The code below takes too long to check for PDDIs between one to a huge number. Is there any way to make it faster?
System.out.print("Enter the number");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = 0, sum = 0, k = 0;
// We're going to try all integers between one to n.
for(int i = 1; i<=n; i++){
sum = 0;
m = i;
while(m>0){
k = m % 10;
sum = sum + (int)Math.pow(k, k);
m = m/10;
}
if(i == sum)
System.out.println(i);
}
The number from 0 to 9 to the power of 2 can be precalculated and kept in a an array.
int powered [] = new int [10];
powered[0] = 0;
powered[1] = 1;
powered[2] = 4;
..
powered[9] = 81;
Then for each digit fech the powered number using the digit as an index to the powered array.
For example 234 would be powered[2] + powered[3] + powered[4]
This will save some math operations.
Also you could think of a multithreaded approach having N threads doing the calculations for different numbers in parallel.
Use cached values instead of Math.pow
Since you are using only power from 0 to 9, you could cache these values in a int[] instead of computing Math.pow(k, k) everytime. It won't improve that much but, it's a start.
int[] pows = new int[] {0, 1, 4, 27, 256, 3125, 46656, 823543, 16777216, 387420489 };
for (int i = 0; i < 10; ++i) {
pows[i] = (int) Math.pow(i, i);
}
System.out.print("Enter the number");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = 0, sum = 0, k = 0;
// We're going to try all integers between one to n.
for(int i = 1, i<=n, i++){
sum = 0;
m = i;
while(m>0){
k = m % 10;
sum = sum + pows[k]; // use cached values here
m = m/10;
}
if(i == sum)
System.out.println(i);
}
Skip useless values
Based on logic you may skip some iterations.
Lets take the number 281 as an example, which gives 4 + 16777216 + 1 = 16777251, the result is above 281, so theres no changes that 282, 283, 284, ... 289 gives a number equals to 281.
In such cases you may want to skip these useless iterations by manually incrementing i.
int[] pows = new int [10];
for (int i = 0; i < 10; ++i) {
pows[i] = (int) Math.pow(i, i);
}
System.out.print("Enter the number");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = 0, sum = 0, k = 0, lastNumberDigit;
// We're going to try all integers between one to n.
for(int i = 1, i<=n, i++){
sum = 0;
m = i;
while(m>0){
lastNumberDigit = m; // on the last iteration, we'll get the last digit
k = m % 10;
sum = sum + pows[k]; // use cached values here
m = m/10;
}
if(i == sum) {
System.out.println(i);
} else if (sum > i) {
i += (10 - lastNumberDigit - 1); // jump to the next decade (-1 because the for will apply i++ on it)
}
}
I used this logic on decade, but you may want to extend it to hundreds or even more, but it will be much more tricky.
Is there more efficient way to do that?
Given number N - find all the narcissistic ( armstrong ) numbers that < N.
Here is my code, but I guess there is more efficient solutions. Also, probably, we could solve it through bit operation?
public static void main(String args[]) throws Exception
{
long a = System.nanoTime();
int t [] = getNumbers(4_483_647L);
long b = System.nanoTime();
System.out.println("Time totally "+(b-a));
for(int k: t)
System.out.print(k+" ");
}
public static int[] getNumbers(long N)
{
int length=1;
int porog=10, r=1, s=1;
double k;
LinkedList<Integer> list = new LinkedList<>();
for(int i=1; i<N; i++)
{
if(i==porog)
{
length++;
porog*=10;
}
s = i;
k=0;
while(s>0)
{
r = s%10;
k+=Math.pow(r, length);
if(k>i)break;
s=s/10;
}
if((int)k==i)
list.add(i);
}
int[] result = new int[list.size()];
int i=0;
for(int n: list)
{
result[i] = n;
i++;
}
return result; } }
Some observations:
If your initial maximum is a long, your results should be long types, too, just in case (int works for you as the narcissistic numbers are far apart)
If you change your return type to be a "big" Long, you can use Collections.toArray() to repack the results to an array...
...although really, you should just return the linked list...
You don't need to keep recalculating powers. For each decade in the outer loop, you only ever need i^j, where i=0..9 and j is the number of digits in the current decade
In fact, you don't need Math.pow() at all, as you can just use multiplication at each decade
Applying my ideas from my comment above and also changing the method signature, you get something that runs about 30 times faster:
public static Long[] getNumbers(long N) {
int porog = 10;
LinkedList<Long> list = new LinkedList<>();
// initial powers for the number 0-9
long[] powers = { 0l, 1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l, 9l };
for (long i = 1; i < N; i++) {
if (i == porog) {
porog *= 10;
// calculate i^length
for (int pi = 1; pi < 10; pi++) {
powers[pi] *= pi;
}
}
long s = i;
long k = 0;
while (s > 0) {
int r = (int)(s % 10);
k += powers[r];
if (k > i)
break;
s /= 10;
}
if (k == i)
list.add(i);
}
return list.toArray(new Long[]{});
}
From Rosetta Code blog (not my own code)
public static boolean isNarc(long x){
if(x < 0) return false;
String xStr = Long.toString(x);
int m = xStr.length();
long sum = 0;
for(char c : xStr.toCharArray()){
sum += Math.pow(Character.digit(c, 10), m);
}
return sum == x;
}
It's possible to generate Armstrong Numbers quite efficient. For example, all integers can be generated within 10-15 ms.
We may note that for each multi-set of digits, like [1, 1, 2, 4, 5, 7, 7] there is only one sum of powers, which in its turn may either be or be not represented by the digits from set. In the example 1^7 + 1^7 + 2^7 + 4^7 + 5^7 + 7^7 + 7^7 = 1741725, which can be represented by the digits and thus is an Armstrong number.
We may build an algorithm basing on this consideration.
For each number length from 1 to N
Generate all possible multi-sets of N digits
For each multi-set calculate sum of digits^N
Check if it's possible to represent the number we got on step 4 with
the digits from the multi-set
If so - add the number to the result list
The number of cases calculated for each length N is equal to the number of combinations (N + 9, 9) = (N+9)!/(9!N!). Thus for all Ns less than 10 we will generate only 92,377 multi-sets. For N<20: 20,030,009.
Please see GitHub for the description of a few approaches, along with some benchmarking and the Java code. Enjoy! :)
I'm not a professional coder, just self taught with no work experience, so I apologize if my code is bit sloppy.
I took dovetalk's solution and 1) wrote it myself so to better understand it b) made some adjustments that improved the run time considerably for large numbers. I hope this helps anyone else looking for help with this problem:
public static long[] getNumbers(long N) {
long tempII = N;
LinkedHashSet<Long> narcNums = new LinkedHashSet<>();
long tempResult;
long digitLengthTemp = 10;
long tempI;
long[] powers = {0l, 1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l, 9l};
for (long i = 0; i < N; i++) {
if (i == digitLengthTemp) {
digitLengthTemp *= 10;
for (short x = 2; x < powers.length; x++) powers[x] *= x;
}
//set value of top digits of numbers past first 3 to a remedial value
tempI = i;
long remedialValue = 0;
tempI /= 10; tempI /= 10; tempI /= 10;
while (tempI > 0) {
short index = (short) (tempI % 10);
remedialValue += powers[index];
tempI /= 10;
}
//only passes 1000 at a time to this loop and adds each result to remedial top half
for (int j = 0; j < (tempII > 1000 ? 1000 : tempII); j++) {
//sets digit length and increases the values in array
if (i == 0 && j == digitLengthTemp) {
digitLengthTemp *= 10;
for (short x = 2; x < powers.length; x++) powers[x] *= x;
}
//resets temp results
tempResult = remedialValue;
tempI = j;
//gets the sum of each (digit^numberLength) of number passed to it
while (tempI > 0) {
if (tempResult > i + j) break;
short index = (short) (tempI % 10);
tempResult += powers[index];
tempI /= 10;
}
//checks if sum equals original number
if (i + j == tempResult) narcNums.add(i + j);
}
i += 999; // adds to i in increments of 1000
tempII -= 1000;
}
//converts to long array
long[] results = new long[narcNums.size()];
short i = 0;
for (long x : narcNums) {
results[i++] = x;
}
return results;
}
A major optimisation is to not examine all the numbers in range 1..N . Have a look here.
I'm a total beginner of java.
I have a homework to write a complete program that calculates the factorial of 50 using array.
I can't use any method like biginteger.
I can only use array because my professor wants us to understand the logic behind, I guess...
However, he didn't really teach us the detail of array, so I'm really confused here.
Basically, I'm trying to divide the big number and put it into array slot. So if the first array gets 235, I can divide it and extract the number and put it into one array slot. Then, put the remain next array slot. And repeat the process until I get the result (which is factorial of 50, and it's a huge number..)
I tried to understand what's the logic behind, but I really can't figure it out.. So far I have this on my mind.
import java.util.Scanner;
class Factorial
{
public static void main(String[] args)
{
int n;
Scanner kb = new Scanner(System.in);
System.out.println("Enter n");
n = kb.nextInt();
System.out.println(n +"! = " + fact(n));
}
public static int fact(int n)
{
int product = 1;
int[] a = new int[100];
a[0] = 1;
for (int j = 2; j < a.length; j++)
{
for(; n >= 1; n--)
{
product = product * n;
a[j-1] = n;
a[j] = a[j]/10;
a[j+1] = a[j]%10;
}
}
return product;
}
}
But it doesn't show me the factorial of 50.
it shows me 0 as the result, so apparently, it's not working.
I'm trying to use one method (fact()), but I'm not sure that's the right way to do.
My professor mentioned about using operator / and % to assign the number to the next slot of array repeatedly.
So I'm trying to use that for this homework.
Does anyone have an idea for this homework?
Please help me!
And sorry for the confusing instruction... I'm confused also, so please forgive me.
FYI: factorial of 50 is 30414093201713378043612608166064768844377641568960512000000000000
Try this.
static int[] fact(int n) {
int[] r = new int[100];
r[0] = 1;
for (int i = 1; i <= n; ++i) {
int carry = 0;
for (int j = 0; j < r.length; ++j) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
and
int[] result = fact(50);
int i = result.length - 1;
while (i > 0 && result[i] == 0)
--i;
while (i >= 0)
System.out.print(result[i--]);
System.out.println();
// -> 30414093201713378043612608166064768844377641568960512000000000000
Her's my result:
50 factorial - 30414093201713378043612608166064768844377641568960512000000000000
And here's the code. I hard coded an array of 100 digits. When printing, I skip the leading zeroes.
public class FactorialArray {
public static void main(String[] args) {
int n = 50;
System.out.print(n + " factorial - ");
int[] result = factorial(n);
boolean firstDigit = false;
for (int digit : result) {
if (digit > 0) {
firstDigit = true;
}
if (firstDigit) {
System.out.print(digit);
}
}
System.out.println();
}
private static int[] factorial(int n) {
int[] r = new int[100];
r[r.length - 1] = 1;
for (int i = 1; i <= n; i++) {
int carry = 0;
for (int j = r.length - 1; j >= 0; j--) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
}
How about:
public static BigInteger p(int numOfAllPerson) {
if (numOfAllPerson < 0) {
throw new IllegalArgumentException();
}
if (numOfAllPerson == 0) {
return BigInteger.ONE;
}
BigInteger retBigInt = BigInteger.ONE;
for (; numOfAllPerson > 0; numOfAllPerson--) {
retBigInt = retBigInt.multiply(BigInteger.valueOf(numOfAllPerson));
}
return retBigInt;
}
Please recall basic level of math how multiplication works?
2344
X 34
= (2344*4)*10^0 + (2344*3)*10^1 = ans
2344
X334
= (2344*4)*10^0 + (2344*3)*10^1 + (2344*3)*10^2= ans
So for m digits X n digits you need n list of string array.
Each time you multiply each digits with m. and store it.
After each step you will append 0,1,2,n-1 trailing zero(s) to that string.
Finally, sum all of n listed string. You know how to do that.
So up to this you know m*n
now it is very easy to compute 1*..........*49*50.
how about:
int[] arrayOfFifty = new int[50];
//populate the array with 1 to 50
for(int i = 1; i < 51; i++){
arrayOfFifty[i-1] = i;
}
//perform the factorial
long result = 1;
for(int i = 0; i < arrayOfFifty.length; i++){
result = arrayOfFifty[i] * result;
}
Did not test this. No idea how big the number is and if it would cause error due to the size of the number.
Updated. arrays use ".length" to measure the size.
I now updated result to long data type and it returns the following - which is obviously incorrect. This is a massive number and I'm not sure what your professor is trying to get at.
-3258495067890909184
Hello fellow programmers !
I am a beginner with Java and i am looking for a method or a way maybe to store the digits of a 6 digit number entered by the user , in an int array.
For example :-
if the number is 675421.
then i want to store the digits in an array like :-
int[] array = new int[6];
int number = 675421
array[0] = 6;
array[1] = 7;
array[2] = 5;
array[3] = 4;
array[4] = 2;
array[5] = 1;
I want to do so so that i can work with the array to maybe sort or change the order or numbers in array. Thanks!
Here you go,
String temp = Integer.toString(number);
int[] num = new int[temp.length()];
for (int i = 0; i < temp.length(); i++){
num[i] = temp.charAt(i) - '0';
}
for (int i = 0; i < temp.length(); i++) {
System.out.println(num[i]);
}
Edit, after comment
Here, First, you are converting to your number to a string.
Then, take each char out of it(in the loop), subtract the ASCII value of 0 from each char to get the digit [ie, ASCII of 0 is 48, 1 is 49, ... ] (see ASCII table)
Do something like this:
String number = "123123";
int[] intArray = new int[number.length()];
for (int i = 0; i < number.length(); i++)
{
intArray[i] = Integer.parseInt(Character.toString(number.charAt(i)));
}
Hope this helps,
Jason.
Below is the recursive solution
public static void main(String[] args) {
int testNum = 675421;
List<Integer> digitList = new ArrayList<Integer>();
collectDigits(testNum, digitList);
Object[] resultArr = digitList.toArray();
int listSize = resultArr.length;
for (int listCount = 0; listCount < listSize; listCount++) {
System.out.println("result["+listCount+"] = "+resultArr[listCount]);
}
}
private static void collectDigits(int num, List<Integer> digits) {
if (num / 10 > 0) {
collectDigits(num / 10, digits);
}
digits.add(num % 10);
}
One way to do this would be to turn the original integer into a string.
Loop over the string, parsing each character back to an int, and place into the array. Here is an example:
int number = 123456;
String strNumber = number+"";
int[] array = new int[strNumber.length()];
int index = 0;
for(char c : strNumber.toCharArray()){
array[index++] = Integer.parseInt(c+"");
}
System.out.println(Arrays.toString(array));
Math solution, you can split the int number using this:
int[] array = new int[6];
int number = 675421;
array[0] = ((number/100000)%10);
array[1] = ((number/10000)%10);
array[2] = ((number/1000)%10);
array[3] = ((number/100)%10);
array[4] = ((number/10)%10);
array[5] = ((number/1)%10);
If the "number" has a variable length you can automate this, write a coment if you need help
I am trying to make an Array so that it contains 10 different integers 0-9.
I have this:
for (int i = 0; i < perm.length; i++)
{
int num = (int) (Math.random() * 9);
boolean check = true;
if (Arrays.asList(perm).contains(num) == true)
check = false;
else
{
check = true;
perm[i] = num;
}
while (check == false)
{
num = (int) (Math.random() * 9);
}
}
It seems that it should work and make an array with different integers, but it does not.
If you want to avoid creating a List you can just shuffle yourself :
Random random = new Random();
int[] perm = new int[10];
for (int i = 0; i < 10; i++) {
perm[i] = i;
}
for (int i = 0; i < 9; i++) {
int j = random.nextInt(10 - i);
int tmp = perm[i];
perm[i] = perm[i + j];
perm[i + j] = tmp;
}
System.out.println(Arrays.toString(perm));
How about this instead (if you want a more concise approach):
List<Integer> l = new ArrayList<Integer>();
for (int i = 0; i < 10; i++)
l.add(i); // add 0-9
Collections.shuffle(l)
Integer[] ints = l.toArray(new Integer[10]);
All we're doing here is creating a list, filling it with the integers 0-9, shuffling it, and writing the contents to an array.
If you want a more 'manual' approach, I'd suggest something like this:
List<Integer> l = new ArrayList<Integer>();
for (int i = 0; i < 10; i++)
l.add(i); // add 0-9
int[] ints = new int[10];
for (int i = 0 ; i < 10; i++)
ints[i] = l.remove((int)(Math.random() * l.size()));
System.out.println(Arrays.toString(ints));
[7, 2, 3, 4, 9, 6, 0, 1, 8, 5]
I'm assuming that you're allowed to use lists, since the code you posted includes a call to Arrays.asList.
It sounds like you're trying to generate a permutation of the numbers from 0 to 8 (9?). The easiest way to do this is to fill an array list with the numbers in sequence, and then use Collections.shuffle().