Infinite loop due to an Array issue - java

public class trothBrthdays {
public static void main ( String args [] ) {
Random day = new Random();
int days[] = new int[366];
int smallest = 0;
int largest = 885000;
for (int i = 1; i <= 885000; i++)
{
int persons = day.nextInt(365) + 1;
days[persons] += 1;
}
for (int a = 1; a <= 365; a++)
{
System.out.printf ( " \nDay %d: %d ", a, days[a]);
}
Here program finds day with most birthdays on it
for (int b = 0; b < days.length;)
{
if(days[b] > smallest)
{
largest = days[b];
System.out.printf ( "\nLargest: %d ", days[b]);
}
}
Here program finds day with least birthdays on it
for (int c = 0; c > days.length;)
{
if (days[c] < largest)
{
smallest = days[c];
System.out.printf ( "\nSmallest: %d ", days[c]);
}
}
}
}
The problem is when the program gets to finding the largest number it infinitely loops the largest number and I can't figure out why. I'm still a Beginner program and would love constructive criticism on how to format and type this program.

The reason this is happening is because of your for loops:
for (int b = 0; b < days.length;)
The construction of a for loop is in three parts. Part one is the iterator's declaration:
(int b = 0;
part two is the break condition. That is, what condition must be met, else the loop breaks.
b < days.length;
finally, the third part determines what should change between each iteration. But your for loop is missing that part. It should be...
b++)
Edit:
The second problem that you have is that this will not work with the code as it is written. But I suppose that will be an exercise for you to figure out why.

Related

String-Word counter

I have to print the count of the words in a string which are repeated exactly N times?
example:
one two three four three two five
1
output:3
since one,four and five appears only once.
My code shows me the output as 1.
what is wrong with my code and logic?thank you.
import java.util.*;
public class Hello {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
String s=scan.nextLine(),b;
int n=scan.nextInt();
int c=0,f=0,i;
String[] a=s.split(" ");
for(i=0;i<a.length;i++)
{
b=a[i];
for(int j=i+1;j<a.length;j++)
{
if(b.equalsIgnoreCase(a[j]))
{
c++;
}
}
if(n==c)
{
f++;
}
else
{
c=0;
}
}
System.out.print(f);
}
}
I see three reasons that makes your result incorrect.
First one is c
If a word is here once only, then the if statement if(b.equalsIgnoreCase(a[j])) will never be true. Which means that c will be always equal to 0.
So you you need to use 1 as default value for c or you should check the value of c using the following statement if (n == c + 1)
The second point is that you should reset the value of c even if it is equal to n.
Then with this double for loop:
for (i = 0; i < a.length; i++) {
b = a[i];
for (int j = i + 1; j < a.length; j++) {
When you searching for a value that is there once only, the last occurence of every words will be counted as well.
There is lot of ways to solve that. one of them is to use a Set<String> and only count for the words that has not been used before.
So at the end you will have something similar to that:
int c=1,f=0,i;
String[] a=s.split(" ");
Set<String> words = new HashSet<>();
for (i = 0; i < a.length; i++) {
b = a[i];
if (words.add(b)) {
for (int j = i + 1; j < a.length; j++) {
if (b.equalsIgnoreCase(a[j])) {
c++;
}
}
if (n == c) {
f++;
}
c = 1;
}
}
I think It's because you don't initialize C when n==c . Therefor it increases to 1 after one and one are matched. And it's not working well . It should be 0 for every loop
Also why j starts from i+1? After each loop it will lose comparison one by one Since a[j] is getting smaller. It should always containt list of full input numbers

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));
}

Calculate factorial of 50 using array only in java

