How to protect arrays from changing? - java

I'm trying to get data from arrays that were used in method fifo and lifo. I have main array that fills from input by user. These array is used in methods fifo and lifo, the problem is that these two functions giving the same priceOfGoods, because while fifo using main array in process it changing data inside it. I want to prevent changing data in ```main array** and use it in two methods without changing data inside main array. Any ideas? Thanks!
public class Solution {
public static int[][] takingGoodsAndPrice(Scanner input, Integer m) {
final int[][] goodsAndPrice = new int[m][2];
// Taking goods and its price
for (int i = 0; i < m; i++) {
for (int j = 0; j < 2; j++) {
goodsAndPrice[i][j] = Integer.parseInt(input.next());
}
}
return goodsAndPrice;
}
public static int[] takingAmountOfSales(Scanner input, Integer k) {
final int[] amountOfSales = new int[k];
// Taking sale of goods
for (int i = 0; i < k; i++) {
amountOfSales[i] = Integer.parseInt(input.next());
}
return amountOfSales;
}
public static Integer fifo(Integer k, Integer m, int[][] goodsAndPrice, int[] amountOfSales) {
int priceOfRestGoods = 0;
int[][] goods = goodsAndPrice;
int[] amount = amountOfSales;
// Evaluates amount of goods that were not sold
for (int i = 0; i < k; i++) {
for (int j = 0; j < m; j++) {
if (amount[i] == 0)
break;
if (goods[j][0] > amount[i]) {
goods[j][0] = goods[j][0] - amount[i];
amount[i] = amount[i] - amount[i];
} else if (goods[j][0] <= amount[i]) {
amount[i] = amount[i] - goods[j][0];
goods[j][0] = 0;
}
}
}
// Evaluates price of goods that were not sold
for (int i = 0; i < m; i++) {
priceOfRestGoods = priceOfRestGoods + (goods[i][0] * goods[i][1]);
}
return priceOfRestGoods;
}
public static Integer lifo(Integer k, Integer m, int[][] goodsAndPrice, int[] amountOfSales) {
int priceOfRestGoods = 0;
// Evaluates amount of goods that were not sold
for (int i = 0; i < k; i++) {
for (int j = m-1; j >= 0; j--) {
if (amountOfSales[i] == 0)
break;
if (goodsAndPrice[j][0] > amountOfSales[i]) {
goodsAndPrice[j][0] = goodsAndPrice[j][0] - amountOfSales[i];
amountOfSales[i] = amountOfSales[i] - amountOfSales[i];
} else if (goodsAndPrice[j][0] <= amountOfSales[i]) {
amountOfSales[i] = amountOfSales[i] - goodsAndPrice[j][0];
goodsAndPrice[j][0] = 0;
}
}
}
// Evaluates price of goods that were not sold
for (int i = 0; i < m; i++) {
priceOfRestGoods = priceOfRestGoods + (goodsAndPrice[i][0] * goodsAndPrice[i][1]);
}
return priceOfRestGoods;
}
//
// public static Integer medium() {
//
// }
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int n = input.nextInt(); // n - total amount of goods
final int m = input.nextInt(); // m - total amount of goods that has been received
final int k = input.nextInt(); // k - total amount of goods that has been released
final int[][] goodsAndPrice = takingGoodsAndPrice(input, m);
final int[] amountOfSales = takingAmountOfSales(input, k);
System.out.println(fifo(k, m, goodsAndPrice, amountOfSales));
System.out.println(lifo(k, m, goodsAndPrice, amountOfSales));
}
}

At the moment, you're creating new variables to store the arrays, but they will reference the same array done like this, meaning that any changes made to them will also be present in the original parameters. You'll want to store a copy of the arrays in those variables instead. See here.

When you do the following
int[][] goods = goodsAndPrice;
you are still referencing the values referenced by goodsAndPrice i.e. both goods and goodsAndPrice will reference the same values. Therefore, any changes made using one of these references will be same for the other reference.
What you need to do is to create a copy of goodsAndPrice[][] and make changes to the copy. You can do create a copy of goodsAndPrice[][] as follows:
int[][] goods = Arrays.stream(goodsAndPrice).map(int[]::clone).toArray(int[][]::new);

Related

