frequency of items in int[] as opposed to List<Integer>? - java

I'm trying to figure out how to get the frequency of items within a list. When I approach this problem I typically, in the past, did:
int occurrences = Collections.frequency(list, 0);
It works when my list is a List<Integer> list. Is there a way to do this if I'm using int[] list? When I try collections, my list gets converted and then my code breaks. I can convert my code if needed, but was wondering, if there was a way to get the frequency from int[] instead.

You can (1) write your own linear-time frequency method, or (2) convert to an array of boxed int types and use Arrays.asList with Collections.frequency.
int[] arr = {1, 2, 3};
Integer[] boxedArr = new Integer[arr.length];
for(int i = 0; i < arr.length; i++)
boxedArr[i] = arr[i];
System.out.println(Collections.frequency(Arrays.asList(boxedArr), 1));

You could create a List from the int[], but otherwise, you just have to write your own.
int[] l = //your data;
List<Integer> list = new List<Integer>();
for(int i : l)
list.add(i);
int o = Collections.frequency(list, 0);
Or Arrays.asList(l); to make it shorter.

int occurrences = Collections.frequency(Arrays.asList(list), 0);
Or if you are against converting it to a list:
int occurrences = 0;
for (int i = 0; i < list.length; i++)
{
if(list[i] == X) // X being your number to check
occurrences++;
}

You can do this way as well.
List<Integer> intList = Arrays.asList(new Integer [] {
2, 3, 4, 5, 6,
2, 3, 4, 5,
2, 3, 4,
2, 3,
2
});
System.out.println(" count " + Collections.frequency(intList, 6));

Related

Creating an array that has duplicated elements of an original array without using ArrayList?

I have an array in Java.
// original array
int[] arr = {1, 2, 3, 4};
How do I get another array that has the duplicated elements of the original array next to the original elements n number of times like so...
// n = 2
int[] arr2 = {1, 1, 2, 2, 3, 3, 4, 4};
// n = 3
int[] arr3 = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};
You can use streams :)
int[] result = Arrays.stream(arr)
.flatMap(x -> IntStream.range(0, n).map(e -> x))
.toArray();
Because this looks like a homework requirement, you are not likely to be allowed to use streams, so here's a solution with for loops:
int[] result = new int[arr.length * n];
for (int i = 0 ; i < result.length ; i++) {
result[i] = arr[i / n];
}
If using loops is fine,
int origArr = {1,2,3,4};
int[] newArr = new int[n*origArr.length]; // default initialized with zero in Java
int i=0; // loop over new array
int j=0; // loop over original array
while(j<origArr.length){
for(int k=0; k<n; k++){
newArr[i] = origArr[j];
i++;
}
j++;
}

Sort array in a specific order in java

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.

Adding indexes of a list to a new list

Given an array of ints length 3, return an array with the elements "rotated left" so {1, 2, 3} yields {2, 3, 1}.
My first attempt(I had done this in python easily so I had the same idea).
public int[] rotateLeft3(int[] nums) {
return [nums[1:] + nums[0]];
}
But as you expected I got an error, so I immediately wrote this.
public int[] rotateLeft3(int[] nums) {
int[] answer = new int[3];
answer[0] = nums[1];
answer[1] = nums[2];
answer[2] = nums[0];
return answer;
}
I feel like this is possibly the most inefficient way to answer the question, but I only did this because it says of length 3. My previous code works in python for all sizes. So I was wondering how would my previous code be written in java?
with collection:
Java - Rotating array
use Integer nums[];
if not, iterate and convert your int[] to Integer[]
or use http://commons.apache.org/lang/ :
Integer[] array2= ArrayUtils.toObject(nums);
Collections.rotate(Arrays.asList(nums), -1);
convert to array : .toArray();
Maybe...
public int[] rotateLeft(int size, int[] array) {
int temp = int[size-1]; // We're just gonna save the las value.
for (int i = size-1; i == 0; i--) {
array[i] = array[i-1]; // We move them all 1 to the left.
}
array[0] = temp; // This is why we saved the las value.
return array;
Hope it helped you!
You can do that easily with System.arraycopy:
int[] arr = { 1, 2, 3};
int[] rotated = new int[arr.length];
System.arraycopy(arr, 1, rotated, 0, arr.length - 1);
rotated[arr.length-1] = arr[0];

How can I add new integers to replace the old integers to my already-existing Array?

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.

How to add an element to Array and shift indexes?

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);
}
}
}

Categories