How to create an array from a pre-existing array? - java

New to java and am trying to create a program/method that will take an int array, and return another int array but it replaces the values of the indexes with the value of the elements. (Example {2,1,3} will return {0,0,1,2,2,2}
public static void main(String[] args) {
int[] pracArray = {2, 1, 3};
int sum = 0;
for (int i = 0; i < pracArray.length; i++)
{
sum = sum + pracArray[i];
}
System.out.println("Amount of array indexes: " + sum);
int[] newArray = new int[sum];
System.out.println(Arrays.toString(pracArray));
for (int i = 0; i < pracArray.length; i++)
{
for (int j = 0; j < pracArray[i]; j++)
{
newArray[j] = i;
}
}
System.out.println(Arrays.toString(newArray));
}
}
Currently I am getting [2,2,2,0,0,0]. I have tried changing the how many times each for loop iterates with no avail. I have also tried to make the elements of newArray equal to a counter ( int count = 0; and having count++ in the for loop) since the values of the new array will always be 0 - however many runs.

Given the length of your array is 3, your outer 'i' loop is iterating through the values 0,1,2. That means your inner 'j' loop never writes to index 3,4,5 (hence why they are 0 in the output), and why the first 3 indexes are set to '2' (2 is the last indexed processed in the 'i' loop). Try this instead...
int h = 0;
for (int i = 0; i < pracArray.length; i++)
{
for (int j = 0; j < pracArray[i]; j++)
{
newArray[h] = i;
h++;
}
}

Related

Sorting an array by number of digits in each element from largest to smallest using loops java