How to create random numbers a specific number of times?

How can i create a random number a specific numbers of time?
public class Feld {
public static void main(String[] args) {
double k = (int)(Math.random()*1000001);
int n = 1000000;
int arr[] = new int[n];
int i = 0;
for(i = 0;i<n;i++){
arr[i] = i;
}
boolean found = false;
i=0;
while (i < arr.length) {
if (arr[i] == k) {
found = true;
break;
}
i++;
}
if (found) {
i++;
System.out.println(i);
}
else {
System.out.println((arr.length + 1));
}
}
}
My problem is, that if i put k into a loop to create it more than one time i'll get an error at:
if (arr[i] == k)
!!I just found out that i made a mistake explaining my problem. The array should be filled with values from 0-1.000.000 and i am supposed to print out the position of a random generated number for a specific amount of times.
If you want to have an array full of random numbers, I suggest using the following:
int n = 1000000;
int arr[] = new int[n];
for(int i = 0; i < n; i++){
arr[i] = (int)(Math.random() * 1000001);
}
That will work and you don't even need the variable k.
Edit:
If you want to print at what position you find a specific value (for example x = 543), you can use the following code:
int x = 543;
int n = 1000000;
int arr[] = new int[n];
for(int i = 0; i < n; i++){
arr[i] = (int)(Math.random() * 1000001);
if(arr[i] == x) {
System.out.println(i);
break;
}
}
Edit2
One possible solution to your new problem looks like this:
public class Feld {
public static void main(String[] args) {
int n = 1000000;
int arr[] = new int[n];
int i = 0;
for(i = 0; i < n; i++){
arr[i] = i; //Filling array with values 0-1000000
}
int number = 20; //Print out position of a random generated number a specific amount of times
int randomNumber = (int)(Math.random()*1000001); //The random number
for(int j = 0; j < number; j++) { //Find number for a specific amount of times
for(int k = 0; k < arr.length; k++) { //Find number in array
if(arr[k] == randomNumber) {
System.out.println(arr[k]); //Print
break; //Number found, don't have to search anymore
}
}
}
}
}
I would write a method that returns an array of random numbers and takes an int argument that defines the length of the array.
One possible solution is this:
public static int[] createRandomArray(int length) {
// create an array of the given length
int[] result = new int[length];
// and use a single for loop that puts random int values into every index
for (int i = 0; i < result.length; i++) {
result[i] = ThreadLocalRandom.current().nextInt();
}
// then simply return the result
return result;
}
Try it as follows
public static void main(String[] args) {
// super primitive time measurement:
// take the moment in time before calling the method
Instant start = Instant.now();
// then call the method
int[] array = createRandomArray(1000000);
// and take the moment in time after the method returned
Instant end = Instant.now();
// then calculate the duration
Duration duration = Duration.between(start, end);
// and print the duration in milliseconds
System.out.printf("Array creation took %d milliseconds\n", duration.toMillis());
}
The result is the following output on my system:
Array creation took 10 milliseconds

How can I make a new Array and copy all the postive elements from the other array in the new array and return it?

