The loop runs twice in a single run - java

This problem is from https://www.hackerrank.com/ and link to it is https://www.hackerrank.com/challenges/java-list/problem .
In the below code while loop is running twice as according to question we need to enter Q, Q times an operation to perform in the Array Declared. For this, i am running twice the loop so that I can get the desired result.
import java.util.*;
public class javaList {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int i, x;
ArrayList L = new ArrayList(N);
for (i = 0; i < N; i++) {
L.add(sc.nextInt());
}
int Q = sc.nextInt();
i = 0;
// for normal running i have multiplied Q by 2 so that i can get the results
while (i < Q * 2) {
System.out.println("Loop: " + i);
String s = sc.nextLine();
int sz = L.size();
// code for checking insert
if (s.equals("Insert")) {
x = sc.nextInt();
int y = sc.nextInt();
//if the position i am looking exists then just replace
// i need to insert at index x of array L but array.size() gives one more than the last index
if ((sz - 1) >= x) {
L.add(x, y);
}
//if the position i am looking does not exist then create
else {
for (int j = sz; j <= x; j++) {
//add number to desired place
if (j == x)
L.add(y);
//in between the two endings of array and insertion adding default value 0
else
L.add(0);
}
}
//checking code for Delete
} else if (s.equals("Delete")) {
x = sc.nextInt();
//if the desired location exists then only replace
if ((sz - 1) >= x) {
L.remove(x);
}
}
i++;
}
for (i = 0; i < L.size(); i++) {
System.out.print(L.get(i) + " ");
}
}
}
I want to Know why the loop is running twice in a single run.

So, from discussion in the comments, you've stated that your question is:
if Q = 2 then it should ask operations Insert or Delete 4 times as of my code. But it asks only 2 times. Simply that is my problem
First, you may not fully understand your own program flow. Before the while loop, you need to enter three sets of values, a value for N, values for L, and a value for Q.
Once you enter your while loop, you will be prompted for a value for s (which it seems you intend to be either "Insert" or "Delete"). However, the first time around, it will get an empty string and s will be "\n". Why? Because for N, L, and Q, the user will enter values as follows:
[value] [ENTER]
The return key is itself a value. So, in the input buffer (assuming Q = 2), is "2\n". When your code runs to get s String s = sc.nextLine(); it will see the next line symbol and skip prompting user for input.
Because s is not "Insert" or "Delete", it will skip those the first time around. You will then be prompted to enter a value for "s" after the start next loop.
To help you realize what's going on, I suggest adding statements everywhere you ask users to enter a value, like System.out.println("Enter a value for Q:");
This will help you keep track of program flow.

Your code is waaay to complicated. Try this:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
for (int i = 0, n = scanner.nextInt(); i < n; i++) {
list.add(scanner.nextInt());
}
for (int i = 0, n = scanner.nextInt(); i < n; i++) {
if (scanner.next().equals("Insert")) {
list.add(scanner.nextInt(), scanner.nextInt());
} else {
list.remove(scanner.nextInt());
}
}
String result = list.stream()
.map(String::valueOf)
.collect(Collectors.joining(" "));
System.out.println(result);
}

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.

How to add even numbers in a range using a for loop

I have to create a program that gets a range from the user then adds each even number in the range and prints to screen. I am struggling to figure out how to add each number in the for loop. If the range is 5 to 10 the screen should print 24 as the answer. Below is my code.
//worksheet 4 - question 3
//asks user for a range. Adds even numbers in range and prints their sum.
import java.util.Scanner;
class P3LoopRange
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int initial, finalValue;
System.out.print("Enter a start value: ");
initial = input.nextInt();
System.out.print("Enter a second value: ");
finalValue = input.nextInt();
while (finalValue <= initial)
{
System.out.println("Second value must be larger than start value.");
System.out.print("Enter a second value: ");
finalValue = input.nextInt();
}
int range = finalValue - initial;
int x = 0
for (int i = initial; i <= finalValue; i++)
{
if (i%2==0)
{
int x = x+i;
}
}
System.out.printf(x);
}
}
You declare twice the x local variable.
You cannot as it is not legal to have a duplicate local variable.
Besides, declaring it inside the loop makes it be overwritten at each iteration.
So, just declare it before the loop and it should be fine.
int x = 0;
for (int i = initial; i <= finalValue; i++)
{
if (i%2 == 0)
{
x = x + i;
}
}
Change int x = x+i; to x=x+i;. Here you are re initializing x each time.
Problem is at: int x = x+i;
just remove int and your problem is solved

