Array, quantity of positive and negative numbers must be equal - java

quantity of positive and negative numbers in array must be equal.
an array mustn't contain zero.
The main issue is that array is not always consist of 50/50 of percent of positive and negative numbers.
If you can show me much simply way to code it you are welcome!
public static void main(String[] args) throws IOException {
int array[] = new int[12];
int positiveCounter = 0;
int negativeCounter = 0;
for (int i = 0; i < array.length; i++) {
array[i] = createRandom();
while (array[i] == 0) {
array[i] = createRandom();
}
if (positiveCounter > array.length / 2) {
array[i] = -1 * array[i];
positiveCounter--;
negativeCounter++;
}
if (negativeCounter > array.length / 2) {
array[i] = -1 * (-array[i]);
negativeCounter--;
positiveCounter++;
}
if (array[i] > 0) {
positiveCounter++;
}
if (array[i] < 0) {
negativeCounter++;
}
}
System.out.println(Arrays.toString(array));
System.out.println("Pos: " + positiveCounter);
System.out.println("Neg: " + negativeCounter);
}
static int createRandom() {
Random random = new Random();
int x = -10 + random.nextInt(11 - (-10));
return x;
}

The comments may lead to a very compact way to achieve your goal, but for what it is worth I'd like to explain why your code is not working as expected, and show a way that it will.
You attempt to invert the sign to keep the amount of positive and negative numbers balanced. This will work, but you have a flaw in your code. You must only invert the number if the current number needs to be inverted. If you look at this code you will see it always inverts and adjusts the counters even if array[i] is negative (in which case nothing needs to be done):
if (positiveCounter > array.length / 2) {
array[i] = -1 * array[i]; // <- This is a problem
positiveCounter--;
negativeCounter++;
}
To follow should fix your issue; the inversion is only done as needed:
for (int i = 0; i < array.length; i++) {
array[i] = createRandom();
while (array[i] == 0) {
array[i] = createRandom();
}
if (positiveCounter >= array.length / 2 && array[i] > 0) {
array[i] = array[i] * -1; // Force the number to be negative
}
if (negativeCounter >= array.length / 2 && array[i] < 0) {
array[i] = array[i] * -1; // Force the number to be positive
}
if (array[i] > 0) {
positiveCounter++;
}
if (array[i] < 0) {
negativeCounter++;
}
}

Related

Return the sum of all items of the array that are factors of n

I am tasked with returning the sum of all the factors of n within the given array. I wrote a test and it is expecting 10 to be returned however I am getting 0 returned. Any tips on why this may be the case? Currently, the code I have written so far is below. The first if statement is there to ensure that if the array is null it just returns 0.
public static int sumFactors(int[] data, int n) {
if (data == null || data.length == 0) {
return 0;
} int sum = 0;
for (int i = 0; i < data.length; i++)
{
if (data[i] % n == 0)
{
sum = sum + data[i];
}
}
return sum;
}
You got it the other way around, x % n gives the remainder of x divided by n, so the condition to check if data[i] divides n is n % data[i] == 0
public static int sumFactors(int[] data, int n) {
if (data == null || data.length == 0) {
return 0;
}
int sum = 0;
for (int i = 0; i < data.length; i++){
if (n % data[i] == 0)
{
sum = sum + data[i];
}
}
return sum;
}

find all subsets of array having subset of size greater than or equal to 2

The below code prints all subsets, but I need of size greater than or equal to 2.
public static void printSubsets(char set[])
{
int n = set.length;
for (int i = 0; i < (1<<n); i++)
{
System.out.print("{ ");
for (int j = 0; j < n; j++)
if ((i & (1 << j)) >0 )
System.out.print(set[j] + " ");
System.out.println("}");
}
}
A subset of size 0 corresponds to i == 0. To eliminate the empty subset start at i = 1.
A subset of size 1 corresponds to i having exactly one bit set; or, equivalently, when it is a power of 2. A positive number i is a power of two if (i & (i - 1)) == 0.
for (int i = 1; i < (1<<n); i++) {
if ((i & (i - 1)) == 0) {
continue;
}
System.out.print("{ ");
for (int j = 0; j < n; j++) {
if ((i & (1 << j)) != 0) {
System.out.print(set[j] + " ");
}
}
System.out.println("}");
}
Alternatively, you could keep your original loop and simply insert this check:
if (Integer.bitCount(i) < 2) {
continue;
}
It's not as clever or efficient, but it is nice and readable.

