Arrays and read and write text files issue - Java - java

Here is what I have to do...
Input File: dishin.txt
Output File: dishout.txt
Time Limit: 1 second
You do not like statisticians, and statisticians do not like you. Ever since that life actuary kicked sand into your ice cream when you were four, you have waged a slowly escalating war against those number-crunching jerks. But all that is about to change.
After many sleepless nights you have conceived the ultimate revenge: beating them at their own game. Using your computer programming skills, you will write a freeware statistics package so thorough, so complete, that statisticians all around the world will be out of a job. It will be able to predict weather patterns, calculate life expectancies, and even play the perfect poker game.
First, though, you must implement word wrap. However, this task is rather finnicky, not very mathematical in nature, and ultimately not very important. More urgently, you also need to implement some basic data analysis. Specifically, you decide to write a test program that takes a data set (a list of integers) and calculates the following measures of spread:
Minimum - the smallest value in the list. For example, the minimum of the numbers {5, 6, 5, 3} is 3.
Maximum - the largest value in the list. For example, the maximum of the numbers {5, 6, 5, 3} is 6.
Mean (or average) - defined as the sum of everything in the list divided by the number of items in the list. For example, the mean of the numbers {5, 6, 5, 3} is (5+6+5+3)/4 = 19/4 = 4.75. However for simplicity you are asked to round all answers down to the nearest whole number. So the mean of the numbers {5, 6, 3, 3}, rounded down, is 4.
Input:
The first line of input will consist of a single integer n (1 <= n <= 1,000), the size of your data set. The following n lines will describe the data set. Each of these lines contains an integer between 0 and 1,000,000 inclusive.
Output
The output file should consist of three integers separated by spaces: the minimum, maximum and mean of the data set.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Solution {
public static void main(String[] args) throws IOException {
///home/sebastian/workspace/Informatics Competition/src/
Scanner input = new Scanner(new File("/home/sebastian/workspace/Informatics Competition/src/dishin.txt"));
BufferedWriter output = new BufferedWriter(new FileWriter("/home/sebastian/workspace/Informatics Competition/src/dishout.txt"));
ArrayList<Integer> numbers = new ArrayList<Integer>();
while(input.hasNextInt()) {
numbers.add(input.nextInt());
}
numbers.remove(0);
Object max = Collections.max(numbers);
Object min = Collections.min(numbers);
System.out.println(numbers);
int sum = 0;
for (int i = 0; i<=numbers.size(); i++) {
sum += (int)(numbers.get(i));
}
int mean = (int)(sum / numbers.size());
output.write(String.valueOf(min+" "+max+" "+mean));
input.close();
output.close();
}
}
Here is the error:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
at java.util.ArrayList.rangeCheck(ArrayList.java:638)
at java.util.ArrayList.get(ArrayList.java:414)
at Solution.main(Solution.java:35)

It should be
for (int i = 0; i<numbers.size(); i++)
instead of
for (int i = 0; i<=numbers.size(); i++)
index must be less than the size of the numbers. Index starts from 0 till (size - 1)
Use The For-Each Loop to avoid such issues if you are interested to iterate each and every item of the array.
For-each loop (Advanced or Enhanced For loop):
The for-each loop introduced in Java5. It is mainly used to traverse array or collection elements. The advantage of for-each loop is that it eliminates the possibility of bugs and makes the code more readable
Syntax of for-each loop:
for(data_type variable : array | collection){}

Related

Getting random verbiage while printing array variable in Java