How to exclude -1 sentinel value when finding minimum element in an array, java

I'm trying to find the minimum element in an array of size 25 elements are read by user and should stop when the user enters -1
import java.util.*;
public class LabSheet4{
public static void main (String[] args){
Scanner read = new Scanner (System.in);
double scores[] = new double[25];
int minIndex=0, i =0, sentinel=0;
do{
scores[i] = read.nextDouble();
if(scores[i]==-1)
sentinel=-1;
i++;}while(sentinel!=-1);
for(int k=0;k<scores.length;k++)
if(scores[minIndex] > scores[k] && scores[minIndex]>0)
minIndex = k;
lowestScore = scores[minIndex];}}
How do I exclude -1?
One way would be to not put the value in the list until after you know it isn't the sentinel.
Another would be to not increment the counter when you find you have added the sentinel. Note that this means you need a slightly bigger array.
One way is not to store it in the first place but another fix would be to ignore it when running on the array like this.
for(int k=0;k<scores.length;k++)
if(scores[minIndex] > scores[k] && scores[minIndex]>0 && scores[k] !=1)
One common idiom for this class of problems, is to use a while loop with an assignment and test. Something like,
double scores[] = new double[25];
int i = 0;
double score;
while ((score = read.nextDouble()) != -1) {
scores[i] = score;
i++;
}
Then you could start at 0 and iterate from 1 to i (because 0 is your initial value and i is the count of elements). Like,
int minIndex = 0;
for (int k = 1; k < i; k++) {
if (scores[minIndex] > scores[k]) {
minIndex = k;
}
}
double lowestScore = scores[minIndex];
Instead of
if(scores[i]==-1)
sentinel=-1;
use
if (scores[i]==-1 && i > 0) {
sentinel=-1;
scores[i] = scores[minIndex];
}
so you replace -1 with (so far) the lowest value - which is OK, isn't it?.
Do not store -1 in scores at all.
That way you won't have to exclude it later.
Most importantly,
it's not a functional value like the other values you store,
but a symbol with a special technical meaning in the way you process input.
As such, it doesn't belong in the scores array.
Change your loop that reads the user input,
so as to not store -1.
Check the input before you store it,
and break out of the loop if it is -1:
while (true) {
double input = read.nextDouble();
if (input == -1) {
break;
}
scores[i++] = input;
}
Btw, what will happen if the user enters 26 values that are not -1?
The program will crash, because scores can only store 25 values.
So you need further some improvements to prevent that from happening.
For example you could use a for loop instead:
for (int i = 0; i < scores.length; i++) {
double input = read.nextDouble();
if (input == -1) {
break;
}
scores[i] = input;
}

Java Random Utility Generating Too Many 0's And Static Numbers

