Java array reading loop never ends? - java

Hi I am new to programming and today i was writing a code for one Java array task and in the beginning i tried just to test what i have done and in the first for loop (the array reading ) the program does not stop to read a numbers even i already enter a number (n) for its length. Please help ?
import java.util.Scanner;
public class ReadTwoElementsForArrayAndSum {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.println("Please enter N element:");
int n = in.nextInt();
System.out.print("Please enter K element, for k < N: ");
int k = in.nextInt();
int[] arrayN = new int[n];
System.out.print("Please enter N numbers for the array: ");
for(int i = 0; i < arrayN.length; i++) {
arrayN[i] = in.nextInt();
}
boolean changed = false;
do {
int temp = 0;
for( int i = 0; i < (arrayN.length-1); i++) {
if(arrayN[i] > arrayN[i+1]){
temp = arrayN[i];
arrayN[i] = arrayN[i+1];
arrayN[i+1] = temp;
changed = true;
}
}
} while (changed);
for(int i = 0; i < arrayN.length; i ++) {
System.out.printf("%d", arrayN[i]);
System.out.print(k);
}
in.close();
}
}

Loop is infinite because once the if condition inside for loop is executed then changed is set to true and its value never changed to false causing infinite loop by do while loop.
Instead you can use Arrays.sort(arrayN) or if you want to use loop only then try below code
int count = 0;
do {
int temp = 0;
count++;
for (int i = 0; i < (arrayN.length - 1); i++) {
if (arrayN[i] > arrayN[i + 1]) {
temp = arrayN[i];
arrayN[i] = arrayN[i + 1];
arrayN[i + 1] = temp;
}
}
} while (count < (arrayN.length));
Demo

in this loop :
do {
int temp = 0;
for( int i = 0; i < (arrayN.length-1); i++) {
if(arrayN[i] > arrayN[i+1]){
temp = arrayN[i];
arrayN[i] = arrayN[i+1];
arrayN[i+1] = temp;
changed = true;
}
}
} while (changed);
you once change the changed to true and never make it false. If you want to end your loop you must some how(it depends on your approach) make changed false so it can end the loop.

what you should be doing in a do-while loop is
boolean flag=true;
do{
(some condition){
flag=false;
}
}while(flag)
this causes correct execution of do-while loop

Related

Compare 2 team strength and find the wining probability

TeamA = {3,6,7,5,3,5,6,2,9,1}
TeamB = {2,7,0,9,3,6,0,6,2,6}
print the maximum number of fights TeamA can win if they go to fight in an optimal manner. Consider each number in array is a member and that member fight against another member of other team. For e.g TeamA[i] will fight with TeamB[i] and TeamA[i] wins if it is greater than TeamB. With the given array order of TeamA will win only 4 one to one fight. If we re-arrange TeamA array, there is possibility to win 7 fights.i.e TeamA==> {3,9,1,5,5,7,2,6,3,6}
Below is the code which determines the output correctly but there is complexity in time due to sorting, Please help me to optimize the below code
import java.io.*;
import java.util.*;
public class FightCode{
// static long[] result ={};
public static void main(String args[] ) throws Exception {
Scanner scanner = new Scanner(System.in);
try {
int testCount = scanner.nextInt();
for (int test=0;test<testCount;test++) {
int totalMem = scanner.nextInt();
Long[] teamA = new Long[totalMem];
Long[] teamB = new Long[totalMem];
if (totalMem <1)
return;
for (int r = 0; r < totalMem; r++) {
teamA[r] = (Long)scanner.nextLong();
}
for (int i = 0; i < totalMem; i++) {
teamB[i] = (Long)scanner.nextLong();
}
int count = 0;
// int[]swapar = new int[totalMem];
Arrays.sort(teamB, Collections.reverseOrder());
Arrays.sort(teamA, Collections.reverseOrder());
boolean result = Arrays.equals(teamA, teamB);
if (result)
return;
// System.out.println(Arrays.toString(teamB));
// System.out.println(Arrays.toString(teamA));
for (int a = 0; a < totalMem; a++) {
for (int k=0;k<totalMem;k++) {
if(teamA[k] > teamB[a]){
// swapar[a] = teamA[k];
teamA[k] = 0L;
count++;
break;
}
}
}
// System.out.println(Arrays.toString(swapar));
System.out.println(count);
}
} catch(Exception e) {
System.err.println(e.getStackTrace().toString());
} finally {
scanner.close();
}
}
}
This question was asked on techgig Code Gladiator 2020.
Instead of looping over entire team B in range 0 to k-1, you can loop between x and k-1 , where x is last index in team B where last match was found.
for (int a = 0; a < totalMem; a++) {
for (int k=minIndex;k<a-1;k++) {
if(teamA[a] > teamB[k]){
// swapar[a] = teamA[k];
minIndex=k+1;
count++;
break;
}
}
}