I'm trying to sort an array by the number of digits in each element from largest to smallest. This technically works but it seems to sort the array by value as well. For example, instead of printing out 1234 700 234 80 52, it should print 1234 234 700 52 80 as 234 is before 700 in the original array.
public class Sort {
public static void main(String[] args) {
//Initialize array
int [] arr = new int [] {52, 234, 80, 700, 1234};
int temp = 0;
//Displaying elements of original array
System.out.println("Elements of original array: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
//Sort the array in descending order
//Math function is used to find length of each element
for (int i = 0; i < arr.length; i++) {
for (int j = i+1; j < arr.length; j++) {
if(Math.log10(arr[i]) + 1 < Math.log10(arr[j]) + 1) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
System.out.println();
//Displaying elements of array after sorting
System.out.println("Elements of array sorted in descending order: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
The easiest way to find the length of the number is to convert it into a String and then call the method length on it.
int number = 123;
String numberAsString = String.valueOf(number);
int length = numberAsString.length(); // returns 3
But you also could do it by division. The following method takes a number and divides by multiples of 10.
divide by 1 (we have at least a length of 1)
division by 10 > 0 (we have at least a length of 2)
division by 100 > 0 (we have at least a length of 3)
...
the variable i is used as dividend and the variable j is used as counter. j counts the length of the number.
As soon as number / i equals zero we return the counter value.
public int lengthOfNumber(int number) {
if (number == 0) {
return 1;
}
for (int i = 1, j = 0; ; i *= 10, j++) {
if (number / i == 0) {
return j;
}
}
}
There are multiple ways to sort the array. Here are some examples (I used the string version for comparing the values).
Use nested for-loop
public void sortArray(int[] array) {
for (int i = 0; i < array.length; i++) {
int swapIndex = -1;
int maxLength = String.valueOf(array[i]).length();
for(int j = i + 1; j < array.length; j++) {
int length2 = String.valueOf(array[j]).length();
if (maxLength < length2) {
maxLength = length2;
swapIndex = j;
}
}
if (swapIndex > -1) {
int temp = array[i];
array[i] = array[swapIndex];
array[swapIndex] = temp;
}
}
}
I used a variable swapIndex which is initialized with -1. This way we can avoid unnecessary array operations.
We take the first element in the outer for-loop and go through the rest of the array in the inner for-loop. we only save a new swapIndex if there is a number in the rest of the array with a higher length. if there is no number with a higher length, swapIndex remains -1. We do a possible swap only in the outer for-loop if necessary (if swapIndex was set).
Using Arrays.sort()
If you want to use Arrays.sort you need to convert your array from primitive type int to Integer.
public void sortArray(Integer[] array) {
Arrays.sort(array, (o1, o2) -> {
Integer length1 = String.valueOf(o1).length();
Integer length2 = String.valueOf(o2).length();
return length2.compareTo(length1);
});
}
Using a recursive method
public void sortArray(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
String current = String.valueOf(array[i]);
String next = String.valueOf(array[i + 1]);
if (current.length() < next.length()) {
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
// here you do a recursive call
sortArray(array);
}
}
}

Why does my sorting algorithm fails after the 3rd iteration of the for loop?

/*
This is the prompt:
starts with an unsorted array a
output: sorted array a.
Find the smallest element in the array a[1: n], call it a[j].
Swap it with a[0], if it is smaller than a[0].
Repeat this process with index 1, 2, ... until the who array is sorted.
*/
public class assing2 {
public static void main(String args[])
{
//array of ints
int[] A = new int[] {33, 20, 8, 11, 5};
int min_id = 0;
int temp_i = 0;
//int temp_max = 0;
for (int i = 0; i < A.length; i++)
{
min_id = i;
temp_i = A[i];
for (int j = 1; j < A.length; j++)
{
if (A[min_id] > A[j])
{
min_id = j;
}
}
A[i] = A[min_id];
A[min_id] = temp_i;
}
System.out.println("Sorted array");
for ( int i = 0; i < A.length; i++)
{
System.out.println(A[i]);
}
}
}
This is the output
Sorted array
5
20
11
33
8
When I run it in the debugger i can see that the first 2 iterations of the first for loop looks like its working but after that it unsorted what was sorted.
Whats is wrong with my logic?
for (int j = 1; j < A.length; j++)
is wrong. You should check only the elements after i, since the elements before i are sorted by the previous iterations. So it should be
for(int j = i+1; j < A.length; j++)
Also in the first loop, you dont need to do anything about the last element. You can change the stop condition to i<A.length-1

Remove duplicates in array, zero padding at end

I have a task, to remove duplicates in array, what by "remove" means to shift elements down by 1, and making the last element equal to 0,
so if I have int[] array = {1, 1, 2, 2, 3, 2}; output should be like:
1, 2, 3, 0, 0, 0
I tried this logic:
public class ArrayDuplicates {
public static void main(String[] args) {
int[] array = {1, 1, 2, 2, 3, 2};
System.out.println(Arrays.toString(deleteArrayDuplicates(array)));
}
public static int[] deleteArrayDuplicates(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] == array[j]) { //this is for comparing elements
for (; i > 0; i--) {
array[j + 1] = array[j]; //this is for shifting
}
array[array.length - 1] = 0; //making last element equal to "0"
}
}
}
return array;
}
}
But it doesn't work.. Is anyone familiar with a right solution?
I appreciate your assistance and attention very much.
Your Code:
In short, the approach you have chosen calls for a third loop variable, k, to represent the index that is currently being shifted left by 1 position.
i - the current unique item's position
j - the current position being tested for equality with unique item at i
k - the current position being shifted left due to erasure at j
Suggestion:
A more efficient approach would be to eliminate the repetitive left shifting which occurs each time a duplicate is found and instead keep track of an offset based on the number of duplicates found:
private static int[] deleteArrayDuplicates(int[] array) {
int dupes = 0; // total duplicates
// i - the current unique item's position
for (int i = 0; i < array.length - 1 - dupes; i++) {
int idupes = 0; // duplicates for current value of i
// j - the current position being tested for equality with unique item at i
for (int j = i + 1; j < array.length - dupes; j++) {
if (array[i] == array[j]) {
idupes++;
dupes++;
} else if(idupes > 0){
array[j-idupes] = array[j];
}
}
}
if(dupes > 0) {
Arrays.fill(array, array.length-dupes, array.length, 0);
}
return array;
}
This has similar complexity to the answer posted by dbl, although it should be slightly faster due to eliminating some extra loops at the end. Another advantage is that this code doesn't rely on any assumptions that the input should not contain zeroes, unlike that answer.
#artshakhov:
Here is my approach, which is pretty much close enough to what you've found but using a bit fewer operations...
private static int[] deleteArrayDuplicates(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
if (array[i] == NEUTRAL) continue; //if zero is a valid input value then don't waste time with it
int idx = i + 1; //no need for third cycle, just use memorization for current shifting index.
for (int j = i + 1; j < array.length; j++) {
if (array[i] == array[j]) {
array[j] = NEUTRAL;
} else {
array[idx++] = array[j];
}
}
}
return array;
}
I just wrote the following code to answer your question. I tested it and I am getting the output you expected. If there are any special cases I may have missed, I apologize but it seemed to work for a variety of inputs including yours.
The idea behind is that we will be using a hash map to keep track if we have already seen a particular element in our array as we are looping through the array. If the map already contains that element- meaning we have already seen that element in our array- we just keep looping. However, if it is our first time seeing that element, we will update the element at the index where j is pointing to the element at the index where i is pointing to and then increment j.
So basically through the j pointer, we are able to move all the distinct elements to the front of the array while also making sure it is in the same order as it is in our input array.
Now after the first loop, our j pointer points to the first repeating element in our array. We can just set i to j and loop through the rest of the array, making them zero.
The time complexity for this algorithm is O(N). The space complexity is O(N) because of the hash table. There is probably a way to do this in O(N) time, O(1) space.
public static int[] deleteArrayDuplicates(int[] array) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
int j = 0;
for (int i = 0; i < array.length; i++) {
if (map.containsKey(array[i])) {
continue;
}
else {
map.put(array[i],1);
array[j] = array[i];
j++;
}
}
for (int i = j; i < array.length; i++) {
array[i] = 0;
}
return array;
}
Let me know if you have additional questions.
Spent a couple of hours trying to find a solution for my own, and created something like this:
public static int[] deleteArrayDuplicates(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[j] == array[i]) { //this is for comparing elements
int tempIndex = j;
while (tempIndex + 1 < array.length) {
array[tempIndex] = array[tempIndex + 1]; //this is for shifting elements down/left by "1"
array[array.length - 1] = 0; //making last element equal to "0"
tempIndex++;
}
}
}
}
return array;
}
Code is without any API-helpers, but seems like is working now.
Try this:
public static void main(String[] args)
{
int a[]={1,1,1,2,3,4,5};
int b[]=new int[a.length];
int top=0;
for( int i : a )
{
int count=0;
for(int j=0;j<top;j++)
{
if(i == b[j])
count+=1;
}
if(count==0)
{
b[top]=i;
top+=1;
}
}
for(int i=0 ; i < b.length ; i++ )
System.out.println( b[i] );
}
Explanation:
Create an another array ( b ) of same size of the given array.Now just include only the unique elements in the array b. Add the elements of array a to array b only if that element is not present in b.
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class StackOverFlow {
public static void main(String[] args) {
int[] array = {1, 1, 2, 2, 3, 2};
Set<Integer> set=new HashSet<>();
for (int anArray : array) {
set.add(anArray);
}
int[] a=new int[array.length];
int i=0;
for (Integer s:set) {
a[i]=s;
i++;
}
System.out.println(Arrays.toString(a));
}
}
Hope this simple one may help you.
Make use of Set which doesn't allow duplicates.
We can use ARRAYLIST and Java-8 Streams features to get the output.
public static int[] deleteArrayDuplicates(int[] array) {
List<Integer> list = new ArrayList(Arrays.stream(array).boxed().distinct().collect(Collectors.toList()));
for (int i = 0; i < array.length; i++) {
if (i < list.size()) {
array[i] = list.get(i);
} else {
array[i] = 0;
}
}
return array;
}
OUTPUT
[1, 2, 3, 0, 0, 0]

