I want to write a code that asks for three numbers dig(1), dig(2), dig(3) and displays a sequence of numbers dig(1), dig(2), dig(3), ..., dig(n) according to this rule:
a = dig(2) - dig(1)
b = dig(3) - dig(2)
dig(n) = dig(n-1) + a if n is odd
dig(n) = dig(n-1) + b if n is even
Example:
7, 8, 5, 6, 3, 4, 1, 2, -1, 0
It asks an user for three integers dig1, dig2, dig3
It asks a number N ≥ 3 which will be the whole sequence count.
It prints a sequence beginning with
Then prints the sequence, beginning with the three leading integers, followed by N-3 other terms that follow the pattern defined by the first three integers. See examples below for more information.
(The sequence begins with n = 1, but of course the array starts at 0.)
int dig1 = 0;
int dig2 = 0;
int dig3 = 0;
int a;
int b;
int n = 0;
int i;
dig1 = scnr.nextInt();
dig2 = scnr.nextInt();
dig3 = scnr.nextInt();
n = scnr.nextInt();
int[] array = new int[n];
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
a = dig2 - dig1;
b = dig3 - dig2;
for (i = 3; i < n; i++){
if(i%2 == 0){
array[i] = b + array[i-1];
}
else{
array[i] = a + array[i-1];
}
}
System.out.println(array[i]);
}
}
whenever I try to print this out, I get this error:
java.lang.ArrayIndexOutOfBoundsException
Another example: if I put in the numbers: 0 1 0 9 into my input, I should receive back the sequence 0 1 0 1 0 1 0 1 0
Printing array[n-1] gives me back just the final output. I'm trying to iterate through each number.
Sorry if that's unclear, but any help would be great, thank you.
Your System.out.println(array[i]); seems to be out of the for loop. Then i will be equal to n. And there is no element with index n in array with length n. The elements are from 0 to n-1.
At first I thought that you were choosing an array size less than 3, and that the code was failing here, during the initialization of the array:
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
But now, I actually think that the last line of code is the problem. Have a closer look at your for loop:
for (i=3; i < n; i++) {
if (i % 2 == 0) {
array[i] = b + array[i-1];
}
else {
array[i] = a + array[i-1];
}
}
System.out.println(array[i]);
Appreciate that at the end of the for loop, i, the loop counter, will always be n, the size of the array. Accessing array[n] will always be out of bounds, because an array in Java has a highest addressable index of one less than the actual number of buckets. So, if you were intending to just print the final element, then use this:
System.out.println(array[i-1]);
or
System.out.println(array[n-1]);
at the line n=scrn.nextInt(), you are assigning to n a integer from scrn but you don't know the value of that integer.
Then with this:
int[] array = new int[n];
Your array is of size of n elements starting from index 0 to index n-1.
So let's suppose the value you affected to n with .nextInt() is inferior to 3: initial value of i, the loop will even not be reached, because you will be out of bounds just here:
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
since you will be attempting to affect a value on an array at an index that does not exists (n is inferior to three but you are trying to affect three values in an array of size n).
Then if n is superior to 3, since your printing code is out from the loop, the value of i is equal to n and there is no value at index n. remember, the loop will leave only if the condition i<n is false and to reach that condition i must be equal or superior and that will lead to an IndexOutOfBoundsException on printing.
I think you printing line code should be inside the for loop.
Related
Given an integer array, find the maximum number of sums of adjacent elements that are divisible by n.
Example 1:
input: long[] array = [1, 2, 3], n = 7
output: 0
Example 2:
input: long[] array = [1, 2, 4], n = 7
output: 1
Example 3:
input: long[] array = [2, 1, 2, 1, 1, 2, 1, 2], n = 4
output: 6
Constraints:
array.length = 50000
array[index] <= 2^31 - 1
n <= 2^31 - 1
Currently, this is my code:
public static int maxSums(long[] array, long n) {
int count = 0;
if (array.length == 1 && array[0] == n) {
return 1;
} else {
for (int i = 0; i < array.length; i++) {
long sum = 0;
for (int j = i; j < array.length; j++) {
sum += array[j];
if (sum % n == 0) {
count++;
}
}
}
}
return count;
}
which is essentially the window sliding technique. However, this code runs with time complexity O(n^2) which is pretty slow, and results in Apex CPU Time Limit Exceeded towards the higher end of the constraints. Is there a faster way to solve this?
An approach I just thought of is O(n*m), where n is the actual n parameter and m is the array length.
The algorithm remembers for every subsequence up to the current index what reminder the sequence sum has. This information is stored inside the array called currentMod.
When iterating over the input array this currentMod is updated. We simply add to each possible modulo value of iteration i-1 the value of the input array at index i. The updated array includes the number of subsequence sums ending at index i for each possible reminder: 0, 1, 2 up to n-1.
The element first element of tmpMod at index i includes the number of subsequences that end at index i and have a sum divisible by n. Therefore, we add them to our final result.
Here is the algorithm:
public static int maxSums(int[] array, int n) {
int[] currentMod = new int[n];
int count = 0;
for (int i = 0; i < array.length; i++) {
// Add +1 to 0 remainder as a new sequence can start at every index which has sum 0
currentMod[0] += 1;
int[] tmpMod = new int[n];
for (int j = 0; j < currentMod.length; j++) {
// For every subsequence reminder of i-1 calculate the reminders of adding element i to every subsequence
tmpMod[(j + array[i]) % n] += currentMod[j];
}
// Add number of subsequence sums that divide by n with remainder 0 to result
count += tmpMod[0];
currentMod = tmpMod;
}
return count;
}
P.S.: This algorithm is not strictly better/worse than yours. It depends on another input value. This means it depends on your inputs what is more efficient. My algorithm is only better for a case with large arrays and low n values.
EDIT: After a lot of thinking and testing I think I found a good solution. It is O(n) in time complexity. It is also O(n) in space complexity as there can be at most n different remainders with n values in the array.
The algorithm keeps track of the current remainder, which is dividable by the input n from the start. For each new subsequence, we add the 1 at the current remainder. In this way, we already define which total sum (mod n) we need that the subsequence is dividable by n.
public static int maxSums(int[] array, int n) {
Map<Integer, Integer> currentMod = new HashMap<Integer, Integer>();
int count = 0;
int currentZero = 0;
for (int val : array) {
currentMod.put(currentZero, currentMod.getOrDefault(currentZero, 0) + 1);
currentZero = (currentZero + val) % n;
count += currentMod.getOrDefault(currentZero, 0);
}
return count;
}
Also, some comparisons to show that it should work out:
len(array)=50000 and n=1000:
Your method: 11704 ms
My old one: 188 ms
My new one: 13 ms
len(array)=50000 and n=1000000:
Your method: 555 ms
My old one: stopped after 2 minutes
My new one: 6 ms
I got the 2d array to print but with all zero's and the only random number comes up on the bottom right corner
How do I get the code to print random numbers in all the elements of the 2d array?
Here is my code:
public static void main(String[] args) {
int columns = 8;
int rows = 4;
int rLow = 2;
int rHigh = 9;
printRandos(columns, rows, rLow, rHigh);
}
public static void printRandos(int clmn, int rws, int rlow, int rhigh) {
Random rando = new Random();
int randoNum = rlow + rando.nextInt(rhigh);
int[][] randoArray = new int[rws][clmn];
for (int i = 0; i < rws; i++) {
for (int k = 0; k < clmn; k++) {
randoArray[rws - 1][clmn - 1] = randoNum;
System.out.print(randoArray[i][k] + " ");
}
System.out.print("\n");
}
}
for (int i = 0; i < rws; i++)
{
for (int k = 0; k < clmn; k++)
{
int randoNum = rlow + rando.nextInt(rhigh);
randoArray[i][k] = randoNum;
System.out.print(randoArray[i][k]+" ");
}
System.out.print("\n");
}
your mistake inside the inner for loop of the printRandos method. Firstly your random number is outside the loop so your array elements were receiving the same number all the time. Another mistake is that you are assigning the value to the same array element all the time i.e rws-1 and clmn-1 .
inside your inner loop replace it with this:
int randoNum = rlow + rando.nextInt(rhigh);
randoArray[i][k] = randoNum;
System.out.print(randoArray[i][k]+" ");
Your bug is in this line:
randoArray[rws-1][clmn-1] = randoNum;
This stores your random number into randoArray[rws-1][clmn-1] each time, which as you noticed, is the bottom right corner. rws is always 4, and clmn is always 8. So you store the same number there 32 times, which gives the same result as storing it only once.
In the following line you are correctly printing the number from the current array location:
System.out.print(randoArray[i][k]+" ");
An int array comes initialized with all zeroes, and since except for the last corner you have not filled anything into your array, 0 is printed.
Also if you want different random numbers in all the cells, you would need to call rando.nextInt() inside your innermost for loop.
Unless you need this 2-D array for some purpose (which doesn't show from the minimal example code that you have posted), you do not need it for printing a matrix of random numbers, i.e., you may just print the numbers form within your loop without putting them into the array first.
Finally if rhigh should be the highest possible random number in the array, you should use rando.nextInt(rhigh - rlow + 1). With rlow equal to 2 and rhigh equal to 9 this will give numbers in the range from 0 inclusive to 9 - 2 + 1 = 8 exclusive, which means that after adding to rlow = 2 you will get a number in the range from 2 to 10 exclusive, in other words, to 9 inclusive.
I am on purpose leaving to yourself to fix your code based on my comments. I believe your learning will benefit more from working it out yourself.
Your assign the array value outside the array length
int[][] randoArray = new int[rws][clmn];
randoArray[rws][clmn] = randoNum;
Here randoArray[rws] is out of bounds.
Can someone explain to me how this code works?
It lets the user input numbers up until 1000, then it prints the original inputted numbers, the even and the odd, all in a separate array. But I just don't understand the parts where there is gem++ and gem1++ when it outputs the even and odd not the number of the even and odd numbers.
And after putting this
double even[] = new double[gem];
double odd[] = new double [gem1];
why does it need to repeat gem=0 and gem1=0 again? I'm so sorry if I ask too many question, I'm just confused, I just learned java last week.
public class wutt {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter no. of elements you want in array : ");
int n = s.nextInt();
if (1 <= n && n <= 1000) {
double a[] = new double[n];
int gem = 0, gem1 = 0;
System.out.println("Enter all the elements : ");
for (int i = 0; i < n; i++) {
a[i] = s.nextInt();
if (a[i] % 2 == 0)
gem++;
else
gem1++;
}
double even[] = new double[gem];
double odd[] = new double[gem1];
gem = 0;
gem1 = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] % 2 == 0) {
even[gem] = a[i];
gem++;
} else {
odd[gem1] = a[i];
gem1++;
}
}
System.out.println("Original: " + Arrays.toString(a));
System.out.println("Odd: " + Arrays.toString(odd));
System.out.println("Even: " + Arrays.toString(even));
} else
System.out.print("Invalid input");
}
}
If you want the program stops after the user enters a number greater than 1000 o less than 0 you need to add the break statement in your if condition.
if (size < 0 || size > 1000) {
System.out.println("Size must be between 0 and 1000");
break;
}
the code before double even[] = new double[gem];
double odd[] = new double [gem1]; is trying to get the number of odds occurred and the number of even occurred and put all inputted elements in array a.
after all that ,now what we got is a array of numbers called a containing all the inputted elements. and two numbers called gem and gem1, which contains the number of odds occurred and the number of even occurred.
so
we get gem(numberOfEvens), gem1(numberOfOdds) and list a
next, we need to put all odds from a to a new array called odd[] with size gem1, and
put all evens from a to a new array called even[] with size gem. at this point, the duty of variable gem1 and gem is done. they become useless.
now we need to go through the list and pick the odd and even out and put them in the array one by one in a sequential way. that's why we need two new variables with 0 initialized.
in this case, because gem and gem1 are useless aready, they are reassigned to help manipulate the tree arrays a , odd[] and even[]
So the user inputs the number of elements he/she wants in the array (n)
double a[] = new double[n]; // a is the array that is initialised to accommodate n elements
int gem = 0, gem1 = 0; // gem is the counter for "even" numbers and "gem1" the counter for odd numbers, and like every good counter, they start at 0
System.out.println("Enter all the elements : ");
for (int i = 0; i < n; i++) { // so we ask the user to input n elements
a[i] = s.nextInt(); // here we read every input and put it in the a array
if (a[i] % 2 == 0) // if the new number is even
gem++; // we increase the even counter "gem"
else // otherwise, when it is an odd number
gem1++; // we increase the odd counter
}
double even[] = new double[gem]; // now we create a new array where we want to hold all the even numbers, we do that by telling it how many even numbers we have counted before (gem)
double odd[] = new double[gem1]; // and a new array for all odd numbers (gem1 was our counter)
gem = 0; // now we reinitialise the counters, because we want to start from the beginning
gem1 = 0;
for (int i = 0; i < a.length; i++) { // in order to copy all numbers from the a array into the two other arrays for even and odd numbers, we iterate over the whole length of the a array. i is the index for the "a" array
if (a[i] % 2 == 0) { // ever even number we encounter
even[gem] = a[i]; // we put in the even array
gem++; // while gem, the "even numbers counter" is our index for the "even" array
} else {
odd[gem1] = a[i]; // odd numbers are for the odd array
gem1++; // while the former "odd numbers counter" now serves as our "odd" array index
}
}
and that's pretty much it. First the user inputs all numbers in a single array and simply counts how many odd and how many even numbers where inputted,
then two new arrays are created, one for the even and one for the odd numbers and since we counted them, we know how big these two new arrays have to be.
And finally all numbers are again iterated over and put in their according array.
At the end you have 3 array, one that holds all numbers, one that holds the even numbers and one with only the odd numbers.
EDIT
here are a few minor changes you could make without changing the nature of that method:
double allNumbers[] = new double[n]; // "allNumbers" is way more specific than "a"
int oddCounter = 0; // "oddCounter" instead of "gem"
int evenCounter = 0; // numbers in variables like "gem1" is really bad practice, because numbers don't say anything about the nature of the variable
System.out.println("Enter all the elements : ");
for (int i = 0; i < n; i++) {
allNumbers[i] = s.nextInt();
if (allNumbers[i] % 2 == 0) {
evenCounter++;
} else {
oddCounter++;
}
}
// until here nothing changes but the names
double even[] = new double[evenCounter];
double odd[] = new double[oddCounter];
int oddIndex = 0; // and here we create new variables, instead of reusing old ones
int evenIndex = 0; // there is absolutely no performance gain in reusing primitives like this - it's just confusing
for (int i = 0; i < allNumbers.length; i++) {
if (allNumbers[i] % 2 == 0) {
even[evenIndex++] = allNumbers[i]; // the "++" can be done directly in the first expression. that's just to make it shorter.
} else {
odd[oddIndex++] = allNumbers[i]; // it is not more performant nor easier to read - just shorter
}
}
EDIT (again)
This is how the arrays look like, say when you enter 4 numbers:
gem = 0
gem1 = 0
n = 4 // user said 4
a = [ , , , ] // array a is empty but holds the space for 4 numbers
a = [1, , , ] // user enters 1
^
i=0
gem1 = 1 // 1 is an odd number -> gem1++
a = [1,4, , ] // user entered "4"
^
i=1
gem = 1 // 4 is an even number -> gem++
a = [1,4,2, ] // user entered "2"
^
i=2
gem = 2 // 24 is an even number -> gem++
a = [1,4,2,7] // user entered "7"
^
i=3
gem1 = 2 // 7 is an odd number -> gem1++
then we fill the other arrays
even = [ , ] // gem is 2, so we have 2 even numbers
odd = [ , ] // gem1 is 2, so we have 2 odd numbers
a = [1,4,2,7]
^
i=0
odd[1, ] // for i=0, a[i] is 1, which is an odd number
a = [1,4,2,7]
^
i=1
even = [4, ] // for i=1, a[i] is 4, which is an even number
a = [1,4,2,7]
^
i=2
even = [4,2] // for i=2, a[i] is 2, which is an even number
a = [1,4,2,7]
^
i=3
odd = [1,7] // for i=3, a[i] is 7, which is an odd number
and in the end you have
a = [1,4,2,7]
even = [4,2]
odd = [1,7]
A perfect number is one that is the sum of its factors, excluding itself. The 1st perfect number is 6 because 6 = 1 + 2 + 3. The 2nd perfect number is 28 which equals 1 + 2 + 4 + 7 + 14. The third is 496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248. In each case, the number is the sum of all its factors excluding itself.
Write a method named henry that takes two integer arguments, i and j and returns the sum of the ith and jth perfect numbers. So for example, henry (1, 3) should return 502 because 6 is the 1st perfect number and 496 is the 3rd perfect number and 6 + 496 = 502.
I have done this far:: but this is showing ArrayIndexOutOfBoundException at this line temp[index] = j; please help me to solve this OutOfBound issue, Thanks..
public static int henry (int a, int b){
List<Integer> arr = new ArrayList<Integer>();
int henryNumber = 0;
for(int i=4;;i++){
List<Integer> temp = new ArrayList<Integer>();
int sum = 0;
for(int j = 1; j<i; j++){
if(i%j == 0 ) { temp.add(j); }
}
for (Integer item : temp) { sum+=item; }
if(sum == i) arr.add(i);
if(arr.size() == b) {
henryNumber = arr.get(a-1) + arr.get(b-1);
break;
}
}
return henryNumber;
}
int[] temp = {};
This sets temp to an array of 0 elements. So when you try to access temp[index] where index is = to 0 its out of bounds because the array doesn't have even a single element
You would need to create an array of x number elements by doing:
int[] temp = new int[x];
and then you can set the value at each of the indicies to whatever value you want.
An array has a fixed length as soon as it it created, and that length cannot be changed.
int[] temp = {};
This creates an empty array. Its length is zero. You can't change that, you can't add any items to it.
temp[index] = j;
This tries to put something in the temp array. However, as I said, the array is empty, its length is zero, so any value of index would be out of bounds.
Using a List (which is commented out in your source) will allow you to create a growing collection of elements. Alternatively, you have to think of a proper size for your array, that will hold all the elements you'll be using, and use that size when you create the array.
Try doing
int[] temp=new int[i];
instead of
int[] temp={};
I have never assigned an array like this before.
I just want to know how this program works, and why the answer is 14.
here is the code:
public class extra {
public static void main(String[] args){
int[][] table = {{1,2,3},{4,5,6},{7,8,9}};
int sum = 0;
for( int i = 2; i > 0; i-- )
sum += table[i][3-i];
System.out.println(sum);
}
}
I understand the way the matrix is set up
123
456
789
but what is i in this problem, because I thought it was the number of rows, but since it is in a for loop, does it mean that i is the number in the matrix? Also how do the [i][3-i] come in to affect? The answer is 14, and I just want to know how it is 14.
It is only summing part of a diagonal, specifically table[2][1] which is 8, and table[1][2] which is 6.
The easiest way to see what is going on is to add an output statement in the loop:
for (int i = 2; i > 0; i--) {
sum += table[i][3 - i];
System.out.println(i + " " + (3 - i) + " " + table[i][3 - i]);
}
your program takes table[2][1] (value of 8) and table[1][2] (value of 6) elements, sums them and prints as output (value of 14)
regarding your question in a title your main method should be more like this:
public static void main(String[] args) {
int[][] table = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int sum = 0;
System.out.println("Before\n");
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
sum += table[i][j];
System.out.printf("Sum after %d iteration: %d\n", i + j + 1, sum);
}
}
System.out.println("\nIn total: " + sum);
}
i + j + 1 is a sum of current iteration which is sum of both axises, and since Java has 0-based indexed tables, it is increased by 1
Hope it helps!
i, in itself, does not correspond directly to anything in the matrix. It is just the name of the variable that the for loop changes each time it loops.
The [i][3-i] is how the i interacts with table. On the first round of the for loop, the i will be equal to 2. Thus, sum will be increased by table[2][1], which is the 3rd row and the 2nd column of the matrix, which has a value of 8.
On the second round of the for loop, the for loop, the i will be equal to 1. Thus, sum will be increased by table[1][2], which is the 2nd row and the 3rd column of the matrix, which has a value of 6.
Therefore, sum will be equal to 8+6=14.
What the for loop does is as follows:
i = 2. Enter loop.
Add table[2][3-2] to sum. Sum is now 8, because table[2][1] = 8.
Decrement i by 1.
i = 1. Enter loop.
Add table[1][3-1] to sum. Sum is now 14, because table[1][2] = 6.
Decrement i by 1.
i = 0. 0 is not greater than 0, so we exit the loop. The sum became 14.
Two-dimensional arrays like int[][] table have two indexes. One for the "outer" array (or rows), and one for the "inner" ones (columns).
Let's use int[][] table = {{1,2,3},{4,5,6},{7,8,9}}; from your code as an example:
table[1][2]: 1 means we should look in the array at index 1, which is {4,5,6}. 2 means we should look at {4,5,6}'s index 2, which is 6. In other words table[1][2] == 6.
table[2][0]: 2 means we should look in the array at index 2, which is {7,8,9}. 0 means we should look at {7,8,9}'s index 0, which is 7.
for (int i = 2; i > 0; i--)
so starting at 2 it checks if i is greater than zero
loops once then i-- subtracts 1
check again still greater than 0
loops again then subtracts 1 again
checks if greater than 0 now 0 it is not greater than 0 so stops looping
//thus loops 2 times
//[0] = 1st [1] = 2nd [2] = third ...
//counting in code starts at zero not 1 so and array of 3 counts a the spaces 0,1,2
int sum = 0;//sum starts at zero
//using the value of i translates as such
sum += table[2][3-2];//[2][1]this is 3rd group 2nd part so sum += 8
//then
sum += table[1][3-1];//[1][2]this is 2nd group 3rd part so sum += 6
0 + 8 + 6 = 14
Here's how to add elements in a 2D array in a easy way.
First when you initialize a 2D array think of the first brackets [ ] as a column and the second bracket [ ] as column rows.
For example: int[][] num = new int[10][5] which means 10 columns and 5 rows.
If you want to fill all the elements in a 2D array you must use two for loops:
int[][] num = new int[10][5];
for (int i =0; i < num.length;i++ ) {
for (int x=0; x < num[0].length;i++) { //we used num[0] because we need the length of the rows not the columns
num[i][x] = //any value you want to assign
}
}