Java program to accept 6 inputs in an array and find the highest of all. And if any of the numbers are negative the loop has to be terminated

So in this code I had created a code to read 6 values and print the highest of the 6 numbers. That worked well but now if one of the numbers are negative, I want the loop to stop there and exit printing Invalid Loop. But in my code the program prints the highest mark after printing Invalid Input. How do I avoid this?
This is on IntelliJ platform Java v5.0
import java.util.Scanner;
class Highestmark {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a[] = new int[6];
for (int i = 0; i < a.length; i++) {
a[i] = sc.nextInt(); // To exit loop
if (a[i] < 0) {
System.out.println("Invalid Mark");
break;
}
}
int max = a[0];
for (int i = 0; i < a.length; i++) { // To find highest
if (max < a[i]) {
max = a[i];
}
System.out.println("Highest Mark is" + max);
}
}
}
I expect the output to be
25
-26
Invalid Input
But the actual output is
25
26
27
-28
Invalid Input
Highest Mark is 27
This can be simplified a bit, no need to keep an array:
public class HighestMark {
private static final int MAX_INPUT = 6; // could just hard-code this in loop, but good practice to set constants
private static final Scanner SCAN = new Scanner(System.in);
public static void main(String[] args) {
int highest = 0;
for (int i = 0; i < MAX_INPUT; i++) {
int next = SCAN.nextInt();
if (next < 0) { // validate the input (require non-negative int)
System.out.println("appropriate error message...");
break;
}
if (next > highest) {
highest = next;
}
}
System.out.println("Highest mark is " + highest);
}
}
The break only breaks the for-loop but then continues with the code below. You probably just say return instead or System.exit(0);
You need a boolean flag.
Set the flag to false, when there is any negative number.
Check the flag before checking max number.
Scanner sc = new Scanner(System.in);
int a[] = new int[6];
boolean flag = true;
for (int i = 0; i < a.length; i++) {
a[i] = sc.nextInt(); // To exit loop
if (a[i] < 0) {
System.out.println("Invalid Mark");
flag = false;
break;//return; //System.exit(0); any of these 3 will work fine.
}
}
if (flag) {
int max = a[0];
for (int i = 1; i < a.length; i++) // To find highest
{
if (max < a[i])
max = a[i];
}
System.out.println("Highest Mark is" + max);
}

randomly generate 100 unique numbers using Math.random [duplicate]

