Java removing zeros from array - java

I am trying to write a program that will, when executed, will go through an array and remove all instances of 0.0 and change the size of the array equal to the number of non zero elements and put those elements in their previous order. That is, if n=10 and the contents of a[j], j = 0 to n - 1 are initially
0.0, 1.2, 0.0, 0.0, 0.0, 2.3, 0.0, 9.7, 5.6, 0.0
then after execution of the code the contents should be
n=4, a[0]=1.2, a[1]=2.3, a[2]=9.7, and a[3]=5.6.
This is what I have so far:
import java.util.Scanner;
public class hw2
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
final double KEY = 0.0;
int n = scan.nextInt();
double[] a = new double[n];
for(int i=0; i<n; i++)
{
a[i] = scan.nextDouble();
}
for(int k = 0; k<n; k++)
{
if(a[k] == KEY)
{
a[k] = a[k+1];
n--;
}
System.out.println(a[k]);
}
}
}
Just a little nudge in the right direction would be appreciated.

Consider using an ArrayList, which will allow you to add items when you want, grow as needed, and maintain an accurate count.
Although in this case, if you wanted/needed to use an array, you could simply not save the value if it's "0", perhaps. (Also don't increment the "used array variable", except when you add, so you know how much contains "non 0" data or treat the first "0" encountered during iteration as "end of useful data" -- arrays are initialized with the default value of the type.)
If you want to go from an array with zeros to an array with no zeros at all, you must use two passes -- one to count the non-zeros, to construct a new array of the appropriate size, and then copy the non-zero values over. This could be done in reverse as well (compact the initial array, and then copy the "filled" portion of it over), but it's slightly more complicated.
If you do continue with your current approach (which the result array will have zeros, but at the end), you need to maintain two index pointers -- one is the primary loop iterator, the second is the next place to put the non-zero value, which is incremented only when a value is copied (or not moved, as when both indexes are the same, which will be the case until the first 0 is encountered). Make sure to "zero" the place you move the non-zero from. The number of moves can be reduced if order does not need to be preserved.

Your implementation (2nd for loop) is not right, it will fail to simple test case:
Input > 5 2.0 2 0.0 3 0.0
Your program will have wrong output:
2.0
2.0
3.0
3.0
but it should be 2.0 2.0 3
Also, you can't use == to compare two double.
The following code is my solution basing on your current code:
public class hw21 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
final double KEY = 0.0;
final Double ACCEPTABLE_TOLERANCE = 0.000000000001d;
int n = scan.nextInt();
double[] a = new double[n];
for (int i = 0; i < n; i++) {
a[i] = scan.nextDouble();
}
for (int k = 0, j = 0; k < n; k++) {
if (Math.abs(a[k] - KEY) < ACCEPTABLE_TOLERANCE) {
continue;
}
a[j] = a[k];
System.out.println(a[j]);
j++;
}
}
}
Also I prefer to use an ArrayList like below:
public class hw2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
final double KEY = 0.0;
final Double ACCEPTABLE_TOLERANCE = 0.000000000001d;
int n = scan.nextInt();
double[] a = new double[n];
for (int i = 0; i < n; i++) {
a[i] = scan.nextDouble();
}
List<Double> newList = new ArrayList<Double>();
for (int k = 0; k < n; k++) {
if (Math.abs(a[k] - KEY) < ACCEPTABLE_TOLERANCE) {
continue;
}
newList.add(a[k]);
}
System.out.println("There are " + newList.size() + " no-zero double:");
System.out.println(newList);
}
}

import java.util.Arrays;
import java.util.Scanner;
public class StackOverflow1
{
public static final double KEY = 0.0;
private static final Scanner INPUT = new Scanner(System.in);
public static void main(String[] args) {
int length = INPUT.nextInt();
double[] array = new double[length];
for(int i=0; i<length; i++) {
array[i] = INPUT.nextDouble();
}
int index = 0;
for(int k = 0; k < length ; k++) {
if(array[k] == KEY) {
continue;
}
array[index] = array[k]; // bring the non-zeroth element forward
if (index != k) array[k] = 0; //make the non-zeroth element zero in the actual location
index++;
}
System.out.println("n = " + index + " array = " + Arrays.toString(array));
}
}

you can remove those unwanted zeros as follows but in this case it get sorted.
#org.junit.Test
public void test15() throws Exception {
double[] arr = new double[]{0.0,1.1,0.1,0.0,2.1};
double[] nonZeroArr = arr;
Arrays.sort(nonZeroArr);
int index = -1;
while((index = Arrays.binarySearch(nonZeroArr, 0.0)) > -1){
double[] newArr = new double[nonZeroArr.length-index-1];
System.arraycopy(nonZeroArr, index+1, newArr, 0, newArr.length);
nonZeroArr = newArr;
}
for (double d : arr) {
System.out.print(d +",");
}
System.out.println();
for (double d : nonZeroArr) {
System.out.print(d + ",");
}
}

IF you want to sound really smart in class point out that this is a one liner in a lot of languages that are more productive than Java :)

Related

Why is the first element in the array being assigned a value of 0.0? NOTE: Not asking about INDEX, talking about value

