Getting Time limit exceeded error in java - java

class Check {
static void countOddEven(int a[], int n) {
int countEven = 0, countOdd = 0;
for (int item : a) {
if (item % 2 == 0) {
countEven++;
}
}
countOdd = n - countEven;
System.out.println(countOdd + " " + countEven);
}
}
Code is to calculate even and odd numbers in an array. Please help to optimise the code.

You’re code is not correct.
If you were meant to count the even and odd numbers in a, then you are counting the even numbers correctly. If n is not equal to the length of a, then your calculation of the count of odd numbers is incorrect.
If on the other hand — and I’m just guessing — you were meant to count the even and odd numbers among the first n elements, then you are counting the even numbers incorrectly since you are iterating over all of a. Also in this case, if n is much smaller than the length of a, there is an optimization in only iterating over the first n elements as you should.
Finally you may try the following version. I doubt that it buys you anything, but I am leaving the measurements to you.
int countOdd = 0;
for (int ix = 0; ix < n; ix++) {
countOdd += a[ix] & 1;
}
int countEven = n - countOdd;
The trick is: a[ix] & 1 gives you the last bit of a[ix]. This is 1 for odd numbers and 0 for even numbers (positive or negative). So we are really adding a 1 for each odd number.

You should try running code with for loop instead of for each loop
Because ,
When accessing arrays, at least with primitive data for loop is dramatically faster.
however
When accessing collections, a foreach is significantly faster than the basic for loop’s array access.
but if you are getting some another errors , so might have done something wrong while calling the method (make sure n=length of your array)
here is the whole code with main method.
class Check{
static void countOddEven(int a[], int n){
int countEven=0,countOdd=0;
for(int i=0;i<n;i++)
if(a[i]%2==0)
{
countEven++;
}
countOdd=n-countEven;
System.out.println(countOdd+" "+countEven);
}
public static void main(String[] arg){
int a[]={2,3,4,5,6};
int n = 5;
countOddEven(a,n);
}
}

Related

array index not incrementing (need to do casting in square brackets)

I have some doubts as to why the value of index is not incrementing here.
The reason why I have declared my array like that is because I need to store n natural numbers where (1 ≤ n ≤ 1012), so numbers are large which is why I have taken an array of type long, but then I get an error that I cannot put any long value in the group, which is why I cast it to int. Is there any way to declare an array for this type of condition, as I want a large number of indexes, and I can not put a long number in the [ ].
hope you guys understand my problem
CODE:
import java.util.Scanner;
class Error{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
long n = in.nextLong();
long array[] = new long[(int) n];
long index = 0;
for (int j = 1; j <= n; j++) {
if (j % 2 != 0) {//odd
array[(int) index++] = j;
System.out.print(" " + array[(int) --index]);
System.out.print(index);// index value -> always 0 why??
System.out.print(j);
}
}
System.out.println();
}
}
OUTPUT:
Unix-Box ~/Desktop$ javac Error.java
Unix-Box ~/Desktop$ java Error
10
101 303 505 707 909
Unix-Box ~/Desktop$
the middle value is of index and it is always 0
what i shout it to be like
10
101 313 525 737 949
Unix-Box ~/Desktop$
According to
https://www.quora.com/What-is-the-maximum-size-of-the-array-in-Java,
the max size of an array is 2147483647 theoretically, but in practice we would want to use 2147483600 to be safe. Declaring the array as type long will mean that long values can be stored inside. Maybe you can use a two dimensional array to store a long n amount of values. Something like--
public static void main(String[] args)
{
System.out.println("enter the size of the array:");
Scanner in = new Scanner(System.in);
long n = Long.parseLong(in.nextLine());
int secondIndex = 2147483600;
int firstIndex = ((int)(n/secondIndex))+1;
if(secondIndex > n)
{secondIndex = (int)n;
}
else{int leftover = (int)(n%secondIndex);
secondIndex = secondIndex - leftover;}
long[][] array = new long[firstIndex][secondIndex];
//loop through array
outerloop:
for(int i =0;i <firstIndex; i++)
{
for(int z = 0; z<secondIndex; z++)
{
System.out.println("do work with number here: " + array[i][z]);
if(z==(secondIndex-1))
{
z=0;
continue outerloop;
}
}
}
}
You might get a java.lang.OutOfMemoryError:, which can be resolved by reading this article https://plumbr.eu/outofmemoryerror/java-heap-space.
As others have indicated,
array[(int) index++] = j; // You use index and then increment it
System.out.print(" " + array[(int) --index]); // You decrement the index here
That's why index will always be 0 when you print it.
Personally, I don't like mixing brackets with increment operators for the precise reason you're seeing here - it tends to be confusing and it lends itself to subtle (and not-so-subtle) bugs and off-by-one errors. In fact, I really don't like mixing them with any other syntax (with the exception of for loops) as it can quickly become very unclear. For example, if you had done something like
index++;
array[(int)index] = j;
index--;
System.out.print(" " + array[(int)index]);
the problem would've been obvious immediately.
In general, it's a bad idea to sacrifice clarity for brevity.
Also, just to review how the operators in question are working:
index++ - use the value and then increment it
index-- - use the value and then decrement it
++index - increment the value and then use it
--index - decrement the value and then use it.
Here's a C# code sample I put together (Java's behavior will be identical) to illustrate this:
int i = 0;
Trace.TraceInformation((i++).ToString()); // Prints 0
Trace.TraceInformation(i.ToString()); // Prints 1
Trace.TraceInformation((--i).ToString()); // Prints 0
Trace.TraceInformation((i--).ToString()); // Prints 0
Trace.TraceInformation(i.ToString()); // Prints -1
I'd encourage you to trace/step through this to convince yourself that that's the case and to understand exactly why the value is what it is at every point.
Either way, this syntax can be very confusing if overused.