This method returns an array that contains the positive elements of the parameter array in.
To do that, compute the number of positive elements in the array in and store the obtained value in the variable
nElements of type integer, declare the double array output of size nElements, copy the positive elements
of in into the array output, and return the array output. If all the elements of the array in are non-positive,
your method should return an array of size 1 and the only element of the returned array is assigned the
value -1.
My question here is when I run my program it states Exception in thread "main" java.lang.NegativeArraySizeException and I don't know how to take it out and only return the positive elements.
The Java-Code:
public static double [] partialPositiveArray(double [] in)
{
int nElements = 0;
for(int i = 0; i < in.length; i++)
{
if(in[i] > 0)
{
nElements = (int)in[i];
}
else if(in[i] <= 0)
{
nElements = -1;
}
}
double [] output = new double[nElements];
for(int i = 0; i < in.length; i++)
{
output[i] = nElements;
}
return output;
}
with this code you will add all positive numbers. the sum in this example is 60.7 and for all negative numbers it will write -1 in the negative-array. in this example twice.
Code:
public class NegativeAndPositiveNumbers {
public static void main(String[] args) {
double[] arr = {25.0, -7.0, 10.7, 25.0, -64.0};
System.out.println(partialPositiveArray(arr));
int negative[] = negativeArray(arr);
for (int i = 0; i < negative.length; i++){
System.out.print(negative[i] + " ");
}
}
public static double partialPositiveArray(double[] in) {
double nElements = 0;
for (int i = 0; i < in.length; i++) {
if (in[i] > 0) {
nElements += in[i];
}
}
return nElements;
}
public static int[] negativeArray(double[] in) {
int[] negativeWithZero = new int[in.length];
int index = 0;
for (int i = 0; i < in.length; i++) {
if (in[i] <= 0) {
negativeWithZero[index] = -1;
index++;
}
}
int[] negative = new int[index];
for (int j = 0; j < negative.length; j++){
negative[j] = negativeWithZero[j];
}
return negative;
}
}
I think it could be solved more easily, but it works anyway. I hope everything is clear
public static double [] partialPositiveArray(double [] in) {
return Arrays.stream(in)
.filter(d -> d > 0)
.toArray();
}
You are changing the variable nElements when it is positive you are taking the value from in[ ] array and when it is negative you are changing it to -1.
for(int i = 0; i < in.length; i++)
{
if(in[i] > 0)
{
nElements = (int)in[i];
}
else if(in[i] <= 0)
{
nElements = -1;
}
}
In the array you are passing to the function there seems to be a negative number at end so when control comes across this ,nElements value is -1. After the loop you are instantiating an array with size given as this variable
double [] output = new double[nElements];
Therefore you are getting NegativeArrayIndexException
Solution as per requirement:
public static double [] partialPositiveArray(double [] in)
{
boolean gotPositive=false;
int size=0;
int j=0;
for(int i = 0; i < in.length; i++)
{
if(in[i] >= 0)
{
size++;
gotPositive=true;
}
}
if(size==0 && !gotPositive){
size=1;
}
double [] output = new double[size];
for(int i = 0; i < in.length; i++)
{
if(in[i] >= 0)
{
output[j++]=in[i];
}
}
if(!gotPositive){
output[0]=-1;
}
return output;
}

How do i fix my interpretation of this run-length encoding algorithm?