This is a high school assignment. In my first for() loop, I build an array based on user input. However, the first value of the array is skipped and set to 0.0
I have traced the code through and through, to no avail.
import java.util.Scanner;
import java.lang.Math;
public class TestProject {
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("How long do you want the array?");
int length = scan.nextInt();
if(Math.abs(length) != length)
{
System.out.println("Not a valid length!");
}
else
{
double[] array = new double[length];
for(int i = 0; i < length-1; i++)
{
System.out.println("Enter a number");
array[i] = scan.nextDouble();
}
double[] finalarray = new double[array.length];
int finalarraycount = 1;
double flag = -1;
for(int x = 0; x<(array.length -1); x++)
{
if(array[x] > flag)
{
finalarray[finalarraycount] = array[x];
flag = array[x];
finalarraycount++;
}
}
System.out.print("Your array is {");
for(int y = 0; y<finalarray.length; y++)
{
System.out.print(finalarray[y]);
System.out.print(", ");
}
System.out.println("}");
}
}
}
I would like to input a specified number of values determined by variable length into an array, and then print the array in order from smallest to largest. Instead it skips index[0], and sets it to 0.0.
This is just standard compiler behaviour. finalarray[0] is not set to anything by your second for loop. Thus, Java initialises it to 0.0, as explained here: https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.5
finalarraycount should be initialized to 0, not 1.
int finalarraycount = 1;
finalarray[finalarraycount] = array[x];
This is why. You initialize it as 1 but the first index in the array is 0. If this was 0, it would affect the first index in the array.

Use multiple methods in Java

How to use multiple methods in a code? First it asks for the size of an array, then for the numbers of the element. One method is rounding numbers with a special rule.
Second method is a void method which modifies the array. Third method is making a new array with the modified values and returns to this array.
package tombtombbekerekit;
import java.util.Scanner;
public class TombTombbeKerekit {
public static int round(int osszeg)
{
int last_Digit = osszeg % 10;
if(last_Digit < 3)
return osszeg - last_Digit;
else if(last_Digit > 7)
return osszeg + (10 - last_Digit);
else
return osszeg - (last_Digit) + 5;
}
public static void roundSelf(int [] numbers)
{
int[] array = numbers;
for (int i = 0; i < array.length; i++)
return;
}
public static int [] roundNew(int [] numbers)
{
int [] newArray = new int[numbers.length];
return newArray;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Kérem az összegek számát: ");
int size = sc.nextInt();
System.out.println("Kérem az összegeket: ");
int [] array = new int[size];
for (int i = 0; i < array.length; i ++)
{
array[i] = sc.nextInt();
}
int [] kerek = roundNew(array);
System.out.println("Kerekítve: ");
for (int i = 0; i < kerek.length; i++)
System.out.println(kerek[i]);
}
}
You should write your own function. Just find the rule for the rounding. You can use n%10 to get the last digit of an integer named n.
I've written something but haven't tested it, I believe it should work. Check it out:
public int weirdRounding(int n)
{
int last_Digit = n % 10;
if(last_Digit < 3)
return n - last_Digit;
else if(last_Digit > 7)
return n + (10 - last_Digit);
else // the last digit is 3,4,5,6,7
return n - (last_Digit) + 5;
}
Note: You should probably make this code more readable if you're going to use it. For example define int LOWER_BOUND = 3 and int UPPER_BOUND = 7 instead of using '3' and '7', you could also wrap the ugly expressions with functions (e.g. roundUp, roundToFive ..). #Magic_Numbers_Are_Bad

java array rotating by n element gives wrong output in test

I have a problem with an exercise trying to solve it. Here is the task:
Write a program that moves that rotates a list several times (the first element becomes last).
list = 1,2,3,4,5 and N = 2 -> result = 3,4,5,1,2
Note that N could be larger than the length of the list, in which case you will rotate the list several times.
list = 1,2,3,4,5 and N = 6 -> result = 2,3,4,5,1
Input
On the first line you will receive the list of numbers.
On the second line you will receive N
Output
On the only line of output, print the numbers separated by a space.
Here are the TEST:
TEST 1:
Input 5,3,2,1 2
Output 2,1,5,3
TEST 2:
Input 2,1,3,4 5
Output 1,3,4,2
Here is my code so far:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] elements = input.split(",");
int[] array = new int[elements.length];
for (int i = 0; i < elements.length; i++) {
array[i] = Integer.parseInt(elements[i]);
}
int a = scanner.nextInt();
int[] rotated = new int[elements.length];
for (int x = 0; x <= array.length - 1; x++) {
rotated[(x + a) % array.length] = array[x];
}
for (int i = 0; i < rotated.length; i++) {
if (i > 0) {
System.out.print(",");
}
System.out.print(rotated[i]);
}
}
}
The first TEST is passed. But the second test is not passed and my program gives me wrong output: 4,2,1,3 instead of the right one: 1,3,4,2.
I cant figure it out where is the problem.
Thank you in advance for any help.
Your logic can be simplified to :
public static void shiftLeft(int shiftBy, int arr[]) {
for (int j = 0; j < shiftBy; j++) {
int a = arr[0]; // storing the first index
int i;
for (i = 0; i < arr.length - 1; i++) { // shifting the array left
arr[i] = arr[i + 1];
}
arr[i] = a; // placing first index at the end
}
}
Now call it :
public static void main(String[] args) {
// Fetch all data from user as you have done
int arr[] = { 1, 2, 3, 4, 5 };
shiftLeft(n % arr.length, arr);
// print out the array
}
Notice that if the number n is greater than the length of the array, you don't have to actually shift it that many times. Instead you just need to shift it n % arr.length times.