Minimum array value incorrect using recursion

I am trying to create a method to search a 1D array for a minimum value using recursion. It does give me an output but it is always "1" regardless of whether or not the array even contains "1". I am very new to programming and any help is appreciated.
public static int smallest(int[] array)
{
return smallestFrom(array, 0);
}
static int min = 500; //large number
private static int smallestFrom(int[] array, int i)
{
int x = array.length;
if (i < x && array[i] < min)
{
min = array[i];
i++;
smallestFrom(array, i);
}
else if (i < x && array[i] >= min)
{
i++;
smallestFrom(array, i);
}
return min;
}
Output:
2,4,6,1,6,3,8
Smallest: 1
43,76,3,23,95,23
Smallest: 1
Your implementation looks fine to me. Well, that's a bit too much said, but it works. You could improve this quite a bit though:
Large Integer
Why use some arbitrary number as "large number"? This code will break for inputs with larger values than 500. You should just use the constant Integer.MAX_VALUE. There are no larger values possible than this one, it's named in a clear manor and it's defined by the API.
Global variables
This is where the error occurs. Your implementation is designed for singleuse. min will hold 1 after running it with the first array. Since there are no numbers larger than 1 in the second example-array, it will return 1 again. This can be fixed by either resetting min to the original value each time smallest is called, or alternatively completely relinquishing it (see below).
Branching
This problem can be solved with a lot less conditions. Instead of storing the minimum, we could use an alternate definition of the maximum of an array:
max({a, b, c, d, e, f}) = max({a, max({b, c, d, e, f})})
Looks more complicated? Actually it isn't. The idea is that the maximum of an array is the maximum of it's first elements and the maximum of all remaining elements in the array. This could now be translated a lot simpler into code.
Putting it all together
static int min(int[] arr)
{
return minRec(arr, 0);
}
static int minRec(int[] arr, int i)
{
if(i == arr.length)
return Integer.MAX_VALUE;
return Math.min(arr[i], minRec(arr, i + 1));
}
Looks a lot neater, doesn't it? Math.min(int, int) is just the API-implementation of a function that returns the minimum of two parameters.

What is an efficient method for adding thousands of numbers quickly?