I'm learning basics of Java and there seems to be an observation I'm not able to get my head around.
Below is the code that is supposed to print the binary implementation of a base10 number. There are no errors or warnings but logical anomalies I'm looking for answers.
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.*;
public class Main
{
private static final Scanner scanner = new Scanner(System.in);
public static void main(String args[]) {
int n = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
int remainder, quotient, i=0;
int[] binary=new int[n];
/* Binary division -Extracting the 1's and 0's out of the base10 number and storing it in binary[] */
while(n!=0){
remainder=n%2;
quotient=n/2;
binary[i]=remainder;
n=quotient;
i++;
}
int k=i; // For storing the length of array till I want my bits to be reversed since all other bits are initialized to 0.
/*Reversing the binary[] to get the coreect binary value.*/
for(int j=0; j<=i; j++){
int temp=binary[j];
binary[j]=binary[i];
binary[i]=temp;
i--;
}
/*Printing out all the bits of binary number. */
for(int l=1;l<=k;l++){
System.out.print(binary[l]);
}
System.out.println(binary); /*Prints a garbage looking value: For ex- for 25 i get: [I#33909752 */
scanner.close();
}
}
Concerns for my code:
1. I am not able to comprehend possible reasoning as to why I am getting random garbage looking verbiage when I try to print the array variable - binary. Is this something expected? If so what is this?
For example:
In my code when I provide an input of 25 I get [I#33909752 while printing the binary variable. I expected something like an [1,1,0,0,1,0,....,0]
2. I get an extra 0 in front of my binary value if I start my for-loop to print the binary from 0 instead of 1
For example:
for(int l=1;l<=k;l++)
{
System.out.print(binary[l]);
}
Prints 11001 for 25 but if I start the loop from 0, I get 011001. I checked all other places of the code by putting SOPLn statements and nowhere the 0 index of array is getting 0. I wonder why?
Don't import arbitrary stuff coming into you mind. You don't use anything from the packages java.io, java.math, java.security, java.text, java.util.concurrent, or java.util.regex. The only thing needing an import in your code so far is java.util.Scanner
You don't need a construct like scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?"). If you are going to read another token, which does not happen in you code anyway, the scanner will already skip white-space, including line breaks, by default. There's also scanner.nextLine(), but you don't need it here.
Do not close System.in. While a Scanner created around a resource allocated by yourself should be closed, you are not responsible for System.in.
System.out.println(Object) prints the result of calling toString() on the object. For classes not providing an implementation, like arrays, the method inherited from java.lang.Object produces getClass().getName() + "#" + Integer.toHexString(hashCode()). The int[] array's class name is [I, that's why you see [I# plus some hex number.
Use System.out.println(Arrays.toString(binary)); instead. But this will print the entire array, including the unused elements.
Instead of modifying an existing variable in a loop, creating the need for a new variable in the outer scope, you should introduce a new changeable, temporary variable in the loop. Further, you have to become familiar with the standard loop idiom, start at index zero and exclude the end index (use < rather than <=).
The loop variable will contain the excluded end index after the loop, when the condition evaluated to false. This logic also applies to your first while loop; afterwards, i will contain the first unused the index or the used length, both interpretations are valid. Subsequent uses must exclude it, using <, which is, as said, the usual pattern. For your reversal loop, this also implies that the end index must be decremented before being used.
Fixing the loop logic will fix your issue with the leading zero.
import java.util.Arrays;
import java.util.Scanner;
public class Main {
private static final Scanner scanner = new Scanner(System.in);
public static void main(String args[]) {
int n = scanner.nextInt();
int remainder, quotient, i=0;
int[] binary=new int[n];
/* Binary division -Extracting the 1's and 0's
out of the base10 number and storing it in binary[] */
while(n!=0) {
remainder=n%2;
quotient=n/2;
binary[i]=remainder;
n=quotient;
i++;
}
/*Reversing the binary[] to get the correct binary value.*/
for(int j=0, k=i-1; j<k; j++,k--) {
int temp=binary[j];
binary[j]=binary[k];
binary[k]=temp;
}
/*Printing out all the bits of binary number. */
for(int l=0; l<i; l++) {
System.out.print(binary[l]);
}
System.out.println();
System.out.println(Arrays.toString(binary));
}
}
25
11001
[1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Count the number of integers in an array divisible by a given query k

In this problem I have a number of queries for which I have to output the count of integers in the array which is divisible by k(one of the queries).The array contains duplicate elements. I am trying to optimise the problem and my approach is given below :
Code:
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int[] ar={2,4,6,9,11,34,654,23,32,54,76,21432,32543,435,43543,643,2646,4567,457654,75,754,7,567865,8765877,53,2};
int query=sc.nextInt();
int length=ar.length;
int count=0;
for (int i=0;i<query ;i++ ) {
int x=sc.nextInt();
for (int j=0;j<length ;j++ ) {
if(ar[j]>x){
if(ar[j]%x==0){
count++;
}
}
}
System.out.println("Count:"+count);
}
}
The above code gives the correct output, but the complexity is O(query*length) and what if the array size is much bigger,the program will timeout.
Can anyone help me optimize the problem?
One optimization that you could do is to take advantage of short-circuiting, and use one if statement (instead of two).
So change this:
if(ar[j]>x) {
if(ar[j]%x==0) {
to this:
if(ar[j]>x && ar[j]%x==0) {
This will not affect the time complexity of your algorithm, but it will help Branch Prediction.
and maximum value of an element in an array is 10^5
This makes it trivial. Use boolean[10001] and mark all multiples of all queries. Then use it for testing the elements.
The new problem is how to mark all the multiples when there are many small queries. The worst case would be queries like {1, 1, 1, ...}, but duplicates can be trivial removed e.g., using a HashSet. Now the worst case is {1, 2, 3, 4, ...}, which needs 10001/1 + 10001/2 + 10001/3... steps. You can do some special treatment for the smallest queries like removing multiples.
For example, when you look at all queries up to 10 and remove multiples among them, then the worst case is {2, 3, 5, 7, 11, 12, 13, 14...}, which should make the marking pretty fast. This step may not be needed at all.
You can do a precomputation step to build a divisors' table. For every element in the array calculate its divisors. You can calculate divisors of a number efficiently in O(sqrt(V)) assuming V is the maximum value in the array. Building the full table will cost O(n * sqrt(V)) which according to your constraints equals 100,000 * sqrt(100,000) =~ 32M which shouldn't be a lot. Memory complexity would be the same.
Then you can answer your queries in O(1) by a lookup in the table.
You can check this link for how to generate divisors in O(sqrt(V)).

Why is my algorithm to find the total amount of unique integers in a subarray (contiguous), not working for larger amounts of Integers and subarrays?

My algorithm to find the maximum number of unique integers among all possible contiguous subarrays doesn't work for larger amounts of Integers and subarrays.
For instance, I have to read a total amount of 6 Integers from the console and each subarray has a size of 3.
So, for this kind of input 5 3 5 2 3 2
my program should print 3 and this works fine.
The first subarray stores 5 3 5 so the number of unique Integers is 2.
The second subarray stores 3 5 2 so the number of unique Integers is 3.
The third subarray would also print 3 because it stores 5 2 3 and so on...
But, it seems like my algorithm can't handle a total amount of 100000 Integers with a subarray size of 99877.
Can anyone explain me, what I have done wrong?
FYI: I have to use a Deque implementation like LinkedList or ArrayDeque
for (int i = 0; i < totalAmountOfIntegers; i++) {
int anyIntegerNumber = consoleInput.nextInt();
arrayDequeToStoreAllIntegers.addLast(anyIntegerNumber);
hashSetToStoreUniqueIntegers.add(anyIntegerNumber);
if (arrayDequeToStoreAllIntegers.size() == sizeOfEachArrayDequeAsSubArray) {
if (hashSetToStoreUniqueIntegers.size() > quantityOfUniqueIntegersInSubarray) {
quantityOfUniqueIntegersInSubarray = hashSetToStoreUniqueIntegers.size();
}
int firstNumberInDeque = arrayDequeToStoreAllIntegers.remove();
if (hashSetToStoreUniqueIntegers.size() == sizeOfEachArrayDequeAsSubArray) {
hashSetToStoreUniqueIntegers.remove(firstNumberInDeque);
}
}
}
The answer would be simply the unique integers in the whole array, since the array is the superset of all subarrays, all numbers would be present in it
Just find how many unique element exist
To be honest, i don't understand your algorithm. I don't really get what the variables are referring to (although they seem to be named in a semantic way).
But what about this:
import java.util.HashSet;
import java.util.Set;
public class UniqueIntegers {
public static void main(String[] args) {
UniqueIntegers ui = new UniqueIntegers();
Integer[][] integers = {
{3,5,3,4,6},
{1,6,3,2,4},
{2,3,4},
{3,3,6,9,2}
};
Set<Integer> unique = ui.uniqueIntegers(integers);
System.out.println("Unique Integers: " + unique.size());
System.out.println("Integers: " + unique);
}
private Set<Integer> uniqueIntegers(Integer[][] ints){
Set<Integer> result = new HashSet<Integer>();
for (Integer[] iSub : ints){
for (Integer i : iSub){
result.add(i);
}
}
return result;
}
}
It prints:
Unique Integers: 7
Integers: [1, 2, 3, 4, 5, 6, 9]
After a day of researching, I have found my mistake.
My third IF-Statement is wrong. I am comparing, if the size of my HashSet variable is equal to the maximum size of elements each subarray can hold.
Instead, I should compare, if my int variable firstNumberInDeque, which I remove first from my ArrayDeque variable, contains another int variable with the same value. So if this is true, my HashSet variable remains unchanged.
But, if my ArrayDeque variable doesn't contain another int with the same value of firstNumberInDeque than firstNumberInDeque should be removed from my HashSet variable.
Here is the right code:
int firstNumberInDeque = arrayDequeToStoreAllIntegers.remove();
if (!arrayDequeToStoreAllIntegers.contains(firstNumberInDeque)) {
hashSetToStoreUniqueIntegers.remove(firstNumberInDeque);
}

hackerrank xor in arrays

I am trying to solve this problem on hackerrank and it took me a while to get to the trick.
The trick lies in property of xor and the number of times a number appears in a subset of array where a subset is contiguous one (kindly note).
So if we have 1,2,3 the subsets will be:
1
1,2
1,2,3
2
2,3
3
The number of times a value at index i appears in these subsets is (n-i)*(i+1) as it can be seen that 1 appears (3-0)*(0+1) = 3 times. n is the length of the array.
Second trick is XOR of a number is 0 with itself if we take that number even number of times and if it appears odd number of times the answer is the number itself, also the important thing to note is XOR operation is associative.
The problem asks us to xor the subsets and then take XOR of each resultant value.
So rather than brute force approach, I counted the number of times each number appears in array and checked out whether it occurs even number of times or odd number of times but 8 testcases passed and 4 failed. The test case are too long to debug or dry run.
My question is why 4 testcase failed. Here is the Java code.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class J {
static int []arr=new int[100000];
static int an;
public static void main(String[] args)throws IOException {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
int t,i,j,n;String []s;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
t=Integer.parseInt(br.readLine());
int []ans=new int[t];
for(i=0;i<t;++i)
{
n = Integer.parseInt(br.readLine());
s=br.readLine().split(" ");
j=0; an=0;
for(String str:s)
arr[j++]=Integer.parseInt(str);
for(j=0;j<n;++j)
{
if(((j+1)*(n-j))%2==1)
an=an^arr[j];
}
ans[i]=an;
}
for(i=0;i<t;++i)
System.out.println(ans[i]);
}
}
The reason is overflow in
(j+1)*(n-j)
The product may be ~10^10 cause the total size of array is up to 10^5.
So you need to calculate this product using long.
I tested your code with this dummy change:
long a = j + 1;
long b = (n - j);
if((a*b)%2==1) {
an=an^arr[j];
}
And program passed all tests successfully.

Counting Int Occurrences in an Array

I am trying to count the occurrences of integers in an array. I was able to get it to work by piecing together some code I found online but I don't really understand why its working. What I have is:
int[] hand = {2, 4, 3, 2, 4};
int[] numOccurence = new int[hand.length];
for (int i = 0; i < hand.length; i++)
numOccurence[hand[i]]++;
for (int i = 1; i < numOccurence.length; i++)
if (numOccurence[i] > 0)
System.out.println("The number " + i + " occurs " + numOccurence[i] + " times.");
The output is:
The number 2 occurs 2 times.
The number 3 occurs 1 times.
The number 4 occurs 2 times.
How is this code counting the number of occurrences properly? I don't see how its accomplishing this. Thank you in advance!
This is only working because you've a good luck. Try making the second element in the hand array as 5 and see what happens. Its because the number present at the current index of hand is taken as the index of array numOccurence. In case of a number greater than or equal to the length of the numOccurence, you'll get the ArrayIndexOutOfBoundsException.
Thereforce, you can better use a Map for this where the key would be the number and the value could be its count.
Something like this:-
Map<Integer, Integer> numOccurence = new HashMap<Integer, Integer>();
for (int i = 0; i < hand.length; i++) {
int cnt = 1;
if (numOccurence.containsKey(hand[i])) {
cnt = numOccurence.get(hand[i]);
cnt++;
}
numOccurence.put(hand[i], cnt);
}
This code does not really work. At least it does for the author's use case but probably not for yours.
Try with {2, 4, 99, 2, 4}; as hand and it will fail.
The author takes the number found in hand as the index of array numOccurence.
numOccurence has the following structure : {nb occ of 0; nb occs of 1;...; nb occs of 4}. Here 99 will be out of bounds.
When you create an array
int[] numOccurence = new int[hand.length];
it is populated by their default values. For primitive int this value is 0.
This will of course only work if hand contains numbers less than or equal to max index (length -1) of the array otherwise it's ArrayIndexOutOfBound for you mister!
Actually it's the same method for creating histogram for picture ;)
You create a table where you will gather the occurrence.
numOccurence[0] will stock the number of 0
numOccurence[1] will stock the number of 1
etc.
That's what is done by this
for (int i = 0; i < hand.length; i++)
numOccurence[hand[i]]++;
it adds 1 to the value in the case corresponding to the number hand[i]
so if you look at this step by step
first he will take hand[0] = 2
so he will put
numOccurence[2] = numOccurence[2] + 1 ;
which is same (but faster to write) as
numOccurence[2]++;
This kind of performing a count is called counting sort.
The advantage of counting sort is it's speed. The disadvantage is the memory requirements when sorting big numbers.
There is a bug in the code:
int[] numOccurence = new int[hand.length];
numOccurence needs to be as long as the highest number in the list (not the number of numbers in the list). Try changing one of the numbers to 15 and you will get an exception.
The code iterates through the given array hand. it takes each value encountered as an index into the array numOccurrence. for each number n in hand, this will happen exactly as often as n occurs in hand, and each time this happens, the nth element of numOccurrence will be incremented.
thus numOccurrence is effectively an array of counters (assuming that the array elements are initialized with 0).
drawbacks of this approach:
the number of counters allocated depends on the magnitude of numbers in your handarray.
if the numbers in your hand array are distributed sparsely, most of the allocated space is never used.
alternative
you could improve the code by sorting hands first. in the sorted array the indexes of all occurrences of a given number are contiguous, so you scan the sorted array once needing a single counter only to compile the frequencies.
First of all the code is wrong. You should set the size of numOccurence array to the max number value from hand array + 1. For example:
int[] hand = {2, 100};
int[] numOccurence[] = new int[101];
(you should obviously find max number programatically)
Now let's take a look at the algorithm.
It takes each number from hand array, treats it as a numOccurence index value and increments number at that index by 1 in hand array. Note that all elements of numOccurence array are 0 by default at the beginning.
int[] hand = {2, 4, 3, 2, 4};
int[] numOccurence = new int[5];
Steps:
i = 0 (nothing happens, because there is no 0 in hand array)
i = 1 (same situation as for 0)
i = 2 (there are two 2 numbers in hand array, so we do operation numOccurence[2] += 1 twice, which in result gives 0 + 1 + 1 = 2. So we got numOccurence[2] = 2)
it continues for all numbers from 0 to max number from hand array (here: 100).

Categories