2
 public static void main(String[] args) {
     double [] boxes;
        boxes = new double[]  {20, 10, 5, 40, 20, 41, 41, 2, 6, 7, 3, 4, 5, 6, 23, 34, 7, 8, 2, 2};
        double heaviest = 0;
        double normal = 0;
        double heavy = 0;
        double totalCost;
        double a = 0;
        double b = 0;
        int repeatCount=0;

        for (int i = 1; i < boxes.length; i++) {
            if (boxes[i] > heaviest)
                heaviest = boxes[i];
        }

        for(double element: boxes) {
            if(element==heaviest) {
                repeatCount = repeatCount+1;
            }
        }

        System.out.println("Count :" +repeatCount);

        for (int j =0; j<boxes.length; j++) {
            if (boxes[j] < heaviest) {
                a = boxes[j] * 2;
                normal = normal+a;
            } else {
                b =  (boxes[j] * 3.5);
                heavy = heavy+b;
            }
        }
        totalCost = normal+heavy;
        System.out.println("total cost of the insuranse is  "+ totalCost);
    }

Part 1: I need to multiply the largest element by 3.5 and rest with 2 and then add the value to get the total.

Part 2: Also I want the number of occurrences of the largest element. OR We can also store the largest element in another array.

In my code, I'm done with the part 1 and for part 2, I'm taking the count of the occurrences of the largest element.

My question:

Is there any other way to do this for reducing the compilation time or for the code to be more optimized if there are more than 1000 elements?

I have also tried using the Collections.frequency(myArray, largestElement) by converting array to list.

TryinHard
  • 4,078
  • 3
  • 28
  • 54
Sagar Panda
  • 561
  • 3
  • 17
  • As you are taking the largest element from the array you can try to sort the array in descending order. so you will get the first element to perform your said task. – Vinayak Pingale Aug 18 '15 at 17:43

2 Answers2

6

As always, correctness is more important than performance.

Not sure why it ignores the first box when looking for the heaviest.

You could reduce the code, but your biggest problem is your code won't be run long enough to get compiled by the JIT. And even then it will be tiny compared to the startup cost of Java.

In short, I wouldn't worry about performance unless your program lasts for a few hundred milli-seconds.

BTW You could use a single loop which would make the code shorter, but like I said it won't make much difference in this case.

This is how I might write it.

double[] boxes = {20, 10, 5, 40, 20, 41, 41, 2, 6, 7, 3, 4, 5, 6, 23, 34, 7, 8, 2, 2};
double heaviest = -1;
int count = 0;
double sum = 0;
for (double box : boxes) {
    sum += box;
    if (box > heaviest) {
        count = 1;
        heaviest = box;
    } else if (box == heaviest) {
        count++;
    }
}

// double total = sum * 2 - heaviest * count * 2 + heaviest * count * 3.5;
double total = sum * 2 + heaviest * count * 1.5;
System.out.println("total: " + total);

Note: there is just one loop. You can work out the count and the sum as you go.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • *"As always, correctness is more important than performance."* ... Are you sure about "always" ? – Jean-François Savard Aug 18 '15 at 17:50
  • @Jean-FrançoisSavard would you like a system which is wrong but very fast or one which is right but fast enough. Note: I consider a system which is not fast enough be to be incorrect, which is my out here ;) There are exceptions such as light weight performance monitors which are just an estimate anyway. – Peter Lawrey Aug 18 '15 at 17:53
  • Make sense, "correctness" did not appear that way in my head at first. +1. – Jean-François Savard Aug 18 '15 at 17:55
  • @Jean-FrançoisSavard I suspect I am in the minority, but performance should be a functional requirement. If it's too slow it is broken. However, this assumes that a) you have a figure you can measure and b) you measured it. A general, "how can I make my code faster?" which should really be, "Is there a way to tidy up my code?" isn't going to lose money if the program take a 10% longer than it might. – Peter Lawrey Aug 18 '15 at 17:59
  • @PeterLawrey: Thanks for your answer. Also no doubt on the point that correctness is more important. – Sagar Panda Aug 18 '15 at 18:05
  • 1
    not to forget, Reduced code and avoided iterations or for loop in itself is a big performance addition. I myself was going to post a similar code in one single for loop and noticed you have already done the same. When you already know what is the orientation of your data, there is always chance to avoid additional code. – Acewin Aug 18 '15 at 18:06
  • While I agree that something too slow should be considered broken, I'm still skeptic about wether performance should be called a *functional* requirement. Perhaps it would be more suitable as a *maintenance* requirement ? Anyway, I agree that it's not a waste of money, but it seems like most of the time the client doesn't :/ – Jean-François Savard Aug 18 '15 at 18:10
  • @Jean-FrançoisSavard if a have a program which prints, but doesn't do it for a day, can I say, don't worry it is working correctly ;) – Peter Lawrey Aug 18 '15 at 18:14
  • 1
    Please define what you mean by "working" ... I have no idea if your program is meant to print once a day or if this behaviour incorrect ;) ... More seriously, It actually does what it is supposed to, just in a very slow maneer. We can surely say that the program is broken, but can we really clasify the issue as a *"functional"* problem considering it exercise the same *function* ? – Jean-François Savard Aug 18 '15 at 18:20
0
public static void main(String[] args) {
    double [] boxes = new double[]  {20, 10, 5, 40, 20, 41, 41, 2, 6, 7, 3, 4, 5, 6, 23, 34, 7, 8, 2, 2};
    double heaviest = 0;
    double normal = 0;
    double heavy = 0;
    double totalCost;
    int repeatCount=0;

    for (double d : boxes) {
        heaviest = Math.max (boxes[i], heaviest);
    }

    for (double d : boxes) {
        if(d == heaviest) {
            repeatCount++;
        }
    }
    System.out.println("Count: " + repeatCount);

    for (double d : boxes) {
        if (d == heaviest) {
            heavy += d * 2.0;       
        } else {
            heavy += d * 3.5;
        }
    }
    totalCost = normal+heavy;

    System.out.println("Total cost of the insuranse is: " + totalCost);
}

This is following your code, with your knowledge but fixed a bit. You never need to use i, nor do you need to store the results in a or b, instead you can user the += operator.

That being said double d1 == double d2 is dangerous to use. I do not recommend to use them directly. Take a read at this article or this. Actually, I recommend you to read both.

Community
  • 1
  • 1
Emz
  • 1,280
  • 1
  • 14
  • 29
  • 1
    You have worked out that all the loops have the same form, try to see if you can use just one loop (without looking at mu answer ;) – Peter Lawrey Aug 18 '15 at 17:50
  • 1
    Yes they can as per your answer, however I didn't want to overdo the code reworking, that answer is more suited for CodeReview than StackOverflow. – Emz Aug 18 '15 at 17:56