Beginner Looking for Guidance on Methods - java

I am trying to complete a project where we have to take a set of data of random numbers between 0 and 364 and see what percentage of the runs (the method takes the number of items in the data set and the number of runs) have a duplicate number in them.
Below is what I have so far, but I am really struggling to figure out how to do this as I keep getting errors:
public double calculate(int size, int count) {
double percentage;
int matches = 0;
int check;
int i = 0;
int add = 0;
Random rnd = new Random();
List<Integer> birthdays = new ArrayList<>();
for (int k = 1; k <= count; k++){
rnd.setSeed(k);
do{
add = rnd.nextInt(365);
birthdays.add(add);
i++;
}while (i < size-1);
//birthdays.add(rnd.nextInt());
for (int j = 0; j <= size-1; j++) {
check = birthdays.get(j);
if (birthdays.indexOf(check) != birthdays.lastIndexOf(check)) {
matches++;
j = size;
}
}
}
percentage = (double)matches / count * 100;
//percentage = 8;
return percentage;
}

There are a couple of problems with your code here. One is the while loop directly after the first for loop that doesn't seem to be doing anything. It says:
while(i < size-1);
That might be giving you an error, but error you are talking about is probably from your second for loop. When you instantiate it you say:
for (int j = 0; j <= size-1; j++)
but then you say:
j = size;
since when you instantiate it you say j<=size-1 but then you set j=size it will give an error.

Related

How to reduce the number of loops if there is no change?