I am attempting to solve a challenge, but I have hit a roadblock. I am a beginner programmer attempting to add tens of thousands of numbers. If I wait long enough, my program can easily yield the correct sum, however, I am looking for a more efficient method.
What is an efficient method for adding thousands of numbers quickly?
Side note: I have been reading about modular arithmetic, but I cannot quite wrap my head around it. Not sure if that could be useful for this situation.
I am attempting to get the sum of every prime number below 2 000 000. Here is my code so far:
public class Problem10 {
public static void main (String[] args) {
long sum = 0L;
for(long i = 1L; i < 2000000; i++) {
if(isPrimeNumber((int)i)) {
sum += i;
}
}
System.out.println(sum);
}
public static boolean isPrimeNumber(int i) {
int factors = 0;
int j = 1;
while (j <= i) {
if (i % j == 0) {
factors++;
}
j++;
}
return (factors == 2);
}
}
You can replace your isPrimeNumber() method with this to speed it up substantially.
public static boolean isPrimeNumber(int i) {
if (i==2) return true;
if (i==3) return true;
if (i%2==0) return false;
if (i%3==0) return false;
int j = 5;
int k = 2;
while (j * j <= i) {
if (i % j == 0) return false;
j += k ;
k = 6 - k;
}
return true;
}
This looks like homework, so I'm not going to give you the solution in code. The least you can do is code it yourself.
In your code, isPrimeNumber() is what's taking up most of the time—if I had to guess, I would say 90-99% of it. What you can do to make it faster is implement the Sieve of Eratosthenes.
To start, you create an array that will hold all the prime numbers1. You should start it with a single value: 2. To find more prime numbers, iterate through every integer from 3 to the highest number you want. For each of those numbers, check if that number is divisible by any of the prime numbers in your array. If the next prime number in your array is greater than i / 2, you know that i is prime, and you can add it to your array.
After you have found all the prime numbers from 1 to n, the only way to sum them is by iterating through the array. That part cannot be optimized, but it will not take very long anyways.
1 There are two ways to do this. One is to just use an ArrayList or LinkedList, and add numbers as needed. The other is to create an array that is as large or larger than you need. As mentioned here, the number of primes equal to or less than n is less than (n / log(n)) * (1 + 1.2762 / log(n)), as long as n is greater than 598. If n is less than 598, you can just create an array of length 109.
In regards to the question in the title, "What is an efficient method for adding thousands of numbers quickly?", the only thing I can think of is multithreading. Create an array of all the numbers you want to sum, then have many threads sum different parts of the array. After that, sum all the results from each thread. This method will probably only be noticeably faster when summing huge amount of numbers, e.g. hundreds of thousands or millions.

Why doesn't my program that computes perfect numbers print anything?