After counting sort the result array has one more element (0) than the original one

So I have a problem, this method is supposed to sort an array of integers by using counting sort. The problem is that the resulting array has one extra element, zero. If the original array had a zero element (or several) it's fine, but if the original array didn't have any zero elements the result starts from zero anyway.
e.g. int input[] = { 2, 1, 4 }; result -> Sorted Array : [0, 1, 2, 4]
Why would this be happening?
public class CauntingSort {
public static int max(int[] A)
{
int maxValue = A[0];
for(int i = 0; i < A.length; i++)
if(maxValue < A[i])
maxValue = A[i];
return maxValue;
}
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length + 1];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
Result[x] = A[i];
x--;
Count[A[i]] = x;
}
return Result;
}
}
You are using int[] Result = new int[A.length + 1]; which makes the array one position larger. But if you avoid it, you'll have an IndexOutOfBounds exception because you're supposed to do x-- before using x to access the array, so your code should change to something like:
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
x--;
Result[x] = A[i];
Count[A[i]] = x;
}
return Result;
}
Here you go: tio.run
int maxValue = max(A) + 1;
Returns the highest value of A + 1, so your new array with new int[maxValue] will be of size = 5;
The array Result is of the lenght A.lenght + 1, that is 4 + 1 = 5;
The first 0 is a predefinied value of int if it is a ? extends Object it would be null.
The leading 0 in your result is the initial value assigned to that element when the array is instantiated. That initial value is never modified because your loop that fills the result writes only to elements that correspond to a positive number of cumulative counts.
For example, consider sorting a one-element array. The Count for that element will be 1, so you will write the element's value at index 1 of the result array, leaving index 0 untouched.
Basically, then, this is an off-by-one error. You could fix it by changing
Result[x] = A[i];
to
Result[x - 1] = A[i];
HOWEVER, part of the problem here is that the buggy part of the routine is difficult to follow or analyze (for a human). No doubt it is comparatively efficient; nevertheless, fast, broken code is not better than slow, working code. Here's an alternative that is easier to reason about:
int nextResult = 0;
for (int i = 0; i < Count.length; i++) {
for (int j = 0; j < Count[i]; j++) {
Result[nextResult] = i;
nextResult++;
}
}
Of course, you'll also want to avoid declaring the Result array larger than array A.

Array in the reverse order [duplicate]