How to calculate the average of even and odd numbers in an array?

As a class exercise I have to code using methods a program that:
1) Calculates the average of even and odd numbers in an array.
I expect on using one method to find the average of even and odd numbers. However, I'm having trouble on returning the right average. For example, if I enter only odd numbers I get an error, and vice versa.
This error:
"java.lang.ArithmeticException: / zero"
Also, if it were possible I would like to get some help on coding the rest of the exercise which asks for:
2) Print the highest and lowest number in the array
3) Allow the user to modify any of the numbers of the array
So far I have this code:
public static void main (String args[]){
int x[] = new int[4];
Scanner input = new Scanner(System.in);
for(int i = 0; i < x.length ; i++){
System.out.println("Enter a number: ");
x[i] = input.nextInt();
}
System.out.println("Average of even numbers: " + getAverage(x));
System.out.println("Average of odd numbers: " + getAverage(x));
}
public static int getAverage(int a[]){
int add_even = 0;
int counter_even = 0;
int average_even = 0;
int add_odd = 0;
int counter_odd = 0;
int average_odd = 0;
for(int i = 0; i < a.length; i++){
if(a[i] % 2 == 0){
add_even += a[i];
counter_even++;
}
else if(a[i] % 2 == 1) {
add_odd += a[i];
counter_odd++;
}
}
if (add_even % 2 == 1 && add_odd % 2 == 1){
average_even = 0;
average_odd = add_odd / counter_odd;
return average_even;
}
else if (add_even % 2 == 0 && add_odd % 2 == 0){
average_even = add_even / counter_even;
average_odd = 0;
return average_even;
}
else{
average_even = 0;
average_odd = add_odd / counter_odd;
return average_odd;
}
}
Thank you!
Your get average looks more complicated then it needs to be.
First off the getAverage(x):
System.out.println("Average of even numbers: " + getAverage(x));
System.out.println("Average of odd numbers: " + getAverage(x));
will return the same value, so if you wanted to get the average for odds or evens the method should require a boolean arg to represent odd or even.
In your method you should loop through all the numbers and check if it is even. If it is even and you are averaging evens add it to a "total" and add one to a counter. At the end divide "total" by the counter and return the value. The average will most likely include a decimal value, so you should return a double or a float.
Example:
public static double getAverage(int a[], boolean even){
double total = 0;//These are doubles so dividing later does not require casting to retain a decimal (this can be an int if you only want to return integers)
double counter = 0;
for(int i = 0; i<a.length; i++){
if(a[i] % 2 == 0 && even){//even
counter++;
total += a[i];
}else{//odd
counter++;
total += a[i];
}
}
if(total == 0){//Avoid dividing by 0.
return 0; //You can also throw an exception instead of returning 0.
}
return total / counter; //Returns the average for even or odd numbers.
}
For the second part of your question you need to loop through the numbers and find the highest and lowest while looping.
Example:
int highest = 0;
int lowest = 0;
for(int i = 0; i<x.length; i++){
if(x[i] > highest){
highest = x[i];
}
if(x[i] < lowest){
lowest = x[i];
}
if(i == 0){
highest = x[i];
lowest = x[i];
}
}
You have a divide by zero error cropping up here.
else if (add_even % 2 == 0 && add_odd % 2 == 0){
average_even = add_even / counter_even;
average_odd = 0;
return average_even;
}
0 % 2 == 0 so even if add_even is 0 (and as a result, so is counter_even) you're attempting to use it to divide. You'll need to account for that in your code by checking if counter_even is 0.
else if (counter_even != 0 && add_even % 2 == 0 && add_odd % 2 == 0){
1)Using one method to get the average of the even and odd numbers isn't proper because you only return one int. It would be simpler to use two methods but if you're insistent on using one method you could add a boolean as a parameter like this to decide which to do. To handle the ArithmeticException just return 0 if there are no values.
public static int average(int[] n, boolean even) {
int total = 0;
int count = 0;
for (int i = 0; i < n.length; i++) {
if (even == (n % 2 == 0)) {
total += n;
count ++;
}
}
if (count == 0)
return 0;
return total / count;
2)To check find the max and min value simply loop through the array like this
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < x.length; i++) {
if (x[i] < min)
min = x[i];
if (x[i] > max)
max = x[i];
}
3)To allow the user to modify the array, you could print the values and prompt them as to which value they would like to change like this.
System.out.print("Array: ");
for (int i = 0; i < x.length; i++) {
System.out.print(i + ",");
}
System.out.println();
System.out.println("Which value would you like to change?");
int index = input.nextInt();
System.out.println("What do you want the new value to be?");
int value = input.nextInt();
You can then run a method that changes the value of the array
edit(x, index, value);
public static int edit(int[] n, int index, int value) {
n[index] = value;
return n;
}
I used JS for this task, you can just rewrite my code to Java language.
A number is divisible by 2 if the result of its division by 2 has no
remainder or fractional component - in other terms if the result is an
integer. Zero is an even number because when 0 is divided by
2, the resulting quotient turns out to also be 0 - an integer (as a
whole number that can be written without a remainder, 0 classifies as
an integer).
function compareEvenOddAverage(arr) {
let even = 0,
odd = 0,
evenCounter = 0,
oddCounter = 0,
str = '';
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
even += arr[i];
evenCounter++;
} else {
odd += arr[i];
oddCounter++;
}
}
if (even / evenCounter > odd / oddCounter) {
str += 'Average value of even numbers is greater';
} else if (even / evenCounter < odd / oddCounter) {
str += 'Average value of odd numbers is greater';
} else {
str += 'Average values are equal';
}
return str;
}
console.log(compareEvenOddAverage([0, 1, 2, 3, 4, 5]));

