Sometimes the program runs fine and sometimes program doesn't do anything - java

I am trying to get a program to make 2 arrays of random numbers and then use the bubble method to sort them so later I can easily pick out the 3 middle numbers. When I retarded eclipse and ran it for the first time, but whenever I try to run it again the console displayed nothing, and I assume the program is still running because I have the option to terminated.
import java.util.Arrays;
import java.util.Random;
public class DiversCalc {
public static void main(String[] args){
int[] Diver1 = new int[7];
int[] Diver2 = new int[7];
Random rand = new Random();
for (int positionInArray = 0; positionInArray < Diver1.length;
positionInArray++) {
int diverScore1 = rand.nextInt(10);
Diver1[positionInArray] = diverScore1;
}
for (int positionInArray2 = 0; positionInArray2 < Diver2.length;
positionInArray2++) {
int diverScore1 = rand.nextInt(10);
Diver2[positionInArray2] = diverScore1;
}
int temp = 0;
boolean checker = false;
boolean checker2 = false;
while(checker==false){
checker=true;
for(int positionCheck1 = 0; positionCheck1 < Diver1.length-1;
positionCheck1++){
if(Diver1[positionCheck1] > Diver1[positionCheck1+1]){
temp = Diver1[positionCheck1+1];
Diver1[positionCheck1+1] = Diver1[positionCheck1];
Diver1[1] = temp;
checker=false;
}
}
}
while(checker2==false){
checker2=true;
for(int positionCheck2 = 0; positionCheck2 < Diver2.length-1;
positionCheck2++){
if(Diver2[positionCheck2] > Diver2[positionCheck2+1]){
temp = Diver2[positionCheck2+1];
Diver2[positionCheck2+1] = Diver2[positionCheck2];
Diver2[1] = temp;
checker2=false;
}
}
}
System.out.println(Arrays.toString(Diver1));
System.out.println(Arrays.toString(Diver2));
}
}

Do you mean to always set the second position at Diver1 to be the temp variable?
Because that is what you are doing by saying Diver1[1] = temp. Maybe try saying something like Diver1[positionCheck2] = temp instead. This applies to both of your spots that you are attempting the sort.
Also, I do not believe your bubble sort is a full bubble sort. It seems to only make one iteration over the array of numbers, bubbling the max value to the end of the array and then stopping. A full bubble sort would continue these iterations, moving the max element all the way to the end, then moving the second max element to the second spot from the end, then moving the third max element to the third spot from the end, etc. until sorted.
Update:
Your code is never reaching the print statements because it is getting stuck in your while loop. while(checker==false) continues to be false, so it never exists the loop. As I mentioned above, fix your "swap" and eventually this should resolve.

Related

Program entering in a infinite loop only with a specific value

I just started with java and while was doing an exercise about permutations (the exercise asked to create a permutation of N elements using an array a[] meeting the requirement that no a[i] is equal to i.) I've created the following code. While testing it, I realized that it entered in a infinite loop sometimes when N = 6 specifically.
Any thoughts on where is the problem?
public class GoodPerm {
public static void main(String arg[]) {
int n = Integer.parseInt(arg[0]);
int[] guests = new int[n];
for (int i = 0; i < n; i++) {
guests[i] = i;
}
for (int i = 0; i < n; i++) {
int r = i + (int) (Math.random() * (n - i));
int q = guests[r];
guests[r] = guests[i];
guests[i] = q;
if(guests[i] == i){
i --;
}
}
for(int q : guests){
System.out.println(q);
}
}
}
Maybe the code enters in a inf-loop in another values, but I didn't found any others.
This code can always enter an inf-loop. As I understand the code, you try to do some random switches to achieve your needed result. But if the last element of your array has never been switched, it won't be possible to switch it to any "later/higher" position (because there are no more). In the "last" iteration of your second for-loop (so i + 1 == n holds at the beginning) r will always evaluate to i thus no real switch happens. If the last element is still in place, you gonna repeat this forever.

Why does this program not stop duplicates in the array?