The line birthdays[j] = rnd.nextInt(365); seems to generate extra 0's in the int[] birthdays array. It also seems to add an EXTRA 0 into the array and generate static values depending on how many simulations I run and how many birthdays I generate. For instance, if I do 5 simulations and enter a 3 for the number of people in each simulation's "birthday pool" I always get an array of [0, 0, 289, 362].
Any help understanding the problem would be greatly appreciated.
public static void main(String[] args) {
System.out.println("Welcome to the birthday problem Simulator\n");
String userAnswer="";
Scanner stdIn = new Scanner(System.in);
do {
int [] userInput = promptAndRead(stdIn);
double probability = compute(userInput[0], userInput[1]);
// Print results
System.out.println("For a group of " + userInput[1] + " people, the probability");
System.out.print("that two people have the same birthday is\n");
System.out.println(probability);
System.out.print("\nDo you want to run another set of simulations(y/n)? :");
//eat or skip empty line
stdIn.nextLine();
userAnswer = stdIn.nextLine();
} while (userAnswer.equals("y"));
System.out.println("Goodbye!");
stdIn.close();
}
// Prompt user to provide the number of simulations and number of people and return them as an array
public static int[] promptAndRead(Scanner stdIn) {
int numberOfSimulations = 0;
while(numberOfSimulations < 1 || numberOfSimulations > 50000) {
System.out.println("Please Enter the number of simulations to do. (1 - 50000) ");
numberOfSimulations = stdIn.nextInt();
}
int sizeOfGroup = 0;
while(sizeOfGroup < 2 || sizeOfGroup > 365) {
System.out.println("Please Enter the size of the group of people. (2 - 365) ");
sizeOfGroup = stdIn.nextInt();
}
int[] simulationVariables = {numberOfSimulations, sizeOfGroup};
return simulationVariables;
}
// This is the method that actually does the calculations.
public static double compute(int numOfSims, int numOfPeeps) {
double numberOfSims = 0.0;
double simsWithCollisions = 0.0;
int matchingBirthdays = 0;
int[] birthdays = new int[numOfPeeps + 1];
int randomSeed = 0;
for(int i = 0; i < numOfSims; i++)
{
randomSeed++;
Random rnd = new Random(randomSeed);
birthdays = new int[numOfPeeps + 1];
matchingBirthdays = 0;
for(int j = 0; j < numOfPeeps; j++) {
birthdays[j] = rnd.nextInt(365);
Arrays.sort(birthdays);
}
for(int k = 0; k < numOfPeeps; k++) {
if(birthdays[k] == birthdays[k+1]) {
matchingBirthdays++;
}
}
if(matchingBirthdays > 0) {
simsWithCollisions = simsWithCollisions + 1;
}
}
numberOfSims = numOfSims;
double chance = (simsWithCollisions / numberOfSims);
return chance;
}
}
The line "birthdays[j] = rnd.nextInt(365);" seems to generate extra 0's in the int[] birthdays array.
Well, it doesn't. The array elements where zero to start with.
What that statement actually does is to generate a single random number (from 0 to 364) and assign it to one element of the array; i.e. the jth element. That is not what is required for your problem.
Now, we could fix your code for you, but that defeats the purpose of your homework. Instead I will give you a HINT:
The birthdays array is supposed to contain a COUNT of the number of people with a birthday on each day of the year. You have to COUNT them. One at a time.
Think about it ...
int arrays are by default initialized to 0 unless explicitly specified. Please see this Oracle tutorial about Arrays.
I found the problem myself. The issue was that having the "Arrays.sort(birthdays);" statement inside of a loop. That generated extra 0's.

Finding out the frequency of unique numbers