Sum all the values in an array of factorials and print the result

I want to write a java program which will calculate the first 20 factorial and store them in an array. Then go through the array and sum all of the items and print the result on the screen.
Here is my code but I think I did something wrong:
public class ArrayQuestion4 {
public static void main(String[] args) {
long array[]= new long[20];
long temp=1;
for ( int i=1; i<20; i++){
temp = i*(i+1);
temp = temp*(temp+1);
array[i]=temp;
System.out.println(array[i]);
}
for ( int i=1; i<20; i++){
temp = array[i];
temp = array[i]+(array[i+1]);
temp = temp+(temp+1);
System.out.println(temp);
}
}
}
The answer that comes out is not correct by the way.
I figure it out the correct code is this:
public class ArrayQuestion4 {
public static void main(String[] args) {
long array[]= new long[20];
array[0]=1;
long temp=0;
for ( int i=1; i<20; i++){
array[i]=array[i-1]*(i+1);
System.out.println(array[i-1]+"*"+(i+1)+" = "+array[i]);
}
for ( int i=1; i<20; i++){
temp = temp + array[i-1] + array[i];
}
System.out.println(" ");
System.out.println("Sum = "+temp);
}
}
The way you define factorial of n is
fact(n) = n * fact(n-1)
In the solution, factorial[n] represents factorial(n).
and temp is the current factorial being calculated.
public static void main(String[] args) {
long factorial[] = new long[20];
//Because Fact(1) = 1 * Fact(0), and fact(0) = 1.
factorial[0] = 1;
for (int n = 1; n < 20; n++) {
// Loop needs to be <20 because i have defined the array size = 20.
// <= would get an array out of bound exception. You can change the limits as you want.
//calculating the factorial based on formula:
// Factorial(N) = n * Facorial(N-1);
long factorialOfN = n*factorial[n-1];
//storing back the value in the array for future use.
factorial[n] = factorialOfN;
//Printing it.
System.out.println(factorialOfN);
}
}
As an illustration of where the code is probably not doing what you want it to be doing, look at what you get for (2)!
temp = i*(i+1); //temp = 1*(1+1); which is 2
temp = temp*(temp+1); //temp = 2*(2+1); which is 6
array[i] = temp; //array[1] = 6; - also note we skip ever assigning array[0]
You get 6 as an answer, which is incorrect.
Long could not hold sum of all 20! results. There is a limit for 'long' in Java and it is
public static final long MAX_VALUE = 0x7fffffffffffffffL;
which is 9223372036854775807
Use 'BigInteger' to get correct answer. And also refer 'How (not) to write Factorial in Java'

Create distinct values in array - not yielding expected results

I am trying to make an array that has different values in its cells, but for some reason it has repeating values. Where am I going wrong?
Here is my code:
package oefarray;
public class OefArray {
int[] getallenArray,differentArray;
public static void main(String[] args) {
OefArray arr = new OefArray();
arr.differentArray(10,10);
}
public void differentArray(int n, int max) {
differentArray= new int[n];
for (int i = 0; i < differentArray.length; i++) {
int value = (int) (Math.random() * max);
differentArray[i]= value;
for (int p: differentArray){
while (value == p){
value = (int) (Math.random() * max);
}
}
differentArray[i]= value;
System.out.println(differentArray[i]);
}
}
}
You're not checking whether the new generated value exists anywhere in the array, only that its value doesn't equal the current value you're examining.
differentArray= new int[n];
for (int i = 0; i < differentArray.length; i++) {
int value = 0;
while(true){
value = (int)(Math.random()*max);
boolean found = false;
for(int p: differentArray){
if(p==value){
found = true;
break;
}
}
if(!found) break;
}
differentArray[i] = value;
}
Here's an alternative to arshajii's solution which doesn't require a direct reference to ArrayList. As he pointed out, this is no more efficient than his solution. Just another way of writing it if you're not comfortable with Lists yet.
int[] nums = new int[max];
for (int i = 0; i < max; i++)
nums[i] = i;
Collections.shuffle(Arrays.asList(nums));
for (int i = 0; i < n; i++)
differentArray[i] = nums.get(i);
For a futuristic approach to this using Java 8, using IntStream.generate can produce some very terse results. This likely performs in the same performance window as the previous answer, so I make no assertion that this is more efficient. It is, however, more expressive.
public int[] differentArray(int length, int maxValue) {
if(length > maxValue) {
throw new IllegalArgumentException("The number of possible unique values is smaller than available number of slots for them.");
}
final Random random = new Random();
return IntStream.generate(() -> random.nextInt(maxValue))
.distinct()
.limit(length)
.toArray();
}

Categories