my intend is to use simplest java (array and loops) to generate random numbers without duplicate...but the output turns out to be 10 repeating numbers, and I cannot figure out why.
Here is my code:
int[] number = new int[10];
int count = 0;
int num;
while (count < number.length) {
num = r.nextInt(21);
boolean repeat = false;
do {
for (int i=0; i<number.length; i++) {
if (num == number[i]) {
repeat = true;
} else if (num != number[i] && i == count) {
number[count] = num;
count++;
repeat = true;
}
}
} while (!repeat);
}
for (int j = 0; j < number.length; j++) {
System.out.print(number[j] + " ");
}
How about you use a Set instead? If you also want to keep track of the order of insertion you can use a LinkedHashSet.
Random r = new Random();
Set<Integer> uniqueNumbers = new HashSet<>();
while (uniqueNumbers.size()<10){
uniqueNumbers.add(r.nextInt(21));
}
for (Integer i : uniqueNumbers){
System.out.print(i+" ");
}
A Set in java is like an Array or an ArrayList except it handles duplicates for you. It will only add the Integer to the set if it doesn't already exist in the set. The class Set has similar methods to the Array that you can utilize. For example Set.size() is equivalent to the Array.length and Set.add(Integer) is semi-equivalent to Array[index] = value. Sets do not keep track of insertion order so they do not have an index. It is a very powerful tool in Java once you learn about it. ;)
Hope this helps!
You need to break out of the for loop if either of the conditions are met.
int[] number = new int[10];
int count=0;
int num;
Random r = new Random();
while(count<number.length){
num = r.nextInt(21);
boolean repeat=false;
do{
for(int i=0; i<number.length; i++){
if(num==number[i]){
repeat=true;
break;
}
else if(i==count){
number[count]=num;
count++;
repeat=true;
break;
}
}
}while(!repeat);
}
for(int j=0;j<number.length;j++){
System.out.print(number[j]+" ");
}
This will make YOUR code work but #gonzo proposed a better solution.
Your code will break the while loop under the condition: num == number[i].
This means that if the pseudo-generated number is equal to that positions value (the default int in java is 0), then the code will end execution.
On the second conditional, the expression num != number[i] is always true (otherwise the code would have entered the previous if), but, on the first run, when i == count (or i=0, and count=0) the repeat=true breaks the loop, and nothing else would happen, rendering the output something such as
0 0 0 0 0 0...
Try this:
int[] number = new int[10];
java.util.Random r = new java.util.Random();
for(int i=0; i<number.length; i++){
boolean repeat=false;
do{
repeat=false;
int num = r.nextInt(21);
for(int j=0; j<number.length; j++){
if(number[j]==num){
repeat=true;
}
}
if(!repeat) number[i]=num;
}while(repeat);
}
for (int k = 0; k < number.length; k++) {
System.out.print(number[k] + " ");
}
System.out.println();
Test it here.
I believe the problem is much easier to solve. You could use a List to check if the number has been generated or not (uniqueness). Here is a working block of code.
int count=0;
int num;
Random r = new Random();
List<Integer> numbers = new ArrayList<Integer>();
while (count<10) {
num = r.nextInt(21);
if(!numbers.contains(num) ) {
numbers.add(num);
count++;
}
}
for(int j=0;j<10;j++){
System.out.print(numbers.get(j)+" ");
}
}
Let's start with the most simple approach, putting 10 random - potentially duplicated - numbers into an array:
public class NonUniqueRandoms
{
public static void main(String[] args)
{
int[] number = new int[10];
int count = 0;
while (count < number.length) {
// Use ThreadLocalRandom so this is a contained compilable unit
number[count++] = ThreadLocalRandom.current().nextInt(21);
}
for (int j = 0; j < number.length; j++) {
System.out.println(number[j]);
}
}
}
So that gets you most of the way there, the only thing you know have to do is pick a number and check your array:
public class UniqueRandoms
{
public static void main(String[] args)
{
int[] number = new int[10];
int count = 0;
while (count < number.length) {
// Use ThreadLocalRandom so this is a contained compilable unit
int candidate = ThreadLocalRandom.current().nextInt(21);
// Is candidate in our array already?
boolean exists = false;
for (int i = 0; i < count; i++) {
if (number[i] == candidate) {
exists = true;
break;
}
}
// We didn't find it, so we're good to add it to the array
if (!exists) {
number[count++] = candidate;
}
}
for (int j = 0; j < number.length; j++) {
System.out.println(number[j]);
}
}
}
The problem is with your inner 'for' loop. Once the program finds a unique integer, it adds the integer to the array and then increments the count. On the next loop iteration, the new integer will be added again because (num != number[i] && i == count), eventually filling up the array with the same integer. The for loop needs to exit after adding the unique integer the first time.
But if we look at the construction more deeply, we see that the inner for loop is entirely unnecessary.
See the code below.
import java.util.*;
public class RandomDemo {
public static void main( String args[] ){
// create random object
Random r = new Random();
int[] number = new int[10];
int count = 0;
int num;
while (count < number.length) {
num = r.nextInt(21);
boolean repeat = false;
int i=0;
do {
if (num == number[i]) {
repeat = true;
} else if (num != number[i] && i == count) {
number[count] = num;
count++;
repeat = true;
}
i++;
} while (!repeat && i < number.length);
}
for (int j = 0; j < number.length; j++) {
System.out.print(number[j] + " ");
}
}
}
This would be my approach.
import java.util.Random;
public class uniquerandom {
public static void main(String[] args) {
Random rnd = new Random();
int qask[]=new int[10];
int it,i,t=0,in,flag;
for(it=0;;it++)
{
i=rnd.nextInt(11);
flag=0;
for(in=0;in<qask.length;in++)
{
if(i==qask[in])
{
flag=1;
break;
}
}
if(flag!=1)
{
qask[t++]=i;
}
if(t==10)
break;
}
for(it=0;it<qask.length;it++)
System.out.println(qask[it]);
}}
public String pickStringElement(ArrayList list, int... howMany) {
int counter = howMany.length > 0 ? howMany[0] : 1;
String returnString = "";
ArrayList previousVal = new ArrayList()
for (int i = 1; i <= counter; i++) {
Random rand = new Random()
for(int j=1; j <=list.size(); j++){
int newRand = rand.nextInt(list.size())
if (!previousVal.contains(newRand)){
previousVal.add(newRand)
returnString = returnString + (i>1 ? ", " + list.get(newRand) :list.get(newRand))
break
}
}
}
return returnString;
}
Create simple method and call it where you require-
private List<Integer> q_list = new ArrayList<>(); //declare list integer type
private void checkList(int size)
{
position = getRandom(list.size()); //generating random value less than size
if(q_list.contains(position)) { // check if list contains position
checkList(size); /// if it contains call checkList method again
}
else
{
q_list.add(position); // else add the position in the list
playAnimation(tv_questions, 0, list.get(position).getQuestion()); // task you want to perform after getting value
}
}
for getting random value this method is being called-
public static int getRandom(int max){
return (int) (Math.random()*max);
}