For school, i have to build myself a method in java that compresses an array using RLE(run-length encoding). I can't find a solution online because my teacher wants me to solve the problem myself. I, unfortunately, cannot do this for i am a busy man with some busy plans.
RLE turns this: {1,1,1,1,2,2,3,3,6,6,6,7,8,8,8}
into this: {4,1,2,2,2,3,3,6,1,7,3,8}
it basically makes a new array that follows this formula {# of this value, this value, # of this value, this value, cont...} there are 4 1's so {4,1} you get my drift.
Here is what i tried to do(forgive me for my crappy code, i am merely a high school student):
public class tester{
public static void main(String[] args){
int[] potato = {1,1,1,2,2,4,4,4,6,6,6,6};
printArray(compress(potato));
}
public static void printArray(int[] arr){
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
public static int[] compress(int[] a) {
//figure out how many different numbers there are.
int diffNums = 1;
for(int i = 0; i < a.length; i++){
if(i != a.length-1 && a[i] != a[i+1]){
diffNums++;
}
}
//make compressed array at the correct length.
int[] compressed = new int[diffNums * 2];
//figure out what each number is.
int[] nums = new int[diffNums];
nums[0] = a[0];
int spot = 0;
for(int i = 0; i < a.length; i++){
if(i != a.length-1 && a[i] != a[i+1]){
nums[spot] = a[i+1];
}
}
//figure out quantity of each number.
int[] quantities = new int[diffNums];
int spot2 = 0;
int spotcur = 0;
for(int i = 0; i < diffNums; i++){
int quant = 0;
while(a[spotcur] == a[spot2]){
quant++;
spotcur++;
}
spot2 = spotcur;
quantities[i] = quant;
}
//add them together and return compressed array
int spotter = 0;
for(int i = 0; i < diffNums; i++){
compressed[spotter] = quantities[i];
spotter++;
compressed[spotter] = nums[i];
spotter++;
}
return compressed;
}
}
Does anyone know how i can fix this crappy code? i am stuck on it
I think this problem could be solved with a lot less code. You could use an outer/inner loop construct something like the following:
public static int[] compress(int[] a) {
List<Integer> encoded = new ArrayList<>();
for (int i=0; i<a.length; i++) {
int num = a[i];
int count = 1;
for (int j=i+1; j<a.length; j++) {
int nextNum = a[j];
if (nextNum != num)
break;
count++;
i++;
}
encoded.add(count);
encoded.add(num);
}
return encoded.stream().mapToInt(i->i).toArray();
}
Also, the Arrays class contains a useful toString method already defined.
System.out.println(Arrays.toString(compress(potato)));

Java set/setElementAt not setting the right value

I need to find all the permutations for a given n(user input) without backtracking.
What i tried is:
import java.util.Scanner;
import java.util.Vector;
class Main {
private static int n;
private static Vector<Vector<Integer>> permutations = new Vector<>();
private static void get_n() {
Scanner user = new Scanner(System.in);
System.out.print("n = ");
n = user.nextInt();
}
private static void display(Vector<Vector<Integer>> permutations) {
for (int i = 0; i < factorial(n) - 1; ++i) {
for (int j = 0; j < n; ++j) {
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
}
System.out.println();
}
}
private static int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}
private static int max(Vector<Integer> permutation) {
int max = permutation.elementAt(0);
for (int i = 1; i < permutation.size(); ++i)
if (permutation.elementAt(i) > max)
max = permutation.elementAt(i);
return max;
}
// CHECKS FOR ELEMENT COUNT AND 0 - (n-1) APPARITION
public static int validate_permutation(Vector<Integer> permutation) {
// GOOD NUMBER OF ELEMENTS
if (max(permutation) != permutation.size() - 1)
return 0;
// PROPER ELEMENTS APPEAR
for (int i = 0; i < permutation.size(); ++i)
if (!permutation.contains(i))
return 0;
return 1;
}
private static Vector<Integer> next_permutation(Vector<Integer> permutation) {
int i;
do {
i = 1;
// INCREMENT LAST ELEMENT
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
// IN A P(n-1) PERMUTATION FOUND n. "OVERFLOW"
while (permutation.elementAt(permutation.size() - i) == permutation.size()) {
// RESET CURRENT POSITION
permutation.set(permutation.size() - i, 0);
// INCREMENT THE NEXT ONE
++i;
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
}
} while (validate_permutation(permutation) == 0);
// OUTPUT
System.out.print("output of next_permutation:\t\t");
for (int j = 0; j < permutation.size(); ++j)
System.out.print(permutation.elementAt(j) + " ");
System.out.println();
return permutation;
}
private static Vector<Vector<Integer>> permutations_of(int n) {
Vector<Vector<Integer>> permutations = new Vector<>();
// INITIALIZE PERMUTATION SET WITH 0
for (int i = 0; i < factorial(n); ++i) {
permutations.addElement(new Vector<>());
for(int j = 0; j < n; ++j)
permutations.elementAt(i).addElement(0);
}
for (int i = 0; i < n; ++i)
permutations.elementAt(0).set(i, i);
for (int i = 1; i < factorial(n); ++i) {
// ADD THE NEXT PERMUTATION TO THE SET
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
System.out.print("values set by permutations_of:\t");
for (int j = 0; j < permutations.elementAt(i).size(); ++j)
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
System.out.println("\n");
}
System.out.print("\nFinal output of permutations_of:\n\n");
display(permutations);
return permutations;
}
public static void main(String[] args) {
get_n();
permutations.addAll(permutations_of(n));
}
}
Now, the problem is obvious when running the code. next_permutation outputs the correct permutations when called, the values are set correctly to the corresponding the vector of permutations, but the end result is a mass copy of the last permutation, which leads me to believe that every time a new permutation is outputted by next_permutation and set into the permutations vector, somehow that permutation is also copied over all of the other permutations. And I can't figure out why for the life of me.
I tried both set, setElementAt, and an implementation where I don't initialize the permutations vector fist, but add the permutations as they are outputted by next_permutation with add() and I hit the exact same problem. Is there some weird way in which Java handles memory? Or what would be the cause of this?
Thank you in advance!
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
This is literally setting the vector at permutations(i) to be the same object as permutations[i-1]. Not the same value - the exact same object. I think this the source of your problems. You instead need to copy the values in the vector.

2D Array Methods & Demo

I have an assignment to design and implement methods to process 2D Arrays.
It needs to have an implementation class (Array2DMethods) that has the following static methods:
readInputs() to read the number of rows and columns fro the user then reads a corresponding entry to that size. Ex: if a user enters 3 for # of rows and 3 for # of columns it'll declare an array of 10 and reads 9 entries.
max(int [][] anArray) it returns the max value in the 2D parameter array anArray
rowSum(int[][] anArray) it returns the sum of the elements in row x of anArray
columnSum(int[][] anArray) it returns the sum of the elements in column x of anArray **careful w/ rows of different lengths
isSquare(int[][] anArray) checks if the array is square (meaning every row has the same length as anArray itself)
displayOutputs(int[][] anArray) displays the 2 Dim Array elements
It also needs a testing class (Arrays2DDemo) that tests the methods.
I've commented the parts I'm having problems with. I'm not sure how to test the methods besides the readInputs method and also not sure how to format the part where you ask the user to enter a number for each row.
Here's my code so far:
import java.util.Scanner;
class Array2DMethods {
public static int [][] readInputs(){
Scanner keyboard = new Scanner(System.in);
System.out.print(" How many rows? ");
int rows = keyboard.nextInt();
System.out.print(" How many columns? ");
int columns = keyboard.nextInt();
int [][] ret = new int[rows][columns];
for (int i = 0; i<ret.length; i++) {
for (int j = 0; j < ret[i].length; j++) {
System.out.print("please enter an integer: "); //Need to format like Enter [0][0]: ... Enter [0][1]: ...etc.
ret[i][j] = keyboard.nextInt();
}
}
return ret;
}
public static int max(int [][] anArray) {
int ret = Integer.MIN_VALUE;
for (int i = 0; i < anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
if (anArray[i][j] > ret) {
ret = anArray[i][j];
}
}
}
return ret;
}
public static void rowSum(int[][]anArray) {
int ret = 0;
for (int i = 0; i<anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
ret = ret + anArray[i][j];
}
}
}
public static void columnSum(int[][]anArray) {
int ret = 0;
for (int i = 0; i < anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
ret = ret + anArray[i][j];
}
}
}
public static boolean isSquare(int[][]anArray) {
for (int i = 0, l = anArray.length; i < l; i++) {
if (anArray[i].length != l) {
return false;
}
}
return true;
}
public static void displayOutputs(int[][]anArray) {
System.out.println("Here is your 2Dim Array:");
for(int i=0; i<anArray.length; i++) {
for(int j=0; j<anArray[i].length; j++) {
System.out.print(anArray[i][j]);
System.out.print(", ");
}
System.out.println();
}
}
}
Class Arrays2DDemo:
public class Arrays2DDemo {
public static void main(String[] args){
System.out.println("Let's create a 2Dim Array!");
int [][] anArray = Array2DMethods.readInputs();
Array2DMethods.max(anArray);
Array2DMethods.rowSum(anArray);
//need to print out and format like this: Ex Sum of row 1 = 60 ...etc
Array2DMethods.columnSum(anArray);
//need to print out and format like this: Ex Sum of column 1 = 60 ...etc.
Array2DMethods.isSquare(anArray);
//need to print out is this a square array? true
Array2DMethods.displayOutputs(anArray);
//need it to be formatted like [10, 20, 30] etc
}
}
Assuming you want anArray to be the array you read in during your inputting, you should name that variable, as such...
public static void main(String[] args){
System.out.println("Let's create a 2Dim Array!");
int[][] anArray = Array2DMethods.readInputs();
System.out.println("max " + Array2DMethods.max(anArray));
Array2DMethods.rowSum(anArray);
Array2DMethods.columnSum(anArray);
System.out.println("Square " + Array2DMethods.isSquare(anArray));
Array2DMethods.displayOutputs(anArray);
}
Say you have a function f which takes a single input x. The problem is you're asking the computer to evaluate f(x) without ever telling it what x is. If you give x a value, however, such as x = 3, then asking f(x) becomes legal, because it becomes f(3), which can be evaluated.

Categories