Related
I ran into an issue I can't seem to solve, and all the searches I do are not completely relevant to the issue I am having, and trying to implement those things to solve my issue still doesn't work. I've spent an hour trying to find another question or post somewhere that would help but can't seem to find any specific to my issue (unless Google just doesn't want to work today).
I am trying to create a method that returns an array of all of the odd numbers between 1 and n, say in this example 1 to 255.
I tried the following (here is the method currently):
import java.util.Arrays;
public class BasicJava: {
public Integer[] arrayOfOdds() {
int n = 255;
Integer[] odds = new Integer[(n+1)/2];
for(int i = 1; i < n+1; i+=2) {
odds[i/2] = i;
}
return odds;
}
}
Main Method:
import java.util.Arrays;
public class BasicJavaTest {
public static void main(String[] args) {
BasicJava test = new BasicJava();
System.out.println(Arrays.toString(test.arrayOfOdds()));
}
}
I tried using an array to do the same thing before switching to using an ArrayList (I like other data structures more than I do arrays) and converting to an array and got the same output (I will just put part of the output array to not use too much space):
[0, 1, 0, 3, 0, 5, 0, 7, 0, 9, 0, 11, 0, 13, 0, 15, 0, 17, 0, 19, 0, 21, 0, 23, 0, 25, 0, 27, 0, 29, 0, 31, 0]
What do I need to resolve this issue?
If I just wanted to print all of the odds between 1 and N using the same for loop and if statement, I would get the correct output.
Thank you
You can do this is linear time complexity and without using an ArrayList.
Your final output will always have n/2 elements so your array size can be fixed at the same. In the next step you can simply populate the values in your array.
FYR code:
int[] arr = new int[((n+1)/2)];
for(int i = 0, e = 1; i < arr.length; e += 2, i++) {
arr[i] = e;
}
You can use IntStream like this.
static int[] arrayOfOdds() {
return IntStream.iterate(1, i -> i + 2)
.takeWhile(i -> i < 256)
.toArray();
}
public static void main(String[] args) {
System.out.println(Arrays.toString(arrayOfOdds()));
}
output:
[1, 3, 5, 7, 9, 11, 13, 15, ... , 251, 253, 255]
int N = 255;
Integer[] array = new Integer[(N+1)/2];
for (int j = 1; j < N+1; j+=2) {
array[j/2] = j;
}
System.out.println(Arrays.toString(array));
You don't need to add condition to check for each integer.
Here is a simple trick to create odds number:
Start with 1 and increase 2 for next element. ( 1,3,5...)
public static void main(String[] args) {
List<Integer> arr = getOddList(255);
System.out.print(arr);
}
private static List<Integer> getOddList(int n) {
List<Integer> nums = new ArrayList<>();
for (int i = 1; i < n; i = i + 2) {
nums.add(i);
}
return nums;
}
//Output [1, 3, 5, 7, 9, 11...
For some reason, my solution is not complete. I got 80/100 from hidden spec tests.
What's wrong with my solution? There is probably a certain use case that I'm not thinking of.
How would space/time complexity change using an ArrayList instead of an array?
Is there a better way to tackle this problem?
My current solution handles:
an empty input array
negative/positive integer values in the input array
duplicates in the input array
sorted/unsorted input array
Instructions:
Write a Java method removeLastOccurrence(int x, int[] arr), which removes the last occurrence of a given integer element x from a given array of integer elements arr.
The method should return a new array containing all elements in the given array arr except for the last occurrence of element x. The remaining elements should appear in the same order in the input and the returned arrays.
The code on the right shows you a code framework in which the implementation of one static method is still missing. Provide this implementation and check that it is correct by either writing more tests yourself or using the provided tests and specification tests.
My code:
class RemoveLastOccurrenceArray {
/**
* Takes the array and the last occurring element x,
* shifting the rest of the elements left. I.e.
* [1, 4, 7, 9], with x=7 would result in:
* [1, 4, 9].
*
* #param x the entry to remove from the array
* #param arr to remove an entry from
* #return the updated array, without the last occurrence of x
*/
public static int[] removeLastOccurrence(int x, int[] arr) {
// if arr == null return null;
if (arr == null || arr.length == 0) return arr;
// return a new array which will be size arr.legnth-1
int[] res = new int[arr.length - 1];
// introduce an int tracker which keep tracks of the index of the last occurrence of x
int last_index = -1;
// traverse through the array to get the index of the last occurrence
for (int i = 0; i < arr.length; i++) if (arr[i] == x) last_index = i;
int i = 0, j = 0;
// copying elements of array from the old one to the new one except last_index
while (i < arr.length) {
if (i == last_index) {
if (i++ < res.length) {
res[j++] = arr[i++];
}
} else res[j++] = arr[i++];
}
// if we pass in x which is not in the array just return the original array
if (last_index == -1) return arr;
// are there duplicates in the array? - WORKS
// does the array have negative numbers? - WORKS
// Is the array sorted/unsorted - WORKS
return res;
}
}
Passing Unit Tests
import static org.junit.Assert.*;
import org.junit.*;
public class RemoveLastOccurrenceArrayTest {
#Test
public void testRemoveArray_Empty() {
int[] array = new int[0];
assertEquals(0, RemoveLastOccurrenceArray.removeLastOccurrence(5, array).length);
}
#Test
public void testFirstSimple() {
int[] input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] result = {2, 3, 4, 5, 6, 7, 8, 9, 10};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(1, input));
}
#Test
public void testLastSimple() {
int[] input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] result = {1, 2, 3, 4, 5, 6, 7, 8, 9};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(10, input));
}
#Test
public void testPositiveInMiddleDuplicate() {
int[] input = {1, 2, 3, 3, 4, 5};
int[] result = {1, 2, 3, 4, 5};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(3, input));
}
#Test
public void testNegativeFirst() {
int[] input = {-3, -1, 2, -3, 3, 4, 5, 0};
int[] result = {-3, -1, 2, 3, 4, 5, 0};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(-3, input));
}
#Test
public void testLasttoRemove() {
int[] input = {1, 4, 7, 9};
int[] result = {1, 4, 7};
assertArrayEquals(result, RemoveLastOccurrenceArray.removeLastOccurrence(9, input));
}
}
Why not try iterating backwards?
for(int i = arr.length; i => 0; i--)
{
if (arr[i] == x)
{
return ArrayUtils.remove(arr, i)
}
}
Then, after you find the index, you can use the Apache Commons ArrayUtils remove command to remove the item at the
This is the answer thank you very much!
Also, if there is no x to find, yours crashes ... mine doesn't. Maybe that's where the twenty marks went?
I was already checking for this but too late in my code. So I just had to move
if (last_index == -1) return arr; before the while loop, and I got 100/100 scores.
Would your prof prefer this? Just another way, and I don't think any more efficient than your answer. But maybe they like to see the java classes used ...
Does your prof not tell you where you lost marks? You can't improve if they don't tell you what they were expecting for full marks. But here was another way ... again, no better in my opinion, and not worth twenty more marks. I'll just post it, because it is 'another way.'
public int[] removeLastOccurrence2(int x, int[] arr) {
// if arr == null return null;
if (arr == null || arr.length == 0) return arr;
// Fill an ArrayList with your initial array ...
java.util.List list = new java.util.ArrayList(arr.length);
for (int i=0; i<arr.length; i++) {
list.add(arr[i]);
}
int[] res;
// Now ... use ArrayList methods to do the work.
// Also, if there is no x to find, yours crashes ... mine doesn't.
// Maybe that's where the twenty marks went?
if ( list.lastIndexOf(x) != -1 ) { // This screens for no x found at all ...
list.remove( list.lastIndexOf(x) ); // Done!
// Make a new array to return.
res = new int[list.size()];
for (int i=0; i<list.size(); i++) {
res[i] = (int) list.get(i);
}
} else {
// No 'x' found, so just return the original array.
res = arr;
}
return res;
}
How about reverse(), remove(), reverse()? Sorry if this is already mentioned in here somewhere and I missed it.
I am trying to sort an array to a specific order. So for example, I have this array
{6,1,1,5,6,1,5,4,6}
and I want them to be sorted to this order
{4,1,6,5}
expected new array would be
{4,1,1,1,6,6,6,6,5}
My idea is this,
public class Sort {
static int[] list = { 6, 1, 1, 5, 6, 1, 6, 4, 6 };
static int[] sorted = { 4, 1, 6, 5 };
static int[] newList = new int[list.length];
static int count = 0;
public static void main(String[] args) {
for (int i = 0; i < sorted.length; i++) {
for (int j = 0; j < list.length; j++) {
if (list[j] != sorted[i])
continue;
else
newList[count++] = sorted[i];
}
}
}
}
It works fine, however, I am not sure if this is the fastest and easier way to do this regarding speed and memory cause the list could have too many numbers.
You can use java built-in sort algorithm with a customized comparator.
public static void main(String[] args) {
Integer[] list = { 6, 1, 1, 5, 6, 1, 6, 4, 6 };
int[] sorted = { 4, 1, 6, 5 };
Map<Integer, Integer> order = new HashMap<>();
for (int i = 0; i < sorted.length; i++)
order.put(sorted[i], i);
Arrays.sort(list, (a ,b) -> order.get(a) - order.get(b));
System.out.println(Arrays.toString(list));
}
The output is [4, 1, 1, 1, 6, 6, 6, 6, 5].
If you
know the possible elements in advance
and they are relatively small numbers
you can simply count them:
int stats[]=new int[7]; // "largest possible element"+1
for(int i=0;i<list.length;i++)
stats[list[i]]++;
and then reconstruct the ordered list:
int idx=0;
for(int i=0;i<sorted.length;i++){
int val=sorted[i];
for(int j=stats[val];j>0;j--)
newlist[idx++]=val;
The two snippets in total have "2*list.length" steps, which is probably faster than your original "sorted.length*list.length" loop-pair.
As you have not described the actual use-case, it is hard to tell more. For example if you have these numbers only, you probably do not need the ordered result to be an actual list. However if these numbers are just part of an object, this build-a-statistics approach is not applicable.
Here is the program task:
Write a method called collapse that accepts an array of integers as a parameter and returns a new array containing the result of replacing each pair of integers with the sum of that pair.
For example, if an array called list stores the values
{7, 2, 8, 9, 4, 13, 7, 1, 9, 10}
then the call of collapse(list) should return a new array containing:
{9, 17, 17, 8, 19}.
The first pair from the original list is collapsed into 9 (7 + 2), the second pair is collapsed into 17 (8 + 9), and so on. If the list stores an odd number of elements, the final element is not collapsed.
For example, if the list had been {1, 2, 3, 4, 5}, then the call would return {3, 7, 5}. Your method should not change the array that is passed as a parameter.
Here is my currently-written program:
public static int[] collapse(int[] a1) {
int newArrayLength = a1.length / 2;
int[] collapsed = new int[newArrayLength];
int firstTwoSums = 0;
for (int i = 0; i < a1.length-1; i++) {
firstTwoSums = a1[i] + a1[i+1];
collapsed[collapsed.length-1] = firstTwoSums;
}
return collapsed;
}
I pass in an array of {7, 2, 8, 9, 4, 13, 7, 1, 9, 10} and I want to replace this array with {9, 17, 17, 8, 19}.
Note:{9, 17, 17, 8, 19} will be obtained through the for-loop that I have written.
Currently, I am having trouble with adding the integers I obtained to my "collapsed" array. It'd be a great help if you could help me or at least give me some guidance on how to do this.
Thanks in advance!
First you have to understand what is going on.
You have an array of certain size where size can either be even or odd. This is important because you are using a1.length/2 to set the size for new array, so you will also have to check for odd and even values to set the size right else it won't work for odd sized arrays. Try a few cases for better understanding.
Here's a way of doing it.
public static int[] collapseThis(int[] array) {
int size = 0;
if(isEven(array.length))
size = array.length/2;
else
size = array.length/2+1;
int[] collapsedArray = new int[size];
for(int i=0, j=0; j<=size-1; i++, j++) {
if(j==size-1 && !isEven(array.length)) {
collapsedArray[j] = array[2*i];
}
else {
collapsedArray[j] = array[2*i]+array[2*i+1];
}
}
return collapsedArray;
}
private static boolean isEven(int num) {
return (num % 2 == 0);
}
Using
collapsed[collapsed.length-1] = firstTwoSums;
The sum of your numbers will be always be put in the same index of the collapsed array, because collapsed.length - 1 is a constant value.
Try creating a new variable starting at zero, that can be incremented each time you add a sum to collapsed. For instance,
int j = 0;
for(...) {
...
collapsed[j++] = firstTwoSums;
}
I think this is a convenient answer.
public static void main(String[] args){
int[] numbers = {1,2,3,4,5};
int[] newList = collapse(numbers);
System.out.println(Arrays.toString(newList));
}
public static int[] collapse(int[] data){
int[] newList = new int[(data.length + 1)/2];
int count = 0;
for (int i = 0; i < (data.length / 2); i++){
newList[i] = data[count] + data[count + 1];
System.out.println(newList[i]);
count = count + 2;
}
if (data.length % 2 == 1){
newList[(data.length / 2)] = data[data.length - 1];
}
return newList;
}
i would combine the cases for the array with either odd or even elements together as below:
public static int[] collapse(int[] a1) {
int[] res = new int[a1.length/2 + a1.length % 2];
for (int i = 0; i < a1.length; i++)
res[i/2] += a1[i];
return res;
}
public static int[] collapse(int[] a1) {
int newArrayLength = a1.length / 2;
int[] collapsed;
if(a1.length%2 == 0)
{
collapsed = new int[newArrayLength];
}
else
{
collapsed = new int[newArrayLength+1];
collapsed[newArrayLength] = a1[a1.length-1];
}
int firstTwoSums = 0;
for (int i = 0; i < newArrayLength; i++) {
firstTwoSums = a1[i*2] + a1[i*2+1];
collapsed[i] = firstTwoSums;
}
return collapsed;
}
I modified your code and you may try it first.
I need to add an element to Array specifying position and value.
For example, I have Array
int []a = {1, 2, 3, 4, 5, 6};
after applying addPos(int 4, int 87) it should be
int []a = {1, 2, 3, 4, 87, 5};
I understand that here should be a shift of Array's indexes, but don't see how to implement it in code.
The most simple way of doing this is to use an ArrayList<Integer> and use the add(int, T) method.
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
// Now, we will insert the number
list.add(4, 87);
This should do the trick:
public static int[] addPos(int[] a, int pos, int num) {
int[] result = new int[a.length];
for(int i = 0; i < pos; i++)
result[i] = a[i];
result[pos] = num;
for(int i = pos + 1; i < a.length; i++)
result[i] = a[i - 1];
return result;
}
Where a is the original array, pos is the position of insertion, and num is the number to be inserted.
Jrad solution is good but I don't like that he doesn't use array copy. Internally System.arraycopy() does a native call so you will a get faster results.
public static int[] addPos(int[] a, int index, int num) {
int[] result = new int[a.length];
System.arraycopy(a, 0, result, 0, index);
System.arraycopy(a, index, result, index + 1, a.length - index - 1);
result[index] = num;
return result;
}
You must make a new array, use System.arraycopy to copy the prefix and suffix, and set that one slot to the new value.
If you prefer to use Apache Commons instead of reinventing the wheel, the current approach is this:
a = ArrayUtils.insert(4, a, 87);
It used to be ArrayUtils.add(...) but that was deprecated a while ago. More info here: 1
I smell homework, so probably an ArrayList won't be allowed (?)
Instead of looking for a way to "shift indexes", maybe just build a new array:
int[] b = new int[a.length +1];
Then
copy indexes form array a counting from zero up to insert position
...
...
//edit: copy values of course, not indexes
Unless I'm missing something, the question is not about increasing the array size. In the example the array size remains the same. (Like a bit shift.)
In this case, there is really no reason to create a new array or to copy it. This should do the trick:
static void addPos(int[] array, int pos, int value) {
// initially set to value parameter so the first iteration, the value is replaced by it
int prevValue = value;
// Shift all elements to the right, starting at pos
for (int i = pos; i < array.length; i++) {
int tmp = prevValue;
prevValue = array[i];
array[i] = tmp;
}
}
int[] a = {1, 2, 3, 4, 5, 6};
addPos(a, 4, 87);
// output: {1, 2, 3, 4, 87, 5}
Here is a quasi-oneliner that does it:
String[] prependedArray = new ArrayList<String>() {
{
add("newElement");
addAll(Arrays.asList(originalArray));
}
}.toArray(new String[0]);
org.apache.commons.lang3.ArrayUtils#add(T[], int, T) is deprecated in newest commons lang3, you can use org.apache.commons.lang3.ArrayUtils#insert(int, T[], T...) instead.
Deprecated this method has been superseded by insert(int, T[], T...) and may be removed in a future release. Please note the handling of null input arrays differs in the new method: inserting X into a null array results in null not X
Sample code:
Assert.assertArrayEquals
(org.apache.commons.lang3.ArrayUtils.insert
(4, new int[]{1, 2, 3, 4, 5, 6}, 87), new int[]{1, 2, 3, 4, 87, 5, 6});
Have a look at commons. It uses arrayCopy(), but has nicer syntax. To those answering with the element-by-element code: if this isn't homework, that's trivial and the interesting answer is the one that promotes reuse. To those who propose lists: probably readers know about that too and performance issues should be mentioned.
int[] b = new int[a.length +1];
System.arraycopy(a,0,b,0,4);
//System.arraycopy(srcArray, srcPosition, destnArray, destnPosition, length)
b[4]=87;
System.arraycopy(a,4,b,5,2);
b array would be created as {1, 2, 3, 4, 87, 5,6};
Try this
public static int [] insertArry (int inputArray[], int index, int value){
for(int i=0; i< inputArray.length-1; i++) {
if (i == index){
for (int j = inputArray.length-1; j >= index; j-- ){
inputArray[j]= inputArray[j-1];
}
inputArray[index]=value;
}
}
return inputArray;
}
System.arraycopy is more performant but tricky to get right due to indexes calculations. Better stick with jrad answer or ArrayList if you don't have performance requirements.
public static int[] insert(
int[] array, int elementToInsert, int index) {
int[] result = new int[array.length + 1];
// copies first part of the array from the start up until the index
System.arraycopy(
array /* src */,
0 /* srcPos */,
result /* dest */,
0 /* destPos */,
index /* length */);
// copies second part from the index up until the end shifting by 1 to the right
System.arraycopy(
array /* src */,
index /* srcPos */,
result /* dest */,
index + 1 /* destPos */,
array.length - index /* length */);
result[index] = elementToInsert;
return result;
}
And JUnit4 test to check it works as expected.
#Test
public void shouldInsertCorrectly() {
Assert.assertArrayEquals(
new int[]{1, 2, 3}, insert(new int[]{1, 3}, 2, 1));
Assert.assertArrayEquals(
new int[]{1}, insert(new int[]{}, 1, 0));
Assert.assertArrayEquals(
new int[]{1, 2, 3}, insert(new int[]{2, 3}, 1, 0));
Assert.assertArrayEquals(
new int[]{1, 2, 3}, insert(new int[]{1, 2}, 3, 2));
}
public class HelloWorld{
public static void main(String[] args){
int[] LA = {1,2,4,5};
int k = 2;
int item = 3;
int j = LA.length;
int[] LA_NEW = new int[LA.length+1];
while(j >k){
LA_NEW[j] = LA[j-1];
j = j-1;
}
LA_NEW[k] = item;
for(int i = 0;i<k;i++){
LA_NEW[i] = LA[i];
}
for(int i : LA_NEW){
System.out.println(i);
}
}
}
Following code will insert the element at specified position and shift the existing elements to move next to new element.
public class InsertNumInArray {
public static void main(String[] args) {
int[] inputArray = new int[] { 10, 20, 30, 40 };
int inputArraylength = inputArray.length;
int tempArrayLength = inputArraylength + 1;
int num = 50, position = 2;
int[] tempArray = new int[tempArrayLength];
for (int i = 0; i < tempArrayLength; i++) {
if (i != position && i < position)
tempArray[i] = inputArray[i];
else if (i == position)
tempArray[i] = num;
else
tempArray[i] = inputArray[i-1];
}
inputArray = tempArray;
for (int number : inputArray) {
System.out.println("Number is: " + number);
}
}
}