This code is radix sort in Java.
Now I can sort. But I want to reduce its functionality if there is no change in the
array, let it stop the loop and show the value.
Where do I have to fix it? Please guide me, thanks in advance.
public class RadixSort {
void countingSort(int inputArray[], int size, int place) {
//find largest element in input array at 'place'(unit,ten's etc)
int k = ((inputArray[0] / place) % 10);
for (int i = 1; i < size; i++) {
if (k < ((inputArray[i] / place) % 10)) {
k = ((inputArray[i] / place) % 10);
}
}
//initialize the count array of size (k+1) with all elements as 0.
int count[] = new int[k + 1];
for (int i = 0; i <= k; i++) {
count[i] = 0;
}
//Count the occurrence of each element of input array based on place value
//store the count at place value in count array.
for (int i = 0; i < size; i++) {
count[((inputArray[i] / place) % 10)]++;
}
//find cumulative(increased) sum in count array
for (int i = 1; i < (k + 1); i++) {
count[i] += count[i - 1];
}
//Store the elements from input array to output array using count array.
int outputArray[] = new int[size];
for (int j = (size - 1); j >= 0; j--) {
outputArray[count[((inputArray[j] / place) % 10)] - 1] = inputArray[j];
count[(inputArray[j] / place) % 10]--;//decrease count by one.
}
for (int i = 0; i < size; i++) {
inputArray[i] = outputArray[i];//copying output array to input array.
}
System.out.println(Arrays.toString(inputArray));
}
void radixSort(int inputArray[], int size) {
//find max element of inputArray
int max = inputArray[0];
for (int i = 1; i < size; i++) {
if (max < inputArray[i]) {
max = inputArray[i];
}
}
//find number of digits in max element
int d = 0;
while (max > 0) {
d++;
max /= 10;
}
//Use counting cort d no of times
int place = 1;//unit place
for (int i = 0; i < d; i++) {
System.out.print("iteration no = "+(i+1)+" ");
countingSort(inputArray, size, place);
place *= 10;//ten's , hundred's place etc
}
}
1
I'm going to resist typing out some code for you and instead go over the concepts since this looks like homework.
If I'm understanding you correctly, your problem boils down to: "I want to check if two arrays are equivalent and if they are, break out of a loop". Lets tackle the latter part first.
In Java, you can use the keyword"
break;
to break out of a loop.
A guide for checking if two arrays are equivalent in java can be found here:
https://www.geeksforgeeks.org/compare-two-arrays-java/
Sorry if this doesnt answer your question. Im just gonna suggest a faster way to find the digits of each element. Take the log base 10 of the element and add 1.
Like this : int digits = (int) Math.log10(i)+1;

Finding Similar Birthday through structure data

Hey guys I am trying to get the number of people who have the same birthday but this solution isn't working.This program is showing 0.0% .Please help me ...!.
public double calculate(int size, int count) {
int matches = 0;//initializing an integer variable
boolean out = false;
List<Integer> days=new ArrayList<Integer>();// creating arraylist name days of type int
for (int j = 0; j <count; j++) {
for (int i = 0; i < size; i++) {// initializing for loop till less than size
Random rand = new Random(); // creating an object of random function
int Brday = rand.nextInt(364) + 0;//initializing the limit of randomc number chozen
days.add(Brday); //adding values to arraylist
}
for (int l = 0; l < size; l++) {
int temp = l;//assigning value of l to a variable
for (int k = l + 1; k < size; k++) {
if (days.get(k) == temp) {// check statement to check values are same
matches++;//incrementing variable
out = true;
mOut.print("Count does have same birthday" + matches);
break;
} else {
mOut.print("does not have same birthday");
}
}
if (out) {
out = false;
break;
}
}
}
double prob = (double) matches / count;
mOut.print("The probability for two students to share a birthday is " + prob*100 + ".");
return prob;//returning double value of the function
}
Actually, you get either 0 percent or 100 percent with your code. Try invoking it with calculate(100, 100) if you want to see.
There are two things that are wrong in this code. First, if you run the simulation more than once (count > 1) then you never clear the list of birthdays before the second iteration.
Your method should begin with:
public double calculate(int size, int count) {
int matches = 0;
boolean out = false;
List<Integer> days;
for (int j = 0; j <count; j++) {
days = new ArrayList<Integer>();
Secondly, you're not comparing two birthdays but you're comparing a birthday to the index in the list.
This line:
int temp = l;//assigning value of l to a variable
Should read:
int temp = days.get(l); // Remember the birthday at index l
With those changes you'll get a much better result.

Returning wrong percentage

I am trying to calculate how many times two people in a group have the same birthday when given a size of the group. I am also given how many times the simulation is ran. I am trying to return the correct percentage for how many times we have two people share the same birthday out of the given amount of simulations.
I created an array first and then called a method to put the elements in a hashMap which would then show when there are two of the same values in the hashMap. However, I am not getting the correct percentage when running on Android Studio. In fact I am getting a percentage way off. I also declared a global static match variable of type int above this block.
/**
* sameBday: Create a word count mapping from an array
*/
public void sameBday(int[] valueHolder) {
Map<Integer, Integer> myMap = new HashMap<Integer, Integer>();
for(int number: valueHolder){
if(!myMap.containsKey(number)){
myMap.put(number, 1);
}
else if(myMap.containsKey(number)){
myMap.put(number, myMap.get(number) + 1);
match++;
break;
}
}
}
public double calculate(int size, int count) {
double percentage = 0.0;
int[] myArray = new int[size];
for(int i = 1; i <= count; i++){
Random r = new Random(i);
for(int j = 0; j < size; j++){
myArray[j] = r.nextInt(365) + 1;
}
sameBday(myArray);
if(i == count){
percentage = (match * (100.0/i));
}
}
return percentage;
}
Well your code is full of weird things, but that's OK we all did that. The first thing is Map, you don't need it. You can create just good old for loop and by additional check you will not compare the same person (it is i != j condition), but if you really want to do this by map you need to at the end of adding number (as key) to map check if some value of key is higher than 1, if true it's a match.
How to do something at the end of loop?
if(i == count){
percentage = (match * (100.0/i));
}
No, just do this after loop :)
//At the beginning there is int match = 0;
public void sameDayBirthday(int[] birthdays) {
for(int i = 0; i < birthdays.length; i++) {
for(int j = 0; j < birthdays.length; j++) {
if(birthdays[i] == birthdays[j] && i != j) {
match++;
return;
}
}
}
}
public double calculate(int size, int count) {
int[] birthdays = new int[size];
Random r = new Random();
for(int i = 1; i <= count; i++){ //looping through i counts (or 20 counts in this case
for(int j = 0; j < size; j++){ //looping through j times every i iteration
birthdays[j] = r.nextInt(365) + 1;
}
sameDayBirthday(birthdays);
}
return (match * (100.0/(double) count));
}
This code by calling calculate(23, 1000000) got me 50.7685% chance, for 22 persons 47.48690%
I am sorry if I offend you I didn't mean it. Leave a comment if you have questions.
I would use a HashSet and skip the sameBday function:
public double calculate(int size, int count) {
int match = 0;
Random r = new Random();
for(int i = 1; i <= count; i++){ //looping through i counts (or 20 counts in this case
Set<Integer> birthdays = new HashSet<Integer>(size);
for(int j = 0; j < size; j++){ //looping through j times every i iteration
Integer birthday = r.nextInt(365) + 1;
if (birthdays.contains(birthday)) {
match++;
break;
} else {
birthdays.add(birthday);
}
}
}
return (match * (100.0/count));
}

How to compare two arrays of different sizes?

So my task is to read a file line by line and store the integers into an array. Then to add the integers in spots 1-5, 2-6, 3-7 etc. and store those into a new array.
In array 1 there is 4 more values than array 2. I need to compare these Arrays and see if array1 is 0.999 bigger than array2.
If it is indeed larger, I need to print out the LOCATION of the number in the array 1.
Right now my problem is my code is outputting that every number is larger than the corresponding number in array 2.
Code:
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class Asgn7
{
public static void main(String[] args) throws FileNotFoundException
{
Scanner file = new Scanner(new File("asgn7data.txt"));
double[] array = new double[file.nextInt()];
double[] newArray = new double[array.length - 4];
double tempVal = 0;
int j = 0;
int count = 0;
while(file.hasNext())
{
for(int i = 0; i < array.length ; i++)
{
array[i] = file.nextInt();
}
for(j = 0; j < array.length - 4; j++)
{
for(int k = 0; k < 5; k++)
{
newArray[j] += array[j+k] / 5;
}
}
for(int i = 2; i < array.length; i++)
{
if(array[i] > (newArray[i-2] + 0.999));
{
count++;
tempVal = count;
}
System.out.println(tempVal);
}
}
}
}
The values which should be compared are from 3-13.
Judging by the picture, you are not placing the values in the correct index in the second array, or you are not matching the correct ones.
If you want it to look exactly like in the picture, the second array should be declared:
double[] newArray = new double[array.length - 2];
And the loop to fill it should be changed to:
for(j = 2; j < array.length - 2; j++)
{
for(int k = -2; k <= 2; k++)
{
newArray[j] += array[j+k] / 5;
}
}
This will put the averages in the third, fourth, fifth... elements in newArray. And now you can compare them directly:
for(int i = 2; i < array.length - 2; i++)
{
if(array[i] > (newArray[i] + 0.999))
{
count++;
tempVal = count;
}
System.out.println(tempVal);
}
If you want to save the two unused spaces, as you originally did, rather than responding exactly to the picture, then you should calculate the values as you originally did. But remember to compare each element to the one two places before it and stop 2 places before the end.
Instead of
for(int i = 2; i < array.length; i++)
use
for(int i = 2; i < array.length - 2; i++)
To print the location, your construct with the count and tempVal is unnecessary. You just need to print i+1. Also note that you have a ; after your if. This means it's an empty if, and the block after it is always performed. Never have a ; after an if, for, while etc.
Not clear with what you are asking for in your question but without questioning what's the logic, by just looking at your code:
for(int i = 2; i < array.length; i++)
{
if(array[i] > (newArray[i-2] + 0.999));
{
count++;
tempVal = count;
}
System.out.println(tempVal);
}
}
if you relocate the system.out line as follows, I think you will get what you expect as follows:
for(int i = 2; i < array.length - 2; i++)
{
if(array[i] > (newArray[i-2] + 0.999));
{
System.out.println(tempVal);
// count++;
// tempVal = count;
}
}
}
PS: Please note that I have also changed the boundary for the loop to stop iteration on 13th member of the array, instead of 15.
Are you sure you're parsing the numbers correctly?
See Java: Reading integers from a file into an array
Why don't you print them out after parsing for verification?
btw, this will overflow the index of the 2nd array (since it is created using new double[array.length - 4]):
for(int i = 2; i < array.length; i++)
so does your code run?