I'm trying to write a program that generates six random integers, and return them to the user without any of the numbers being duplicates. Why do duplicates still get through?
I've searched it up on Google and tried a few of the results, but none of them seemed to work. I thought of my own method to try to solve this issue, by doing the following:
Using a for loop, I store one number at a time from drawnNums (the array with six random numbers) in numToCheck. There is also a variable numOfDuplicates which stores how many of that number it found. Using another for loop, I go through all the numbers in drawnNums and compare it with numToCheck, and add one to numOfDuplicates. It obviously finds itself, so I have an if statement that only redraws numbers if numOfDuplicates is >= 2. This is in the same function where I create the array, so it should create a new array and check through again, redrawing until there are no duplicates.
In my mind, this should stop duplicates from being returned, but it doesn't.
This is from class I have created to generate the array, and what I described above.
// Private function to draw one random number
private int drawNumber() {
return random.nextInt(maxNum) + 1;
}
// Function to randomly draw six numbers using drawNumber() and store in an array
int[] draw() {
int[] drawnNums = {0, 0, 0, 0, 0, 0};
for (int i = 0; i < drawnNums.length; i++) {
int draw = drawNumber();
drawnNums[i] = draw;
}
// Check if there are any duplicates in the array, if there are, redraw
int numOfDuplicates = 0;
for (int x = 0; x < drawnNums.length; x++) {
int numToCheck = drawnNums[x];
numOfDuplicates = 0;
for (int y = 0; y < drawnNums.length; y++) {
if (numToCheck == drawnNums[y]) {
numOfDuplicates++;
}
if (numOfDuplicates >= 2) {
draw();
}
}
break;
}
return drawnNums;
}
}
I expect that if there are duplicates in the array, the numbers will be redrawn until there is an array with no duplicates. But when running the program repeatedly, there are still some arrays with duplicates in them.
Your recursive call to draw is not returning a value. Should be
return draw();
The outer check loop exits early without completely checking the entire array for duplicates, remove the break. Check if x==y in the inner loop, do the duplicate check only if they are not.
Or in java 8, use a one liner to replace the entire thing.
new Random().ints(start, end).distinct().limit(number).toArray();
Ref - Random number generator without replacement?
You want to check for duplicates within your returnable Array before you add to it. In other words, as soon as the draw variable receives a new random value see if that value is already contained within the drawnNums array:
private int[] draw() {
int[] drawnNums = {0, 0, 0, 0, 0, 0};
boolean alreadyHave;
for (int i = 0; i < drawnNums.length; i++) {
int draw = drawNumber();
alreadyHave = false;
for (int j = 0; j < drawnNums.length; j++) {
if (draw == drawnNums[j]) {
alreadyHave = true;
i--;
break;
}
}
if (!alreadyHave) {
drawnNums[i] = draw;
}
}
return drawnNums;
}
If you want uniqueness, it's easiest to use a container that gives you uniqueness.
int[] draw() {
final int COUNT = 6;
// get unique numbers
Set<Integer> nums = new HashSet<>();
while (nums.size() != COUNT)
nums.add(drawNumber());
// convert to array as per original requirements
// though it would be simpler if we could just
// return a Collection<Integer>
int[] result = new int[COUNT];
int k = 0;
for (Integer num : nums)
result[k] = num;
return result;
}
Simpler, by a change of return type, with no loss of usefulness to the caller:
Collection<Integer> draw() {
final int COUNT = 6;
Set<Integer> nums = new HashSet<>();
while (nums.size() != COUNT)
nums.add(drawNumber());
return nums;
}

How to return the largest integer in an Array that has 10 random integers in it?

