I am not sure if it's rly possible to check but I have an issue rn where I have an array
let's say: int[] unmarkedSum = new int[100];
Now I put something in this array when a certain condition is true so not in every single iteration. But I know for a fact that at some point the whole array will be filled with any positive values that are not 0 because of how my algorithm works.
My question here is: Is there a way of checking WHEN it's fully filled?
Like I started like this:
for(int i = 0; i < unmarkedSum.length; i++) {
if(unmarkedSum[i] == 0 {
break;
}
else {
// idk tbh
}
}
In Java by default an array of ints is filled with zeros. You can use this to check if the array is fully filled. For example you can create a method which checks for 0 and returns true if there are no 0:
public static bool isArrayFilled(int[] array) {
for(int i = array.length; i >= 0; i--){
if(array[i] == 0) {
return false;
}
}
return true;
}
If array is big enough and filled out of order, you can use advanced algorithms to find at least one 0 value in the array.
I would simply maintain a variable size that keep tracks of how many values have been written to the array.
Example:
int size = 0;
int[] array = new int[100];
Random r = new Random();
while(size < array.length){
int index = r.nextInt(100);
int val = r.nextInt(1000)+500;
if (array[index] == 0){
array[index] = val;
size++;
}
}
System.out.println(Arrays.toString(array));
Per my previous comment, you can share this array with another thread so that one thread can fill the values and another can check the array at the same time. When the second thread finds that there are no default values (or 0s) then it can notify the first thread (or the main thread). Here is how you can do that
import java.util.Arrays;
import java.util.Random;
public class CheckArray {
public static void main(String[] args) throws InterruptedException {
var arr = new int[50];
Thread arrayChecker = new Thread(() -> {
var isZeroPresent = false;
while (true) {
for (int index = 0; index < arr.length; index++) {
isZeroPresent = false;
if (arr[index] == 0) {
isZeroPresent = true;
break;
}
}
if (isZeroPresent == false) {
// if the for loop completed then control will come here
System.out.println("Array has been filled");
System.out.println(Arrays.toString(arr));
System.exit(0);
}
}
});
arrayChecker.start();
// fill random values in the array
// while another thread has been started
Random random = new Random();
while(true) {
Thread.sleep(500);
int index = random.nextInt(arr.length);
arr[index] = random.nextInt(100);
System.out.println(Arrays.toString(arr));
}
}
}
Related
I'm trying to learn a bit Java with tutorials and currently I'm struggling with piece of code where I should find on which index is difference between arrays (if there is difference at all)
My code
Scanner scanner = new Scanner(System.in);
int[] arrOne = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int[] arrTwo = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int sumArrOne = 0;
int index = 0;
boolean diff = false;
for (int k : arrOne) {
if (Arrays.equals(arrOne, arrTwo)) {
sumArrOne += k;
} else {
for (int i : arrTwo) {
if (k != i) {
index = i;
diff = true;
break;
}
}
}
}
if (diff) {
System.out.println("Found difference at " + index + " index.");
} else {
System.out.println("Sum: " + sumArrOne);
}
So, if arrays are identical I'm sum array elements in arrOne. If they are not identical -> must show at which index they are not.
With this code when I input
1 2 3 4 5
1 2 4 3 5
I should get that difference is at index 2 instead I've got index 1.
I'm not quite sure why and would be glad if someone point me out where is my mistake.
I updated your code. Looks like you're misunderstanding the concept of indexes yet.
Use one common index to check with in both arrays, in my example it's simply called i:
import java.util.Arrays;
import java.util.Scanner;
public class BadArray {
static private final int INVALID_INDEX = Integer.MIN_VALUE;
public static void main(final String[] args) {
try (final Scanner scanner = new Scanner(System.in);) {
final int[] arrOne = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
final int[] arrTwo = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int sumArrOne = 0;
int diffIndex = INVALID_INDEX;
final int minLen = Math.min(arrOne.length, arrTwo.length);
for (int i = 0; i < minLen; i++) {
sumArrOne += arrOne[i];
if (arrOne[i] != arrTwo[i]) {
diffIndex = i;
break;
}
}
if (diffIndex != INVALID_INDEX) {
System.out.println("Found difference at " + diffIndex + " index.");
} else if (arrOne.length != arrTwo.length) {
System.out.println("Arrays are equal but have different length!");
} else {
System.out.println("Sum: " + sumArrOne);
}
}
}
}
I also put the scanner into a try-resource-catch to handle resource releasing properly.
Note you could also do the array lengths comparison right at the start if different array lengths play a more crucial role.
You are trying to find out which index has the first difference so you should iterate via the index rather than using a for-each loop (aka enhanced for loop). The following method should work for this.
/**
* Returns the index of the first element of the two arrays that are not the same.
* Returns -1 if both arrays have the same values in the same order.
* #param left an int[]
* #param right an int[]
* #return index of difference or -1 if none
*/
public int findIndexOfDifference(int[] left, int[] right) {
// short-circuit if we're comparing an array against itself
if (left == right) return -1;
for (int index = 0 ; index < left.length && index < right.length ; ++index) {
if (left[index] != right[index]) {
return index;
}
}
return -1;
}
In your code you compare, where the indexes are different, not the values at the indexes. Also your code has several other issues. I'll try to go through them step by step:
// compare the whole array only once, not inside a loop:
diff = !Arrays.equals(arrOne, arrTwo));
if (!diff) {
// do the summing without a loop
sumArrOne = Arrays.stream(arrOne).sum();
} else {
// find the difference
// it could be the length
index = Math.min(arrOne.length, arrTwo.length);
// or in some different values
for (int i = 0; i < index; i++) { // do a loop with counter
if (arrOne[i] != arrTwo[i]) {
index = i;
break;
}
}
}
It doesn't matter that I set index here above the loop as it's value will be overwritten anyways inside the loop, if relevant.
i new to Java, i want to know if its possible to access a array of size 0?I in a Java course and there a problem to solve where we need to calculate the sum of all element in a array,and if this sum is bigger than 100, we return true. We also need to calculate only positive number, no negative,and finally the code must work even if the array is empty. That my code here:
public static boolean biggerOrLower(){
int data[] =new int[0];
//data = new int[] {0,0,0,0,44,44,66,66,33,444,555,453,};
int iterator = 0;
boolean exced = false;
int sum = 0;
while(iterator < data.length)
{
if(iterator > 0) {
sum = sum + data[iterator];
if (sum > 100) {
exced = true;
break;
}
}
else
{
exced = false;
}
System.out.println(sum);
iterator++;
}
System.out.println(exced);
return exced;
}
}
The problem is, since iterator is = 0 , and the length of data is also 0, it never enter the while loop, but it need too, and if i change the code to while (iterator <= data.length) i got a Exception Index 0 out of bounds for length 0.
Can somebody tell why that happen and how i ca fix that?
Thank
im also a bit new to java but i think this will work
public static boolean biggerOrLower(){
int data[] =new int[0];
//data = new int[] {0,0,0,0,44,44,66,66,33,444,555,453,};
boolean exced = false;
int sum = 0;
for(int i: data){
if(i > 0){ sum += i}
}
exced = sum > 100;
System.out.println(sum);
System.out.println(exced);
return exced;
}
i don't think you need to enter the loop and i believe a for loop is much better at solving this problem
Why do you have to enter the while loop. I don't see it is necessary. You cannot access something that is empty. If you want to execute some code if the array is of size 0 you can do that with an if clause.
I have a random set S of integers and the cardinality (n) of this set may vary from 10 to 1000. I need to store all sums of the nCr combinations of size r generated from this set. Usually r range from 3 to 10.
E.g. if S={102,233,344,442,544,613,71289,836,97657,12} and r=4, Then The sums generated will be {0,1,2,3}=102+233+344+442, {0,1,2,4}=102+233+344+544,....so on.
I implemented a findCombi function (below) in Java which gave me all nCr combinations in terms of r sized sets of indices and then I sifted through these sets in another function to generate the sum of corresponding elements.
But the program is giving heapspace error, probably because of exponential nature and I have 100-5000 of such sets, S. Or may be there is a memory leak?
Is there a faster and lesser-memory consuming way to do it?
Note: dsize=n, combiSize=r
List <List<Integer>> findCombi(int dsize,int combiSize) {
if( (combiSize==0) || (dsize==0) ){
return null;
}
long n=dsize;
int r=combiSize;
for(int i=1;i<combiSize;i++) {
n=n*(dsize-i);
r=r*i;
}
int totalcombi=(int) n/r;
List <List<Integer>> combiData=new ArrayList<>(totalcombi);
int pos;
List <Integer> combi=new ArrayList<>(combiSize);
for(int i=0;i<combiSize;i++) {
combi.add(i,i);
}
combiData.add(new ArrayList<>(combi));
pos=combiSize-1;
while(true) {
if(combi.get(pos)<(dsize-combiSize+pos)) {
combi.set(pos,combi.get(pos)+1);
if(pos==(combiSize-1)) {
combiData.add(new ArrayList<>(combi));
}
else {
combi.set(pos+1,combi.get(pos));
pos++;
}
}
else {
pos--;
}
if(pos==-1) {
break;
}
}
return combiData;
}
I needed something like that earlier, so here is some code adapted from the project I made back then. The method allSums builds a list of indices of size r, which is used to represent all the possible combinations. At each step, the current sum is added to the result set, then the next combination is generated. Since the results are put in a set, there is no way a result could appear twice. I included a main method so you can see it work. I hope this is clear, feel free to ask questions.
import java.util.*;
public class Program {
static private Set<Integer> allSums(List<Integer> values, int r) {
HashSet<Integer> res = new HashSet<>();
if ((values.isEmpty()) || r > values.size()) {
return res;
}
// build the list of indices
List<Integer> li = new ArrayList<>();
for (int i = 0; i < r; i++) {
li.add(i);
}
li.add(values.size()); // artificial last index : number of elements in set
while (true) {
// add the current sum to the result
int sum = 0;
for (int i = 0; i < r; i++) {
sum += values.get(li.get(i));
}
res.add(sum);
// move to the next combination
// first, find the last index that can be incremented
int i = r-1;
while ((i >= 0) && (li.get(i) == li.get(i+1)-1)) {
i--;
}
// was such an index found ?
if (i == -1) {
break; // if not, it's over
}
// increment the last index and set all the next indices to their initial value
li.set(i,li.get(i)+1);
for (int j = i+1; j < r; j++) {
li.set(j, li.get(j-1)+1);
}
}
return res;
}
public static void main(String[] args) {
List<Integer> values = new ArrayList<>();
values.add(10);
values.add(100);
values.add(1000);
values.add(10000);
values.add(100000);
Set<Integer> s = allSums(values, 3);
for (int i : s) {
System.out.println(i);
}
}
}
This question already has answers here:
Java generating non-repeating random numbers
(12 answers)
Closed 9 years ago.
I am trying to write a guessing game program where a 4 digit number is randomly generated. The numbers need to be unique (as in they do not repeat at any time) I am fairly new to Java and I am having trouble displaying the numbers in an array. Also I can't figure out a way to check a number against the others more than once. EX: If random number A is the same as random number B it will make a new random number A. But I dont know how to check if the NEW random A is the same as number B without writing the same code over and over and over. (clearly some kind of loop but I have no idea which kind)
import java.util.Random;
public class Game {
public static void main(String[] args) {
// TODO Auto-generated method stub
int rand1 = 0;
int rand2 = 0;
int rand3 = 0;
int rand4 = 0;
int[] randArray = new int[]{rand1, rand2, rand3, rand4};
Random randy = new Random();
int a = randy.nextInt(9);
int b = randy.nextInt(9);
int c = randy.nextInt(9);
int d = randy.nextInt(9);
//how to check the variable more than one time?
a = rand1;
if (b == a) {
b = randy.nextInt(9);
}
else rand2 = b;
if (c == a || c == b) {
c = randy.nextInt(9);
}
else rand3 = c;
if (d == a || d == b || d == c) {
d = randy.nextInt(9);
}
else rand4 = d;
System.out.print(randArray); //prints gibberish
//prints the numbers fine
//System.out.print(rand1);
//System.out.print(rand2);
//System.out.print(rand3);
//System.out.print(rand4);
}
}
You might first add the random numbers to a java.util.HashSet and then convert it to an array. This way you get rid of all duplicates.
How about using an ArrayList instead?
The syntax is different, but then you can do your program in a looping fashion.
For example:
ArrayList<Integer> randNums = new ArrayList();
while(randNums.size() != 4) {
int a = randy.nextInt(9);
if(false == randNums.contains(a))
randNums.add(a);
}
Edit to add a side note: ArrayList has the prettier printing you are looking for as well.
If you want to change your current array type to Integer instead of an int then i suggest you to take one of the other answers. My first instinct was to show you how clean, readable and simple it will be if you used ArrayList<Integer> and its power and then convert it to Integer[] again no int[].
At the end i decided to wrote you an answer, that may not be the most elegant and defentily not the shortest one, but it will teach you how to think right before you could use tools that will take those element off (ArrayList and its powers as we said).
The algorithm is quite simple.
You create int-array at the n size you needed.
You iterate over it from 0 to n and with every iteration you:
A. Creating a do-while loop that will generate a random number from 0-9.
B. Generate a random temp number from 0-9.
C. Iterating over your current readArray to look-up if the generated number is inside, and if so it will flag it and stop the look-up process (because we found that we already have it).
D. Will check if the flag isExists set as true, if so, then will go into step B again otherwise will go to step 3.
If we reached to the end of look-up(for) without changing flag to true, than the temp(generated number) is not at our current array, and it will be safe to add it.
Will check if we reach to the end of the array or there are more array cell to fill. i < readArray.length.
Code:
Random randy = new Random();
int[] readArray = new int[4];
for (int i = 0; i < readArray.length; i++) {
int temp;
boolean isExists;
do {
isExists = false;
temp = randy.nextInt(10);
for (int j = 0; j < i; j++)
{
if (readArray[j] == temp)
{
isExists = true;
break;
}
}
} while (isExists);
readArray[i] = temp;
}
System.out.println(Arrays.toString(readArray));
If you're OK with storing in memory an 'int' array of 10000 entries:
public class YourClass
{
private static int final SIZE = 10000;
private int[] array = new int[SIZE];
private int currIteration = 0;
private Random random = new Random();
public YourClass()
{
for (int i=0; i<SIZE; i++)
array[i] = i;
}
public int getRandVal()
{
int index = random.nextInt(SIZE-currIteration);
int val = array[index];
array[index] = array[SIZE-currIteration-1];
array[SIZE-currIteration-1] = val;
if (++currIteration == SIZE)
currIteration = 0;
return val;
}
}
For generating random unique integers
Use a Set to create a collection of unique values. Otherwise, for each random number generated, iterate over the array to ensure it's unique before adding it.
Integer[] createGuesses(int numGuesses, int low, int high)
{
Set<Integer> guesses = new HashSet<>();
Random rand = new Random();
while(guesses.size() < numGuesses)
guesses.add(low + rand.nextInt(high - low));
return guesses.toArray(new Integer[numGuesses]);
}
I've just been looking at the following piece of code
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(final String[] args) {
final int sizeA = 3;
final int sizeB = 5;
final List<int[]> combos = getAllCombinations(sizeA-1, sizeB);
int counter = 1;
for(final int[] combo : combos) {
System.out.println("Combination " + counter);
System.out.println("--------------");
for(final int value : combo) {
System.out.print(value + " ");
}
System.out.println();
System.out.println();
++counter;
}
}
private static List<int[]> getAllCombinations(final int maxIndex, final int size) {
if(maxIndex >= size)
throw new IllegalArgumentException("The maximum index must be smaller than the array size.");
final List<int[]> result = new ArrayList<int[]>();
if(maxIndex == 0) {
final int[] array = new int[size];
Arrays.fill(array, maxIndex);
result.add(array);
return result;
}
//We'll create one array for every time the maxIndex can occur while allowing
//every other index to appear, then create every variation on that array
//by having every possible head generated recursively
for(int i = 1; i < size - maxIndex + 1; ++i) {
//Generating every possible head for the array
final List<int[]> heads = getAllCombinations(maxIndex - 1, size - i);
//Combining every head with the tail
for(final int[] head : heads) {
final int[] array = new int[size];
System.arraycopy(head, 0, array, 0, head.length);
//Filling the tail of the array with i maxIndex values
for(int j = 1; j <= i; ++j)
array[size - j] = maxIndex;
result.add(array);
}
}
return result;
}
}
I'm wondering, how do I eliminate recursion from this, so that it returns a single random combination, rather than a list of all possible combinations?
Thanks
If I understand your code correctly your task is as follows: give a random combination of numbers '0' .. 'sizeA-1' of length sizeB where
the combination is sorted
each number occurs at least once
i.e. in your example e.g. [0,0,1,2,2].
If you want to have a single combination only I'd suggest another algorithm (pseudo-code):
Randomly choose the step-up positions (e.g. for sequence [0,0,1,1,2] it would be steps (1->2) & (3->4)) - we need sizeA-1 steps randomly chosen at sizeB-1 positions.
Calculate your target combination out of this vector
A quick-and-dirty implementation in java looks like follows
// Generate list 0,1,2,...,sizeB-2 of possible step-positions
List<Integer> steps = new ArrayList<Integer>();
for (int h = 0; h < sizeB-1; h++) {
steps.add(h);
}
// Randomly choose sizeA-1 elements
Collections.shuffle(steps);
steps = steps.subList(0, sizeA - 1);
Collections.sort(steps);
// Build result array
int[] result = new int[sizeB];
for (int h = 0, o = 0; h < sizeB; h++) {
result[h] = o;
if (o < steps.size() && steps.get(o) == h) {
o++;
}
}
Note: this can be optimized further - the first step generates a random permutation and later strips this down to desired size. Therefore it is just for demonstration purpose that the algorithm itself works as desired.
This appears to be homework. Without giving you code, here's an idea. Call getAllCombinations, store the result in a List, and return a value from a random index in that list. As Howard pointed out in his comment to your question, eliminating recursion, and returning a random combination are separate tasks.