I am trying to solve a problem in Java as part of my assignment. The problem is as below:
The user enters ten numbers one by one upon prompting by the screen. The screen then assigns all the distinct value to an array and a similar array to hold the frequency of how many times those numbers have appeared.
I have done the below work, but seems I am stuck somewhere in assigning the frequencies and distinct values to the arrays:
import java.util.*;
public class JavaApplication10
{
public static void main(String[] args)
{
int [] numbers = new int [10];
int [] count = new int[10];
int [] distinct = new int[10];
for (int k=0;k<10;k++)
{
count[k]=0;
distinct[k]=0;
}
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.print("Enter number 0: ");
numbers[0]=input.nextInt();
count[0]=1;
distinct[0]=numbers[0];
int j=0;
for (int i = 1;i<10;i++)
{
System.out.print("Enter number "+i+": ");
numbers[i]=input.nextInt();
while(j<i)
{
if (distinct[j]==numbers[i])
count[j]=count[j]+1;
else
distinct[j+1]=numbers[i];
j++;
}
}
for (int k=0;k<10;k++)
{
System.out.println(distinct[k]+ " "+count[k]);
}
}
}
I know that it is not fair to ask someone to help me solve the problem. But any kind of hint will be helpful.
Thank you
are the numbers limited to 0-9? If so, I would simple do the assignment.
(please note you will assign the input to a variable called "input"):
numbers[0]=input;
count[input]++;
Also you can start your for loop in "0" to avoid the assignment prior to the for loop.
Just a hint.
Hope this helps!
the ideal data structure would be a HashMap
Steps:
1) initialize an array to store the numbers and for each input
2) check if a hashmap entry with key as the entered number already exists
3) if exists simply increase its count
4) else create new entry with key as the number and count as 1
so at the end your frequencies would be calculated
if you are forced to use 2 arrays
1) initialize two arrays
2) for each input loop the number array and check whether that number is already in the array
3) if so take the array index and increment the value of the frequency array with the same index
4) if not freq[index] = 1
A proper way of doing that would be:
public Map<Integer, Integer> getFrequencies(Iterable<Integer> numbers) {
Map<Integer, Integer> frequencies = new HashMap<Integer, Integer>();
for(Integer number : numbers) {
if (frequencies.get(number) == null) {
frequencies.put(number, 0);
}
frequencies.put(number, frequencies.get(number) + 1);
}
return frequencies;
}
It returns a map number -> frequency.
Arrays are not a way to go in Java, they should be avoided whenever possible. See Effective Java, Item 25: Prefer lists to arrays.
I removed the Scanner object to write the code faster, just replace it with your code above and it should work.
int[] numbers = { 1, 2, 2, 2, 3, 3, 3, 1, 1, 2 };
int[] count = new int[10];
int[] distinct = new int[10];
count[0] = 1;
distinct[0] = numbers[0];
int disPos = 1; //Current possition in the distinct array
boolean valueInarray = false;
for (int i = 1; i < 10; i++) {
valueInarray = false;
for (int d = 0; d < i; d++) {
if (numbers[i] == distinct[d]) {
count[d] = count[d] + 1;
valueInarray = true;
break;
}
}
if (!valueInarray) {
distinct[disPos] = numbers[i];
count[disPos] = 1;
disPos++;
}
}
If you ABSOLUTELY HAVE TO use arrays.. here is a way to do it…
import java.util.Scanner;
import java.util.Arrays;
public class JavaApplication10
{
public static void main(String[] args)
{
int [] numbers = new int [10];
int [] count = new int[10];
int [] distinct = new int[10];
int [] distinct1 = new int[1];
int distinctCount = 0;
boolean found = false;
Scanner input = new Scanner(System.in);
for (int i=0; i<10; i++) {
found = false;
System.out.print("Enter number " + i);
numbers[i]=input.nextInt(); //Add input to numbers array
for (int j=0; j<=distinctCount; j++)
{
if (distinct1[j] == numbers[i]){ // check to see if the number is already in the distinct array
count[j] = count[j] + 1; // Increase count by 1
found = true;
break;
}
}
if (!found) {
distinct[distinctCount] = numbers[i];
count[distinctCount] = 1;
distinctCount++;
distinct1 = Arrays.copyOf(distinct, distinctCount+1);
}
}
for (int j=0; j<distinctCount; j++)
System.out.println("The number " + distinct1[j] + " occurs " + count[j] + " times" );
}
}
I think this is what you need, correct me if I'm wrong...
import java.util.HashMap;
import java.util.Scanner;
public class JavaApplication10 {
public static void main(String[] args) {
// Initializing variables
int[] numbers = new int[10];
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
Scanner input = new Scanner(System.in);
// Getting the 10 inputs
for(int x=0; x<10; x++) {
// Asking for input
System.out.println("Enter number "+x+":");
numbers[x]=input.nextInt();
// If the table contains the number, add 1
// Otherwise: set value to 1
if(table.containsKey(numbers[x]))
table.put(numbers[x], table.get(numbers[x])+1);
else
table.put(numbers[x],1);
}
// Closing the reader
input.close();
// Get the highest and smallest number
int highest=0;
int smallest=0;
for(int i:table.keySet()) {
if(i>highest)
highest=i;
if(i<smallest)
smallest=i;
}
// For every value between the smallest and the highest
for (int x=smallest; x<=highest; x++) {
// Check if the frequency > 0, else continue
if(table.get(x)==null)
continue;
// Output
System.out.println(x+" is "+table.get(x)+" times in \'frequence\'");
}
}
}
This also handles with negative numbers, unlike the other's codes. If you don't want to use HashMaps let me know so I can create something with arrays.
Let me know if it (doesn't) works!
Happy coding (and good luck with your assignment) ;) -Charlie

Categories

Resources