I got an assignment to create a program which displays the perfect integers between one and 100. Here is the actual assignment:
Create a PerfectIntegers application that displays all perfect integers up to 100. A perfect integer is a number which is equal to the sum of all its factors except itself. For example, 6 is a perfect number because 1 + 2 + 3 = 6. The application should include a boolean method isPerfect().
I tried and came up with this:
import java.util.ArrayList;
public class PerfectIntegers {
public static boolean isPerfect(int a){
ArrayList<Integer> factors = new ArrayList<Integer>();
int sum=0;
boolean is;
for (int i=1; i<=100; i++){
double r=a/i;
if (r%1==0){
factors.add(i);
}
}for (int i=0;i<factors.size();i++){
sum+=factors.get(i);
}if (sum==a){
is=true;
}else{
is=false;
}return is;
}
public static void getInts(){
for (int i=2; i<=100; i++){
boolean is=isPerfect(i);
if (is!=false){
System.out.print(i+" ");
}
}
}
public static void main(String[] args) {
getInts();
}
}
Eclipse did not show any errors but when I try to run it, the program is terminated and I get nothing.
The problem is likely with double r, as it is not dividing properly 100% of the time.
Your factorization code is wrong. You can fix it like this:
for (int i = 1 ; i < a; i++) {
if (a % i == 0) {
factors.add(i);
}
}
One reason your old code did not work is that you misunderstood the workings of the % operator. It computes the remainder of the division of the left-hand side by the right-hand side, so r % 1 == 0 will be true for all numbers, because 1 divides everything; r % 2 == 0 is a way to detect even numbers, and so on.
The other reason is that you went all the way to 100 in search of divisors. This necessarily includes a, which automatically puts the total above the number itself, because 1 is already on the list.
Once you get this working, you could simplify the code by dropping the list of factors. Since the sum of all factors is all that you need, you might as well compute it in the factorization loop, and drop the loop that follows it:
sum = 0;
for (int i = 1 ; i < a; i++) {
if (a % i == 0) {
sum += i;
}
}
dasblinkenlight has already provided the correct answer. Let me just add that since this seems to be a (potentially graded) assignment you might consider refactoring the getInts() method as well.
boolean is=isPerfect(i);
if (is!=false){
System.out.print(i+" ");
}
is actually equal to
if (isPerfect(i)){
System.out.print(i+" ");
}
since isPerfect() already returns a boolean that can be used inside the condition of the if-statement.
It can be argued (even though I strongly disagree in this concrete case) that it might be more readable to first store the return value in a variable like in in the first variation. But even then you should never have to check for
if (is!=false) { //...
but should be using
if (is) { // ...
instead.

Project Euler 14: Issue with array indexing in a novel solution

The problem in question can be found at http://projecteuler.net/problem=14
I'm trying what I think is a novel solution. At least it is not brute-force. My solution works on two assumptions:
1) The less times you have iterate through the sequence, the quicker you'll get the answer. 2) A sequence will necessarily be longer than the sequences of each of its elements
So I implemented an array of all possible numbers that could appear in the sequence. The highest number starting a sequence is 999999 (as the problem only asks you to test numbers less than 1,000,000); therefore the highest possible number in any sequence is 3 * 999999 + 1 = 2999998 (which is even, so would then be divided by 2 for the next number in the sequence). So the array need only be of this size. (In my code the array is actually 2999999 elements, as I have included 0 so that each number matches its array index. However, this isn't necessary, it is for comprehension).
So once a number comes in a sequence, its value in the array becomes 0. If subsequent sequences reach this value, they will know not to proceed any further, as it is assumed they will be longer.
However, when i run the code I get the following error, at the line introducing the "wh:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3188644
For some reason it is trying to access an index of the above value, which shouldn't be reachable as it is over the possible max of 29999999. Can anyone understand why this is happening?
Please note that I have no idea if my assumptions are actually sound. I'm an amateur programmer and not a mathematician. I'm experimenting. Hopefully I'll find out whether it works as soon as I get the indexing correct.
Code is as follows:
private static final int MAX_START = 999999;
private static final int MAX_POSSIBLE = 3 * MAX_START + 1;
public long calculate()
{
int[] numbers = new int[MAX_POSSIBLE + 1];
for(int index = 0; index <= MAX_POSSIBLE; index++)
{
numbers[index] = index;
}
int longestChainStart = 0;
for(int index = 1; index <= numbers.length; index++)
{
int currentValue = index;
if(numbers[currentValue] != 0)
{
longestChainStart = currentValue;
while(numbers[currentValue] != 0 && currentValue != 1)
{
numbers[currentValue] = 0;
if(currentValue % 2 == 0)
{
currentValue /= 2;
}
else
{
currentValue = 3 * currentValue + 1;
}
}
}
}
return longestChainStart;
}
Given that you can't (easily) put a limit on the possible maximum number of a sequence, you might want to try a different approach. I might suggest something based on memoization.
Suppose you've got an array of size 1,000,000. Each entry i will represent the length of the sequence from i to 1. Remember, you don't need the sequences themselves, but rather, only the length of the sequences. You can start filling in your table at 1---the length is 0. Starting at 2, you've got length 1, and so on. Now, say we're looking at entry n, which is even. You can look at the length of the sequence at entry n/2 and just add 1 to that for the value at n. If you haven't calculated n/2 yet, just do the normal calculations until you get to a value you have calculated. A similar process holds if n is odd.
This should bring your algorithm's running time down significantly, and prevent any problems with out-of-bounds errors.
You can solve this by this way
import java.util.LinkedList;
public class Problem14 {
public static void main(String[] args) {
LinkedList<Long> list = new LinkedList<Long>();
long length =0;
int res =0;
for(int j=10; j<1000000; j++)
{
long i=j;
while(i!=1)
{
if(i%2==0)
{
i =i/2;
list.add(i);
}
else
{
i =3*i+1;
list.add(i);
}
}
if(list.size()>length)
{
length =list.size();
res=j;
}
list.clear();
}
System.out.println(res+ " highest nuber and its length " + length);
}}

Categories

Resources