I'm a total beginner of java.
I have a homework to write a complete program that calculates the factorial of 50 using array.
I can't use any method like biginteger.
I can only use array because my professor wants us to understand the logic behind, I guess...
However, he didn't really teach us the detail of array, so I'm really confused here.
Basically, I'm trying to divide the big number and put it into array slot. So if the first array gets 235, I can divide it and extract the number and put it into one array slot. Then, put the remain next array slot. And repeat the process until I get the result (which is factorial of 50, and it's a huge number..)
I tried to understand what's the logic behind, but I really can't figure it out.. So far I have this on my mind.
import java.util.Scanner;
class Factorial
{
public static void main(String[] args)
{
int n;
Scanner kb = new Scanner(System.in);
System.out.println("Enter n");
n = kb.nextInt();
System.out.println(n +"! = " + fact(n));
}
public static int fact(int n)
{
int product = 1;
int[] a = new int[100];
a[0] = 1;
for (int j = 2; j < a.length; j++)
{
for(; n >= 1; n--)
{
product = product * n;
a[j-1] = n;
a[j] = a[j]/10;
a[j+1] = a[j]%10;
}
}
return product;
}
}
But it doesn't show me the factorial of 50.
it shows me 0 as the result, so apparently, it's not working.
I'm trying to use one method (fact()), but I'm not sure that's the right way to do.
My professor mentioned about using operator / and % to assign the number to the next slot of array repeatedly.
So I'm trying to use that for this homework.
Does anyone have an idea for this homework?
Please help me!
And sorry for the confusing instruction... I'm confused also, so please forgive me.
FYI: factorial of 50 is 30414093201713378043612608166064768844377641568960512000000000000
Try this.
static int[] fact(int n) {
int[] r = new int[100];
r[0] = 1;
for (int i = 1; i <= n; ++i) {
int carry = 0;
for (int j = 0; j < r.length; ++j) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
and
int[] result = fact(50);
int i = result.length - 1;
while (i > 0 && result[i] == 0)
--i;
while (i >= 0)
System.out.print(result[i--]);
System.out.println();
// -> 30414093201713378043612608166064768844377641568960512000000000000
Her's my result:
50 factorial - 30414093201713378043612608166064768844377641568960512000000000000
And here's the code. I hard coded an array of 100 digits. When printing, I skip the leading zeroes.
public class FactorialArray {
public static void main(String[] args) {
int n = 50;
System.out.print(n + " factorial - ");
int[] result = factorial(n);
boolean firstDigit = false;
for (int digit : result) {
if (digit > 0) {
firstDigit = true;
}
if (firstDigit) {
System.out.print(digit);
}
}
System.out.println();
}
private static int[] factorial(int n) {
int[] r = new int[100];
r[r.length - 1] = 1;
for (int i = 1; i <= n; i++) {
int carry = 0;
for (int j = r.length - 1; j >= 0; j--) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
}
How about:
public static BigInteger p(int numOfAllPerson) {
if (numOfAllPerson < 0) {
throw new IllegalArgumentException();
}
if (numOfAllPerson == 0) {
return BigInteger.ONE;
}
BigInteger retBigInt = BigInteger.ONE;
for (; numOfAllPerson > 0; numOfAllPerson--) {
retBigInt = retBigInt.multiply(BigInteger.valueOf(numOfAllPerson));
}
return retBigInt;
}
Please recall basic level of math how multiplication works?
2344
X 34
= (2344*4)*10^0 + (2344*3)*10^1 = ans
2344
X334
= (2344*4)*10^0 + (2344*3)*10^1 + (2344*3)*10^2= ans
So for m digits X n digits you need n list of string array.
Each time you multiply each digits with m. and store it.
After each step you will append 0,1,2,n-1 trailing zero(s) to that string.
Finally, sum all of n listed string. You know how to do that.
So up to this you know m*n
now it is very easy to compute 1*..........*49*50.
how about:
int[] arrayOfFifty = new int[50];
//populate the array with 1 to 50
for(int i = 1; i < 51; i++){
arrayOfFifty[i-1] = i;
}
//perform the factorial
long result = 1;
for(int i = 0; i < arrayOfFifty.length; i++){
result = arrayOfFifty[i] * result;
}
Did not test this. No idea how big the number is and if it would cause error due to the size of the number.
Updated. arrays use ".length" to measure the size.
I now updated result to long data type and it returns the following - which is obviously incorrect. This is a massive number and I'm not sure what your professor is trying to get at.
-3258495067890909184

Second for loop not being executed

I have this simple program where I am trying to output all the cards in a deck of cards.
However it is only outputting the 1-9 cards of each set, and none of the face cards. i.e. only the for loop with j is being executed, but not the f for loop involving the cardFace array. Why is this?
public class cards {
public final String cardValue[] = {"Heart", "Diamond", "Spade", "Club"};
public final String cardFace[] = {"Jack", "Queen", "King", "Ace"};
public void outputCards() {
for (int i = 0; i < cardValue.length; i++) {
int k = 1;
if (k <= 9) {
for (int j = 1; j <= 9; j++) {
System.out.println("The Card is a " + j + " And is a " + cardValue[i]);
k++;
}
} else {
for (int f = 10; f < cardFace.length; f++) {
System.out.println("The Card is a " + f + " And is a " + cardValue[i]);
k++;
}
}
}
}
}
for(int i = 0; i <cardValue.length; i++){
int k = 1;
if(k <=9){
...
Given the preceding code, it'll always enter on the if and never on the else. Therefore, the for that uses the f variable, will never be executed.
Even if your code got to the loop it will never run because this for condition will never be true:
for(int f = 10; f < cardFace.length; f++){
If you inspect the cardFace array and get its length, you'll see that it is always less than f.
Most all of your logic is a bit off. I suggest that you write out the program steps on paper first, thinking through the steps before trying to commit it to code, because usually these types mistakes are caused by coding before thinking.

Categories