Calculation of a total number of "0" positions between "1" positions in a vector int[]

There is a vector of 1 and 0:
int[] vec = new int[6]{0,1,0,0,1,0};
I need to calculate total number of "0" positions between "1" positions. For instance, if <0,1,0,0,1,0> then the answer is 2. However, the problem is that the vector may contain the following values:
int[] vec = new int[6]{0,1,0,0,0,0}; // the answer is 0
or
int[] vec = new int[6]{1,0,0,1,0,1}; / the answer is 3
So far, I just made a simple algorithm for the 1st case (<0,1,0,0,1,0>).
int start = 0, end = 0;
for (int i=0; i<vec.length; i++)
{
if (vec[i] == 1 && start == 0)
start = i;
if (vec[i] == 1 && start != 0)
end = i;
}
int result = end - start - 1;
I need some help with the development of more generic algorithm that could handle all the above-mentioned cases.
You can iterate over the array from both ends to find the first and last 1. Then, if you found both, count the 0s between them.
int start = -1;
int end = vec.length;
int i = 0;
int j = vec.length-1;
while (i < j) {
if (vec[i] == 1 && start < 0)
start = i;
i++;
if (vec[j] == 1 && end >= vec.length)
end = j;
j--;
if (start >= 0 && end < vec.length)
break;
}
int count = 0;
if (start >= 0 && end < vec.length) {
for (i = start + 1; i < end; i++) {
if (vec[i] == 0)
count++;
}
}
It can probably be optimized into a single loop.
Sorry, initially I thought you wanted to count the number of segments rather than the actual number of zeroes.
You can count all the zeroes after the first one (n), keeping track of the number of zeroes since the last one seen (m). Then when you reach the end of the vector, your count of n is m zeroes too high.
int count = 0;
int zeroesSinceLastOne = 0;
bool firstOneSeen = false;
for(int i = 0, n = vector.size(); i < n; ++i)
{
while(!firstOneSeen && vector[i] == 0)
{
continue;
}
firstOneSeen = true;
if(vector[i] == 0)
{
++count;
++zeroesSinceLastOne;
}
else
{
zeroesSinceLast = 0;
}
}
return count - zeroesSinceLastOnce;
Disclaimer: untested. May give the wrong number or kill your cat.
Try this algo:
startIndex = -1;
endIndex = -1;
for i from 1 to vec.length():
if( 1 == vec[i])
startIndex = i
break;
for i from vec.length() to 1:
if( 1 == vec[i])
endIndex = i
break;
ans = endIndex - startIndex - no_of_ones_in_between