So this is a coding question from school I have, I don't want to say "hey guys do my homework for me!", I actually want to understand what's going on here. We just started on arrays and they kind of confuse me so I'm looking for some help.
Here's the complete question:
Write a program in which the main method creates an array with
10 slots of type int. Assign to each slot a randomly-generated
integer. Call a function, passing it the array. The called
function should RETURN the largest integer in the array to
your main method. Your main method should display the number
returned. Use a Random object to generate integers. Create it
with
Random r = new Random(7);
Generate a random integer with
x = r.nextInt();
So, here's what I have so far:
import java.util.Random;
public class Q1 {
public static void main(String[] args) {
Random r = new Random(7);
int[] count = new int[11];
int x = r.nextInt();
for (int i = 0; i < count.length; i++)
{
count[i] = x;
}
}
I created that array with 10 ints, then used a for loop to assign each slot that randomly generated integer.
I'm having a hard time for what to do next, though. I'm not sure what kind of method / function to create and then how to go from there to get the largest int and return it.
Any help is really appreciated because I really want to understand what's going on here. Thank you!
Here is how to generate Random ints
public static void main(String[] args) {
int []count = new int[10];
Random r = new Random(7);
int x=0;
for (int i = 0; i < count.length; i++)
{
x = r.nextInt();
count[i] = x;
}
System.out.println("Max Number :"+maxNumber(count));}//Getting Max Number
Here is how to make method and get max number from list.
static int maxNumber(int[] mArray){//Passing int array as parameter
int max=mArray[0];
for(int i=0;i<mArray.length;i++){
if(max<mArray[i]){//Calculating max Number
max=mArray[i];
}
}
return max;//Return Max Number.
}
Ask if anything is not clear.
This is how we make method which return int.
You can do it by using a simple for loop for the Array.
First you have to create a seperate int variable (eg: int a) and assign value zero (0) and at each of the iterations of your loop you have to compare the array item with the variable a. Just like this
a < count[i]
and if it's true you have to assign the count[i] value to the variable a . And this loop will continue until the Array's last index and you will have your largest number in the a variabe. so simply SYSOUT the a variable
Important: I didn't post the code here because I want you to understand the concept because If you understand it then you can solve any of these problems in future by your self .
Hope this helps
What you have got so far is almost correct, but you currently are using the same random number in each iteration of your for-loop. Even though you need to get a new random number for each iteration of your for-loop. This is due to how the Random object is defined. You can achieve this by changing your code the following way:
import java.util.Random;
public class Q1 {
public static void main(String[] args) {
Random r = new Random(7);
int[] count = new int[11];
for (int i = 0; i < count.length; i++)
{
int x = r.nextInt(); // You need to generate a new random variable each time
count[i] = x;
}
}
Note that this code is not optimal but it is the smallest change from the code you already have.
To get the largest number from the array, you will need to write another for-loop and then compare each value in the array to the largest value so far. You could do this the following way:
int largest = 0; // Assuming all values in the array are positive.
for (int i = 0; i < count.length; i++)
{
if(largest < count[i]) { // Compare whether the current value is larger than the largest value so far
largest = count[i]; // The current value is larger than any value we have seen so far,
// we therefore set our largest variable to the largest value in the array (that we currently know of)
}
}
Of course this is also not optimal and both things could be done in the same for-loop. But this should be easier to understand.
Your code should be something like this. read the comments to understand it
public class Assignment {
public static int findMax(int[] arr) { // Defiine a function to find the largest integer in the array
int max = arr[0]; // Assume first element is the largest element in the array
for (int counter = 1; counter < arr.length; counter++) // Iterate through the array
{
if (arr[counter] > max) // if element is larger than my previous found max
{
max = arr[counter]; // then save the element as max
}
}
return max; // return the maximum value at the end of the array
}
public static void main(String[] args) {
int numberofslots =10;
int[] myIntArray = new int[numberofslots]; // creates an array with 10 slots of type int
Random r = new Random(7);
for (int i = 0; i < myIntArray.length; i++) // Iterate through the array 10 times
{
int x = r.nextInt();
myIntArray[i] = x; // Generate random number and add it as the i th element of the array.
}
int result = findMax(myIntArray); // calling the function for finding the largest value
System.out.println(result); // display the largest value
}
}
Hope you could understand the code by reading comments..
This can be done in one simple for loop no need to have 2 loops
public static void main(String[] args) {
Integer[] randomArray = new Integer[10];
randomArray[0] = (int)(Math.random()*100);
int largestNum = randomArray[0];
for(int i=1; i<10 ;i++){
randomArray[i] = (int)(Math.random()*100);
if(randomArray[i]>largestNum){
largestNum = randomArray[i];
}
}
System.out.println(Arrays.asList(randomArray));
System.out.println("Largest Number :: "+largestNum);
}
Initialize max value as array's first value. Then iterate array using a for loop and check array current value with max value.
OR you can sort the array and return. Good luck!
Here's a basic method that does the same task you wish to accomplish. Left it out of the main method so there was still some challenge left :)
public int largestValue(){
int largestNum;
int[] nums = new int[10];
for (int n = 0; n < nums.length; n++){
int x = (int) (Math.random() * 7);
nums[n] = x;
largestNum = nums[0];
if (largestNum < nums[n]){
largestNum = nums[n];
}
}
return largestNum;
}

Why is my java program printing zero every time?

I am required to take an array of size x (which contains numbers starting at x and then descending down to 1), and then, with a new array of size y (which may or may not be the same size as x), print out random numbers from array x into array y. I wrote the program and it runs fine, but for some reason in the list of random numbers outputted, the number 0 will show up. Does anybody know why this is happening? Here is my code:
import java.util.Random;
public class Prog1A
{
public static void main(String[] args)
{
System.out.println("Program 1A, Christopher Moussa, masc1574");
Random randGen = new Random();
int[] arr_1 = new int[8];
for (int i = arr_1.length - 1; i >= 0; i--)
{
arr_1[i] = arr_1[i];
}
int[] arr_2 = new int[6];
for (int i = 1; i <= arr_2.length; i++)
{
System.out.print(randGen.nextInt(arr_1.length) + " ");
}
}
}
Any feedback will be greatly appreciated, thank you.
Well you aren't doing anything with this loop. You're essentially assigning a variable to itself right throughout the array. Also, I dislike the way you wrote your loop condition, but my preference isn't the issue here.
for (int i = arr_1.length - 1; i >= 0; i--)
{
arr_1[i] = arr_1[i]; //This code does nothing
}
Then you create arr_2[] but you never assign anything to the variables.
I went ahead and edited your code, and I'll explain a few things.
import java.util.Random;
public class Prog1A
{
public static void main(String[] args)
{
Random randGen = new Random();
int[] arr_1 = new int[8];
int[] arr_2 = new int[6];
System.out.println("Program 1A, Christopher Moussa, masc1574");
//Assigns a random number to each member of arr_1
for (int i = 0; i < arr_1.length; ++i)
{
arr_1[i] = randGen.nextInt(arr_1.length);
}
//Copies arr_1 values to arr_2
for (int i = 0; i < arr_2.length; ++i) //Counting up [0 to 5]
{
arr_2[i] = arr_1[i];
}
for (int i = 0; i < arr_2.length; ++i)
{
System.out.print(arr_2[i] + " ");
}
}
}
Always (if possible) declare all variables at the start of a function/class/program. It keeps code a lot cleaner and helps you to identify possible errors that may occur.
Keep your loop parameters consistent. Start from 0 and go up always, or start from the last value and go down. It eliminates the possibility of an error again. I prefer starting from 0 always but it is up to you, as long as it is clean and it works.
Unless you initialize an array, it is going to be empty. If you try to print from it you'll most likely see zeros.
Just add one to your result, The length of your array is 8. With your current code your are returning a random number between 0 and 7. The nextInt method will never return the upper limit of the integer value supplied. You can test this out yourself by exchanging the arr_1.length for a different number like 10 for example and then remove the + 1. You will notice that it will only return the number 9 at the most and 0 will be the lowest number returned.
System.out.print((randGen.nextInt(arr_1.length) + 1) + " ");

Unexpected Java performance

I have just thrown everything I know about Java optimisation out the window. I have the following task:
Given a 2D array representing a playing field and a position on the field, fill another array with the number of steps a player can make to get to every other position in the field. The player can move up, down, left and right. For example, the first neighbours will be all 1's, with the diagonals being all 2's.
For the first attempt, I tried a simple 4-way floodfill algorithm. It wad dreadfully slow.
Secondly, I decided to get rid of the recursion and use a simple Queue. It worked lovely and gave a huge speed-up (very roughly 20x). Here is the code:
private void fillCounterArray(int[] counters, int position) {
Queue<Integer> queue = new ArrayDeque<Integer>(900);
// Obtain the possible destinations from position, check the valid ones
// and add it the stack.
int[] destination = board.getPossibleDestinations(position);
for (int i = 0; i < destination.length; i++) {
if (board.getBoard()[destination[i]] == Board.CLEAR) {
counters[destination[i]] = 1;
queue.add(destination[i]);
}
}
// Now fill up the space.
while (!queue.isEmpty()) {
int pos = queue.remove();
int steps = counters[pos];
destination = board.getPossibleDestinations(pos);
for (int i = 0; i < destination.length; i++) {
int dest = destination[i];
if (board.getBoard()[dest] == Board.CLEAR && (counters[dest] > steps + 1 || counters[dest] == 0)) {
counters[dest] = steps + 1;
queue.add(dest);
}
}
}
}
Now, "common-sense" told me that the queue operations with a static array and an int-pointer would be faster. So I removed the Queue and use a standard int[] array. The code is identical, except for the queue-like operations. It now looks like this (As you can see, I use to live by the C-side :)):
private void fillCounterArray(int[] counters, int position) {
// Array and its pointer.
int[] queue = new int[900]; // max size of field
int head = 0;
// Obtain the possible destinations from position, check the valid ones
// and add it the stack.
int[] destination = board.getPossibleDestinations(position);
for (int i = 0; i < destination.length; i++) {
if (board.getBoard()[destination[i]] == Board.CLEAR) {
counters[destination[i]] = 1;
queue[head++] = dest[i];
}
}
// Now fill up the space.
while (head > 0) {
int pos = queue[--head];
int steps = counters[pos];
destination = board.getPossibleDestinations(pos);
for (int i = 0; i < destination.length; i++) {
int dest = destination[i];
if (board.getBoard()[dest] == Board.CLEAR && (counters[dest] > steps + 1 || counters[dest] == 0)) {
counters[dest] = steps + 1;
queue[head++] = dest;
}
}
}
}
When I ran this "optimised code" it was significantly slower than using the Queue and only about twice as fast as the recursive technique. There is also hardly any difference when I declare the array as an instance variable. How is this possible?
Your reversed the order while optimising I think;
The queue is fifo, first in first out
The array is lifo, last in first out, as you walk it downwards
That will usually give you different performance ;-)
Insert two Counters in each Loop one in the for loop and one in the while loop in both versions, compare the numbers you get at the end, how many rounds do you make in each version, if you have another Loop in getPossibleDestination then log the pos variable too.
I guess that would be a good starting point to figure it out.
Another way would be to print the time difference on different lines in your program, let say before the 1st loop, between both and at the end, once you compare results and know where it takes a long time in the second Version you can print timestamps in the loop on different lines.

Categories

Resources