ArrayIndexOutOfBounds Exception for some input values

The following is a part of my code.
For some values of bands and bandRows the code seems to run perfectly alright. But for some it gives an ArrayIndexOutOfBounds exception.
Any ideas where I might have gone wrong? I cannot find any mistake in the code.
Thanks in advance
for(int i=0; i<bands; i++)
{
int a=0;
while(a<bucketSize)
{
bandBuckets[i][a] = new ArrayList();
a++;
}
}
for (int i = 0; i < bands; i++)
{
for (int j = 0; j < preprocessedList.size(); j++)
{
int[][] forBuckets = new int[bands][bandRows];
for (int k = 0; k < bandRows; k++)
{
Arrays.fill(forBuckets[i], Bands[i][k][j]);
}
bandBuckets[i][h.hashBands(forBuckets[i], bucketSize)].add(j);
}
}
Here's the h.hashBands() function which is in another class
public int hashBands(int[] in, int bucketSize)
{
int hashVal = 0;
int k = in.length;
int base = 3;
for (int i = 0; i < in.length; i++) {
// for (int j = 0; i < in[i].length; i++)
hashVal += in[i] * Math.pow(base, k - i - 1);
}
return hashVal % bucketSize;
}
Perhaps there is an overflow in your hashBands() function.
The max value for an int is 231 - 1. hashVal will overflow when k - i - 1 is greater than 19. In Java, exceptions aren't thrown for overflows and underflows. Consider using a BigInteger and its modPow() function.
Can you tell where exactly you are getting ArrayIndexOutOfBoundException.
Seeing your code it seems that there might be some problem while returning from hashBands() function. It might be returning something greater than expected.
bandBuckets[i][h.hashBands(forBuckets[i], bucketSize)]
For the 2nd dimension of this array h.hashBands(forBuckets[i], bucketSize) --> this value might be greater than the expected value for that part.....

Categories