This question already has answers here:
How do I reverse an int array in Java?
(47 answers)
Closed 8 years ago.
I have an array of n elements and these methods:
last() return the last int of the array
first() return the first int of the array
size() return the length of the array
replaceFirst(num) that add the int at the beginning and returns its position
remove(pos) that delete the int at the pos
I have to create a new method that gives me the array at the reverse order.
I need to use those method. Now, I can't understand why my method doesn't work.
so
for (int i = 1; i
The remove will remove the element at the position i, and return the number that it is in that position, and then with replaceFirst will move the number (returned by remove) of the array.
I made a try with a simple array with {2,4,6,8,10,12}
My output is: 12 12 12 8 6 10
so if I have an array with 1,2,3,4,5
for i = 1; I'm gonna have : 2,1,3,4,5
for i=2 >3,2,1,4,5
etc
But it doesn't seem to work.
Well, I'll give you hints. There are multiple ways to reverse an array.
The simplest and the most obvious way would be to loop through the array in the reverse order and assign the values to another array in the right order.
The previous method would require you to use an extra array, and if you do not want to do that, you could have two indices in a for loop, one from the first and next from the last and start swapping the values at those indices.
Your method also works, but since you insert the values into the front of the array, its going to be a bit more complex.
There is also a Collections.reverse method in the Collections class to reverse arrays of objects. You can read about it in this post
Here is an code that was put up on Stackoverflow by #unholysampler. You might want to start there: Java array order reversing
public static void reverse(int[] a)
{
int l = a.length;
for (int j = 0; j < l / 2; j++)
{
int temp = a[j]
a[j] = a[l - j - 1];
a[l - j - 1] = temp;
}
}
int[] reverse(int[] a) {
int len = a.length;
int[] result = new int[len];
for (int i = len; i > 0 ; i--)
result[len-i] = a[i-1];
return result;
}
for(int i = array.length; i >= 0; i--){
System.out.printf("%d\n",array[i]);
}
Try this.
If it is a Java array and not a complex type, the easiest and safest way is to use a library, e.g. Apache commons: ArrayUtils.reverse(array);
In Java for a random Array:
public static void reverse(){
int[] a = new int[4];
a[0] = 3;
a[1] = 2;
a[2] = 5;
a[3] = 1;
LinkedList<Integer> b = new LinkedList<Integer>();
for(int i = a.length-1; i >= 0; i--){
b.add(a[i]);
}
for(int i=0; i<b.size(); i++){
a[i] = b.get(i);
System.out.print(a[i] + ",");
}
}
Hope this helps.
Reversing an array is a relatively simple process. Let's start with thinking how you print an array normally.
int[] numbers = {1,2,3,4,5,6};
for(int x = 0; x < numbers.length; x++)
{
System.out.println(numbers[x]);
}
What does this do? Well it increments x while it is less than numbers.length, so what is actually happening is..
First run : X = 0
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[0]);
// Which resolves to..
System.out.println(1);
Second Run : X = 1
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[1]);
// Which resolves to..
System.out.println(2);
What you need to do is start with numbers.length - 1, and go back down to 0. To do this, you need to restructure your for loop, to match the following pseudocode..
for(x := numbers.length to 0) {
print numbers[x]
}
Now you've worked out how to print, it's time to move onto reversing the array. Using your for loop, you can cycle through each value in the array from start to finish. You'll also be needing a new array.
int[] revNumbers = new int[numbers.length];
for(int x = numbers.length - 1 to 0) {
revNumbers[(numbers.length - 1) - x] = numbers[x];
}
int[] noArray = {1,2,3,4,5,6};
int lenght = noArray.length - 1;
for(int x = lenght ; x >= 0; x--)
{
System.out.println(noArray[x]);
}
}
int[] numbers = {1,2,3,4,5};
int[] ReverseNumbers = new int[numbers.Length];
for(int a=0; a<numbers.Length; a++)
{
ReverseNumbers[a] = numbers.Length - a;
}
for(int a=0; a<ReverseNumbers.Length; a++)
Console.Write(" " + ReverseNumbers[a]);
int[] numbers = { 1, 2, 3, 4, 5, 6 };
reverse(numbers, 1); >2,1,3,4,5
reverse(numbers, 2); >3,2,1,4,5
public int[] reverse(int[] numbers, int value) {
int index = 0;
for (int i = 0; i < numbers.length; i++) {
int j = numbers[i];
if (j == value) {
index = i;
break;
}
}
int i = 0;
int[] result = new int[numbers.length];
int forIndex = index + 1;
for (int x = index + 2; x > 0; x--) {
result[i] = numbers[forIndex--];
++i;
}
for (int x = index + 2; x < numbers.length; x++) {
result[i] = numbers[x];
++i;
}
return result;
}

Categories

Resources