Alternate positive and negative numbers in an array

Given an array of positive and negative numbers(no zeroes), I have to arrange them in such a way that the positive and negative numbers should be arranged consecutively.
The number of positive and negative numbers may not be equal i.e. if there is no positive number(or negative) left, then all the remaining negative numbers(or positive) are appended to the end of the array.
The order is important i.e.if input array is {2,-1,-3,-7,-8, 9, 5,-5,-7},then the output array should be {2,-1, 9,-3, 5,-7,-8,-5,-7}. The code is done in O(n) without using another array.
Here is my solution in java, I test it again several case and it works. However, I'm not sure if this run in O(n) time. Basically, I count the number of positive and negative number first. then I have two index i = 0 and j =1. j is always 1 step ahead i. From there I keep checking if the number in i is positive and j is negative, if it isn't, i will iterate through the array until I find the next positive/negative for the correct position and move it to the correct position.
Any suggestion is much appreciated. Thanks!
//array of negative and positive, arrange them so that positive number follow by negative
// if no pos or neg left, the rest append to the array.
//should be O(n) no additional array
public static void alter(int[] a) {
int pos = 0;
int neg = 0;
int index = 0;
while (c < a.length) {
if (a[index] > 0) {
pos++;
} else neg++;
index++;
}
int i = 0;
int j = 1;
int temp = 0;
//run until no more positive number or negative number
while (pos > 0 && neg > 0) {
//
if (a[i] > 0) {
pos--;
if (a[j] < 0) {
i += 2;
j += 2;
neg--;
} else // a[j] > 0
{
while (a[j] > 0) {
j++;
}
//a[j] < 0
neg--;
//move that number to the appropriate place
while (j > i) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
j--;
} // end while
i += 2;
j += 2;
}
} else // a[i] < 0
{
while (a[i] < 0) {
i++;
}
//a[i] > 0
//move that number to the appropriate place
while (i > (j - 1)) {
temp = a[i];
a[i] = a[i - 1];
a[i - 1] = temp;
i--;
}
} //end else
}
}
However, I'm not sure if this run in O(n) time
I do not think it runs in O(n). The moment you have to "find the next correct element and move it to the correct location", you need to
Loop over the remainder of the array. Which means that for the worst case scenario (array with all positive elements at the start, and all negative elements at the end) you will loop for each of the positive elements one more time over half of the "unsorted" part of the array
When you move the element back to the correct location, you move it position by position. This means you loop once more over the "unsorted" part of the array
Not really sure yet how you would get it running in O(n) if you need to respect the requirement that the ordering must be respected without using a third array.
Yes, it can be done in O(n).
Lets assume that c is current position. And a[c] is positive number.
1) Increment i from c towards end of array until i points to first wrong number (number that have the same sign as previous, in this case positive).
2) Set j := i;
3) Increment j towards end of array until j points to number with wanted sign (in this case - negative).
4) Swap a[i] with a[j].
5) Set c := j;
6) Set j := c + 1;
In each step you always increment i or j or c. Never decrement.
Variable i can be incremented no more than n times. Same to j and c.
So maximum number of increments is 3n ~ O(n).
PFB my code. If we will use Stack then it will make our problem more easier.
public class AlternatePosNeg {
public static void main(String[] args) {
int arr[] = { 2, -1, -3, -7, -8, 9, 5, -5, -7 };
Stack<Integer> pos = new Stack<>();
Stack<Integer> neg = new Stack<>();
int i;
for (i = 0; i < arr.length; i++) {
if (arr[i] > 0) {
pos.push(arr[i]);
} else {
neg.push(arr[i]);
}
}
int tempArr[] = new int[arr.length];
i = 0;
int sizePos = pos.size();
int sizeNeg = neg.size();
while (i < tempArr.length) {
if (sizePos > sizeNeg) {
if (pos.size() > 0) {
tempArr[i] = pos.pop();
}
if (neg.size() > 0) {
tempArr[i + 1] = neg.pop();
i++;
}
} else {
if (neg.size() > 0) {
tempArr[i] = neg.pop();
}
if (pos.size() > 0) {
tempArr[i + 1] = pos.pop();
i++;
}
}
i++;
}
for (int no : tempArr) {
System.out.print(no + " ");
}
}
}

Categories