For each multiple of 10 in the given array, change all the values following it to be that multiple of 10, until encountering another multiple of 10. So {2, 10, 3, 4, 20, 5} yields {2, 10, 10, 10, 20, 20}.
I don't understand why this works. In my mind the output for {1, 10, 2, 2} should be {1, 10, 10, 2}, because the for loop should only detect %10 == 0 once, and then loop back and not detect it the next time. Why does it do this more then once?
public int[] tenRun(int[] nums) {
for (int i = 0; i < nums.length-1; i++) {
if (nums[i] % 10 == 0) {
if (nums[i+1] % 10 != 0) {
nums[i+1] = nums[i];
}
}
}
return nums;
}
Try this:-
public int[] tenRun(int[] nums) {
for(int i=0;i<nums.length;i++){
if(nums[i]%10==0){
for(int j=i+1;j<nums.length && nums[j]%10!=0;j++){
nums[j]=nums[i];
}
}
}
return nums;
}
In each iteration, whenever the condition, nums[i] % 10 == 0 evaluates to true (i.e. nums[i] is a multiple of 10), it checks if the next element is not a multiple of 10 i.e. nums[i + 1] % 10 != 0 and if it is the case, it sets the next element to nums[i] which is a multiple of 10. I hope, it helps you understand how it works. Feel free to comment in case of any further doubt.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
System.out.println(Arrays.toString(tenRun(new int[] { 2, 10, 3, 4, 20, 5 })));
}
public static int[] tenRun(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] % 10 == 0) {
if (nums[i + 1] % 10 != 0) {
nums[i + 1] = nums[i];
}
}
}
return nums;
}
}
Output:
[2, 10, 10, 10, 20, 20]
The for loop only loops nums.length-1 times, and it looks at all the overlapping pairs of elements in the array: nums[i] (which I will call a) and nums[i+1] (which I will call b).
The for loop will only ever change b, and never a. It only checks if a is a multiple of 10. If it is, set b to a. Look at the last pair in the array, b here is the last element. Therefore, the last element will potentially be changed by the loop.
The loop will at some point look at nums[1] and nums[2], and after setting nums[2] to 10, it now looks at the last pair, which is nums[2] (a) and nums[3] (b). Notice how nums[2] has just been set a value of 10, so that, nums[3] can be set to 10 as well.
On the other hand, the loop will never sets the first element, which is the a of the first pair. This is correct as it will not be after any multiples of 10.
When you detect a multiple of 10, followed by a non-multiple of 10, your algorithm updates the following value. On the next iteration of the loop you encounter this updated value. Given that this has to be a multiple of 10 now, the subsequent value is then updated.
If we consider the state of i and nums at the start of each iteration, we find:
0: 1, 10, 2, 2
1: 1, 10, 2, 2
2: 1, 10, 10, 2
So on that final iteration (the loop terminates when i == 3), nums[2] == 10, hence nums[3] is also set to 10.
Related
I have a homework assignment that needs me to write a method that, given a list, will remove all multiples of 3 and add the first 5 multiples of 4, 5, and 6. It will then add that list to a HashSet, removing the duplicate integers, and return the size of the HashSet.
I've figured out everything else in this problem save for the "add first 5 multiples of 4, 5, and 6". My current code is the one I'm stuck with, using a for loop to iterate from 1 to 30. However, given an empty list, this adds 28, which is the 7th multiple of 4. I've tried nesting loops so I can iterate to 30 while at the same time iterating to 5, but none of my attempts have worked. Can anyone help me out?
Below is my current code.
public static int modify(List<Integer> list) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == null) {
throw new IllegalArgumentException("Cannot be null.");
}
if (list.get(i) % 3 == 0) {
list.remove(i);
}
}
for (int i = 1; i <= 30; i++) {
if (i % 4 == 0) {
list.add(i);
}
if (i % 5 == 0) {
list.add(i);
}
if (i % 6 == 0) {
list.add(i);
}
}
Collections.sort(list);
HashSet<Integer> unique = new HashSet<Integer>();
unique.addAll(list);
return unique.size();
}
Instead of counting to 30 and checking for incidences of multiples of 4, 5, and 6, why don't you find the multiples directly?
for (int i = 1; i <= 5; i++) {
list.add(4 * i);
list.add(5 * i);
list.add(6 * i);
}
If there are any duplicates, they'll be removed when you add them to the HashSet.
Side note: I'm not sure why you're bothering to sort the list before you add them to the HashSet. Sets inherently have no order so it doesn't matter if the list is sorted or not.
I'm assuming you're expecting the output of passing in an empty list to be:
unique = [4, 5, 6, 8, 10, 12, 15, 16, 18, 20, 24, 25, 30]
size = 13
With your current logic, there's nothing stopping it from adding multiples which are more than 5 (i.e. the 7th multiple of 4 for example), you're just continuing on until you've hit 30 in the loop. Instead, I might recommend having your for loop go 1-5 and then multiply by the factor you'd like a multiple of. i.e.:
// add the first 5 multiples of 4,5,6 to the list
for (int i = 1; i < 6; i++) {
list.add(i*4);
list.add(i*5);
list.add(i*6);
}
I rewrote the whole method making some changes:
The removal part of multiples of 3 in this way is more efficient. I
used the very useful removeIf() method.
I wrote the solution to your problem, identical to the other
answers.
CODE
public static void main(String[] args) {
List<Integer> list = new LinkedList<>();
for (int i = 0; i < 30; i++) {
list.add(i);
}
System.out.println(modify(list));
}
public static int modify(List<Integer> list) {
list.removeIf(n -> (n % 3 == 0));
for (int i = 1; i < 6; i++) {
list.add(4 * i);
list.add(5 * i);
list.add(6 * i);
}
Collections.sort(list);
HashSet<Integer> unique = new HashSet<>(list);
System.out.println(unique.toString()); // You can delete this
return unique.size();
}
OUTPUT
[1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 28, 29, 30]
26
I'm struggling to run this java correctly with a for each loop. It is fine for every test but the last. Could anyone kindly assist in letting me know where I'm going wrong? I feel confident I could do it with a for loop but would like to do it with a for each loop (if suitable).
Drill Question:
Given an array of ints, return true if the sequence of numbers 1, 2, 3 appears in the array somewhere.
arrayOneTwoThree([1, 1, 2, 3, 1]) -> true.
arrayOneTwoThree([1, 1, 2, 4, 1]) -> false.
arrayOneTwoThree([1, 1, 2, 1, 2, 3]) -> true.
For example:
int[] array = {2, 1, 2, 3, 2, 3, 2, 4, 1};
System.out.println(arrayOneTwoThree(array));
Result: true
public static void main(String[] args) {
//int[] array = {2, 1, 2, 3, 2, 3, 2, 4, 1};
//int[] array = {1, 1, 2, 3, 1};
//int[] array = {1, 1, 2, 4, 1};
int[] array = {1, 1, 2, 1, 2, 3};
System.out.println(arrayOneTwoThree(array));
}
public static boolean arrayOneTwoThree(int[] nums) {
for (int num : nums) {
//System.out.print(num);
if (nums[num] == 3 && nums[num-1] == 2 && nums[num-2] == 1)
return true;
}
return false;
}
In the loop, num is NOT the index within the array, it is the value.
I think you are expecting num to be the index, which would be the case if you did a for loop of the form for (int num =0; num < nums.length; num++)
If you want to compare n adiacent elements of array you have to use a loop ending to length - n - 1 : in your case n = 3 so your method can be written like below:
private static boolean arrayOneTwoThree(int[] array) {
final int n = array.length;
if (n < 3) { return false; } //<-- for arrays with less than 3 elements
for (int i = 0; i < n - 2; ++i) {
if (array[i] == 1 && array[i + 1] == 2 && array[i + 2] == 3) {
return true;
}
}
return false;
}
First tree test cases accidentally shoved correct result!
Your code works ONLY for cases, when index of 1 is 1, index of 2 is 2, and index of 3 is 3:
[*, 1, 2, 3, ......... ]
You are probably confused with another programming language. (Maybe for in construction of JavaScript?).
In Java for each over array (or anything else) iterates over values and never over indexes. (As was already specified)
I can see commented out System.out.print(num); why you've ignored it prints values not indexes?
Another issue is ignoring array bounds... Try to examine your code with next array:
int[] array = {2, 3, 2, 1, 2, 3};
It'll end up with ArrayIndexOutOfBoundsException
And answer for your question, how to solve with for each.
Yes, you can introduce external counter, but what would be the sense then?
public static boolean arrayOneTwoThree(int[] nums) {
int i = 0;
for (int num : nums) {
//System.out.print(num);
if (i < 2) continue; // we do not want ArrayIndexOutOfBoundsException happened, right?
if (nums[i] == 3 && nums[num-1] == 2 && nums[num-2] == 1)
return true;
}
return false;
}
If you wish to use for each you should avoid of using indexes to be consistent.
There could be tons of different solutions. You can use some flags or save previous and beforePrevious:
public static boolean arrayOneTwoThree(int[] nums) {
int beforePrevious;
int previous = 0;
int current = 0;
for (int num : nums) {
//System.out.print(num);
beforePrevious = previous;
previous = current;
current = num;
if (current == 3 && previous == 2 && beforePrevious == 1)
return true;
}
return false;
}
Beware: It's just first thought, so this solution may be not optimal and far from perfect, probably you can do better.
I have two arrays of different sizes that I am trying to loop through and perform calculations on, but I am ending up with incorrect outputs.
Here are the arrays:
int[] array1 = [5, 10, 2]
int[] array2 = [11, 23, 4, 6, 5, 8, 9]
int[] array1 = {5, 10, 2};
int[] array2 = {11, 23, 4, 6, 5, 8, 9};
ArrayList<Integer> calculationsArray = new ArrayList<Integer>();
int calculations = 0;
for(int i = 0; i < array1.length; i++) {
for(int j = 0; j < array2.length; j++) {
calculations = ((array1[i] + array2[j]) % 10);
}
calculationsArray.add(calculations);
}
I expect the output of [6, 3, 6, 1, 0, 8, 1]. Example calculations for 4 loops would be:
(11 + 5) % 10 = 6
(23 + 10) % 10 = 3
(4 + 2) % 10 = 6
(6 + 5) % 10 = 1
But the actual output is: [4, 9, 1]
Let's first talk about why you're seeing what you're seeing.
I've reposted your code here, with the indentation changed to reflect the nesting:
for(int i = 0; i < array1.length; i++) {
for(int j = 0; j < array2.length; j++) { // <--- This loop
calculations = ((array1[i] + array2[j]) % 10);
}
calculationsArray.add(calculations);
}
Let's take the inner loop, the one that I've marked above. Notice that on each iteration of the loop, you set calculations to a new value. This overwrites the value that was computed earlier, so that when the inner loop finishes running, the value of calculations will be equal to the last value that's computed in that loop. And that accounts for what you're actually seeing, because
when i = 0, the inner loop's last calculation is (array1[0] + array2[6]) % 10, which is (5 + 9) % 10 = 4,
when i = 1, the inner loop's last calculation is (array1[1] + array2[6]) % 10, which is (10 + 9) % 10 = 9,
when i = 2, the inner loop's last calculation is (array1[2] + array2[6]) % 10, which is (2 + 9) % 10 = 1.
And hey, look! There's your [4, 9, 1] that you're seeing.
The next question is how to go about fixing this. The major issue I believe that you're running into here is the fact that doubly-nested loops probably isn't the way to go here. Specifically, a double for loop here will run array1.length × array2.length times, which is way more than the number of times that you need it to run.
So a first question - how many times should the loop run? Well, you want your output array to have the length of the longer of the two input arrays, which is Math.max(array1.length, array2.length) times. Could you make a single loop that counts up to that number?
You then need to handle the fact that your loop may need to cycle through each input array multiple times. In the example you've given, you'll read the values of array1 multiple times because array2 is longer, but you just as easily could have had to read the values of array2 multiple times if array1 were longer.
As a hint for how to do this, see if you can use the mod operator % to wrap around when the indices get too big.
Hope this helps!
What about somenthing like (not optimized):
ArrayList<Integer> calculationsArray = new ArrayList<Integer>();
int calculations = 0;
int j = 0;
while (j < array2.size()) {
for (int i = 0; i < array1.size(); i++) {
calculations = ((array1.get(i) + array2.get(j)) % 10);
calculationsArray.add(calculations);
}
j++;
}
I am a newbie to programming. I am trying to create a program that would display an array in reverse. Plus also find the even and odd numbers of an array,sum the count and also display the even and odd numbers. The code works but the problem is that it also reverses the even and odd arrays and it shows this weird zero in those arrays. What am I doing wrong?
Please also provide explanation. Thanks!
import java.util.Arrays;
public class ArrayTest {
public static void main(String[] args)
{
int[] array = {1,2,3,4,5,6,7,8,9,10,11,12,13};
for ( int i=0; i<array.length/2; i++ )
{
int temp = array[i];
array[i] = array[array.length-(1+i)];
array[array.length-(1+i)] = temp;
}
System.out.println("Array after reverse: \n" + Arrays.toString(array));
int even=0;
int odd=0;
int[] Even = new int[13];
int[] Odd = new int[13];
for ( int i=0; i<array.length; i++)
{
if (array[i] % 2 == 0)
{
Even[i] = array[i];
even++;
}
else
{
Odd[i] = array[i];
odd++;
}
}
System.out.println("Even: "+even+" ");
System.out.println(Arrays.toString(Even));
System.out.println("Odd: "+odd+" ");
System.out.println(Arrays.toString(Odd));
}
}
The output is:
Array after reverse:
[13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Even: 6
[0, 12, 0, 10, 0, 8, 0, 6, 0, 4, 0, 2, 0]
Odd: 7
[13, 0, 11, 0, 9, 0, 7, 0, 5, 0, 3, 0, 1]
You need to correct your logic
int[] Even = new int[(array.length/2)+1];
int[] Odd = new int[(array.length/2)+1];
for ( int i=0; i<array.length; i++)
{
if (array[i] % 2 == 0)
{
Even[even] = array[i];
even++;
}
else
{
Odd[odd] = array[i];
odd++;
}
}
As per you code, you are initializing array of size 13 for odd and even, which is not correct.
int[] Even = new int[13];
int[] Odd = new int[13];
So, by default, Even and Odd array will be initialized by 0 value. Then, you are setting value as per main array, which a size of 13 on alternate basis (even/odd).
==Updated==
Since, you don't want Even and Odd array in reverse order. Then, you can move the code up.
>>Demo<<
You faced 2 problems (I guess so)
The odd and even arrays are also in reverse order
Reason: The first For loop reverses the 'array' and stores the results in array itself. So, the next time when you try working with 'array' to find odd/even numbers, you are actually working with the reversed array.
Solution: You can assign the original array to a backup array and use that backup array to find odd and even nos.
Unnecessary zeros:
Reason: In your second for loop you used odd[i]=array[i] which seems to be a logical error in your code. Consider the case:
value of i : 0 1 2 3 4 5 ... 12
value of array[i]: 1 2 3 4 5 6 ... 13
value of odd[i] : 1 0 3 0 5 0 ... 13
value of even[i] : 0 2 0 4 0 6 ... 0
This means, the control inside for loop is made to flow either to if{} block or the else{} block and not the both. So, when if(condition) is satisfied, then even[i] array will be updated. But meanwhile what happens to the odd[i] array? It retains the inital value '0'. That's it!
I hope the following code helps you:
import java.util.Arrays;
public class A
{
public static void main(String[] args)
{
int[] array = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int[] arr2 = new int[array.length]; // backup array
arr2=Arrays.copyOfRange(array,0,array.length);
for ( int i=0; i<arr2.length/2; i++ )
{
int temp = arr2[i];
arr2[i] = arr2[arr2.length-(1+i)];
arr2[arr2.length-(1+i)] = temp;
}
System.out.println("Array after reverse: \n" + Arrays.toString(arr2));
int even=0;
int odd=0;
int[] Even = new int[13];
int[] Odd = new int[13];
for ( int i=0; i<array.length; i++)
{
if (array[i] % 2 == 0)
{
Even[even] = array[i];
even++;
}
else
{
Odd[odd] = array[i];
odd++;
}
}
Even=Arrays.copyOfRange(Even,0,even);
Odd=Arrays.copyOfRange(Odd,0,odd);
System.out.println("Even: "+even+" ");
System.out.println(Arrays.toString(Even));
System.out.println("Odd: "+odd+" ");
System.out.println(Arrays.toString(Odd));
}
}
Note: I have used Arrays.copyOfRange(array,start,end) function to copy a certain part of the array from start to end-1 position.
Output:
Array after reverse:
[13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Even: 6
[2, 4, 6, 8, 10, 12]
Odd: 7
[1, 3, 5, 7, 9, 11, 13]
Hope this helps :)
--Mathan Madhav
You select even and odd numbers from reversed array.
You use wrong index for even and odd arrays.
If you don't want to see zeros in output, use print in for statement. Another solution - firstly count odd and even numbers and create arrays with exact size.
import java.util.Arrays;
public class ArrayTest {
public static void main(String[] args)
{
int[] array = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int even=0;
int odd=0;
int[] Even = new int[13];
int[] Odd = new int[13];
for ( int i=0; i<array.length; i++)
{
if (array[i] % 2 == 0)
{
Even[even++] = array[i];
}
else
{
Odd[odd++] = array[i];
}
}
for ( int i=0; i<array.length/2; i++ )
{
int temp = array[i];
array[i] = array[array.length-(1+i)];
array[array.length-(1+i)] = temp;
}
System.out.println("Array after reverse: \n" + Arrays.toString(array));
System.out.println("Even: "+even+" ");
System.out.println(Arrays.toString(Even));
System.out.println("Odd: "+odd+" ");
System.out.println(Arrays.toString(Odd));
}
}
My Title may sound a bit silly, so here is the explanation:
I have an Array
int[] a = new int[] { 1, 2, 3, 4, 5, 6 };
And the output in the End should be like
123321
I already managed to output 123456 and 654321 but I can´t figure out how to output 123321 :(
I am only allowed to use one outer loop and in this loop it is allowed to have a new loop.
I tried different things but I didn´t manage to get it running, can you guys give me a hint please?
What I was thinking about in the beginning:
while(x <=2){
System.out.print(a[x]);
x++;
if(x==2){
while(x>0){
System.out.print(a[x]);
x--;
}
}
}
You should specify what conditions must the output meet.
For iterating to half of the array and then back to the beginning you don't need any inner loop. Try this:
int[] a = new int[] { 1, 2, 3, 4, 5, 6 };
for (int i = 0; i < a.length; ++i){
if (i<a.length/2) System.out.print(a[i]);
else System.out.print(a[a.length-i-1]);
}
The problem with your code is that you go to an infinite loop :
while(x <=2){
System.out.print(a[x]);
x++; // <-- you increment x until it reaches 2
if(x==2){ // <-- x equals to 2
while(x>0){
System.out.print(a[x]);
x--; // <-- you decrement x until it reaches 0
}
} // <-- Wow, 0 <= 2 so re-execute the while loop
You can implement it like this. When you'll go until the middle of the array, the inner loop will get executed until it prints the elements from the current index to 0.
int[] a = new int[] { 1, 2, 3, 4, 5, 6 };
int x = 0;
while(x != a.length/2){ // <-- loop until the middle of the array
System.out.print(a[x]);
x++;
if(x == a.length/2){ // <-- when we reach the middle execute the inner loop
for(int i = x -1; i >= 0; i--) // <-- print the elements of the array from current index to 0
System.out.print(a[i]);
}
}
Just other way with Collections:
List<Integer> first = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5, 6 ));
int half = first.size()/2;
List<Integer> out = new ArrayList<Integer>( first.subList(0, half) );
Collections.reverse( first.subList( 0, half ) );
out.addAll( first.subList( 0, half ) );
System.out.println(out); // [1, 2, 3, 3, 2, 1]