Counting non repeating integers

I need help with a coding question. I would like some tips on finding the answer but not the answer itself.
Sample input looks like this 3112.
Sample output is 2 because the integers doesn't repeat.
here's the code
public static int lonelyInteger(int[] arr)
{
need to code this
}
public static void main(String[] args) throws IOException
{
Scanner in = new Scanner(System.in);
final String fileName = System.getenv("OUTPUT_PATH");
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));
int res;
int _arr_size = Integer.parseInt(in.nextLine());
int[] _arr = new int[_arr_size];
int _arr_item;
for(int _arr_i = 0; _arr_i < _arr_size; _arr_i++)
{
_arr_item = Integer.parseInt(in.nextLine());
_arr[_arr_i] = _arr_item;
}
res = loneyInteger(_arr);
bw.write(String.valueOf(res));
bw.newLine();
bw.close();
}
You can make a counter for the integers that repeated themselves while you read them .
For example :
for(int _arr_i = 0; _arr_i < _arr_size; _arr_i++)
{
_arr_item = Integer.parseInt(in.nextLine());
if (itemNotInList(_arr_item))
repeatedItemsCounter++;
}
unrepeadedItems = allItems - repeatedItemsCounter
Write a loop that iterates from the start to the end of arr, and check the element in front and behind at each index for it it contains a different value. If the value is different from the previous and next elements, add one to the counter. Make sure to do a check that the index in front or behind aren't equal to -1 or arr.length before accessing those indexes.
Spoiler:
int count = 0;
for (int i = 0; i < arr.length; i++)
if (i-1 >= 0 && arr[i] == arr[i-1] ||
i+1 < arr.length && arr[i] == arr[i+1])
continue;
else
count++;
return count;

Taking User Input for an Array

A link to the assignment:
http://i.imgur.com/fc86hG9.png
I'm having a bit of trouble discerning how to take a series of numbers and apply them to an array without a loop. Not only that, but I'm having a bit of trouble comparing them. What I have written so far is:
import java.util.Scanner;
public class Lottery {
public static void main(String[] args) {
int userInputs[] = new int[5];
int lotteryNumbers [] = new int[5];
int matchedNumbers =0;
char repeatLottery = '\0';
Scanner in = new Scanner (System.in);
do{
System.out.println("Enter your 5 single-digit lottery numbers.\n (Use the spacebar to separate digits): ");
for(int i = 0; i <5; i++ )
userInputs[i] = in.nextInt();
System.out.println("Your inputs: ");
printArray(userInputs);
System.out.println("\nLottery Numbers: ");
readIn(lotteryNumbers);
for(int i=0; i<5; i++) {
System.out.print(lotteryNumbers[i] + " ");
}
matchedNumbers = compareArr(userInputs, lotteryNumbers);
System.out.println("\n\nYou matched " + matchedNumbers + " numbers");
System.out.println("\nDo you wish to play again?(Enter Y or N): ");
repeatLottery = in.next().charAt(0);
}
while (repeatLottery == 'Y' || repeatLottery == 'y');
}
public static void printArray(int arr[]){
int n = arr.length;
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
}
}
public static void readIn(int[] List) {
for(int j=0; j<List.length; j++) {
List[j] = (int) (Math.random()*10);
}
}
public static int compareArr (int[] list1, int[] list2) {
int same = 0;
for (int i = 0; i <= list1.length-1; i++) {
for(int j = 0; j <= list2.length-1; j++) {
if (list1[i] == list2[j]) {
same++;
}
}
}
return same;
}
}
As you'll notice, I commented out the input line because I'm not quite sure how to handle it. If I have them in an array, I should be able to compare them fairly easily I think. This is our first assignment handling arrays, and I think it seems a bit in-depth for only having one class-period on it; So, please forgive my ignorance. :P
Edit:
I added a new method at the end to compare the digits, but the problem is it compares them in-general and not from position to position. That seems to be the major issue now.
your question isn't 100% clear but i will try my best.
1- i don't see any problems with reading input from user
int[] userInput = new int[5]; // maybe here you had a mistake
int[] lotterryArray = new int[5]; // and here you were declaring your arrays in a wrong way
Scanner scanner = new Scanner(system.in);
for ( int i = 0 ; i < 5 ; i++)
{
userInput[i] = scanner.nextInt();
} // this will populate your array try to print it to make sure
Edit : important in the link you shared about the assignment the compare need to check the value and location so if there are two 5 one in input one in loterry array they need to be in the same location check the assignment again
// to compare
int result = 0 ; // this will be the number of matched digits
for ( int i = 0 ; i < 5 ; i++)
{
if ( userInput[i] == loterryArray[i] )
result++
}
// in this comparsion if the digits are equale in value and location result will be incremented

Categories