2

I am given a problem in which I have to store a list of N numbers in an array and then sort it ,
and then I have to add the numbers at alternative positions and output the sum.
The problem is the constraint of N i.e 0 <= N <= 1011 so I have to declare the N as double type variable here is my code :

ArrayList<Double> myList = new ArrayList<Double>();
myList.add(number);
.....
Collections.sort(myList);
String tempNo = "";
for(double i = 0 ; i < myList.size() ; i=i+2){
tempNo = myStringWayToAdd(tempNo , myList(i)+"");  // Since the sum will exceed the limit of double I have to add the numbers by help of Strings
}

But the problem is that the get(int) method takes an int not double. Is there any other way I can solve the problem? , and Is it even allowed to store number of elements that exceed int range?
Any help will be highly appreciated. Thank you in Advance.


Edit 1 : I can use Strings instead of double in ArrayList and then add up the numbers but my problem is that i need to store N elements which can exceed the range of Integers
  • `get(int)` is for getting a specific index of an element in the arraylist. `get(0)` gets the first element. – Compass Sep 30 '14 at 14:13
  • As documented you can store more than Integer.MAX_VALUE values. BTW To store 2 billion `Double` objects you would need 64 GB of memory at a minimum. – Peter Lawrey Sep 30 '14 at 14:13
  • Good luck working with more than 2 billion objects in memory. – icza Sep 30 '14 at 14:14
  • @Compass yes I want to get the number at alternate index and add them – user3921830 Sep 30 '14 at 14:14
  • @user3921830 aha! I'll write it out :3 – Compass Sep 30 '14 at 14:14
  • if you are using whole numbers I would use `Long` or a collection designed for `long` primitives as it will uses 1/4 the memory. – Peter Lawrey Sep 30 '14 at 14:15
  • @PeterLawrey But still compiler wont accept long i think – user3921830 Sep 30 '14 at 14:16
  • How much memory do you have? – Peter Lawrey Sep 30 '14 at 14:16
  • the index has nothing to do with the data type you store. The index is always an `int` – Peter Lawrey Sep 30 '14 at 14:17
  • @PeterLawrey I can use Strings in for double and add it that way but still I have to Store number of elements that exceed the range of interger – user3921830 Sep 30 '14 at 14:19
  • The purpose of this problem is to example what you would do if the built in collections are not enough. You have up to 100 triilion values which would use about 1 TB of memory at best. Assuming you don't have 1 TB or more to play with what might you do instead? – Peter Lawrey Sep 30 '14 at 14:19
  • @user3921830 in which case you need to do something else. List, nor array, nor any in memory solution is likely to work. – Peter Lawrey Sep 30 '14 at 14:20
  • What I would do is use memory mapped files, or streaming IO which you merge sort as this allows you to use the capacity of your disk space. rather than your memory. However, this is a pretty advanced answer, where does this requirement come from? – Peter Lawrey Sep 30 '14 at 14:24
  • @PeterLawrey I think I need to use a file maybe but that will increase the programming effort – user3921830 Sep 30 '14 at 14:26
  • @user3921830 I suspect that is the point of the question. ;) The first part of the answer is to realise that standard libraries will not do the job and why. – Peter Lawrey Sep 30 '14 at 14:28
  • If you find yourself exceeding the API's like this then it's usually a code smell. I think you need to seriously rethink what it is you're doing. – Ben Thurley Sep 30 '14 at 14:29
  • @BenThurley in real world problems, I agree. I suspect this is an interview style question which is designed to appear simple and see if the candidate realises it's not possible to provide a simple solution. – Peter Lawrey Sep 30 '14 at 14:31

3 Answers3

1

Ah, I misunderstood the question. So we have to store something that is significantly larger than the capacity of int.

Well, we can do this by dividing and conquering the problem. Assuming this is theoretical and we have unlimited memory, we can create a SuperArrayList.

'Scuse my bad generics, no compiler.

public class SuperArrayList<E>() {
    private ArrayList<ArrayList<E>> myList;
    private int squareRoot;
    private double capacity;
    public SuperArrayList(double capacity) {
        this.capacity = capacity;
        squareRoot = Math.ceil(Math.sqrt(capacity)); //we create a 2d array that stores the capacity
        myList = new ArrayList<ArrayList<E>>(); 
        for(int i = 0; i < squareRoot; i++) {
            myList.add(new ArrayList<E>());
        }
    }

    public E get(double index) {
        if(index >= capacity || index < 0) {
            //throw an error
        }
        else {
            return myList.get((int) capacity / squareRoot).get(capacity % squareRoot);
        }       
    }
}

As an alternative to squareRoot, we can do maxValue and add additional arraylists of length maxvalue instead.

Compass
  • 5,867
  • 4
  • 30
  • 42
1

You could use LinkedList because it does not have a size limit (although odd things may begin to happen up there). You should also be able to use BigInteger for your numbers if the numbers themselves could get huge (you don't seem to state).

    // LinkedList can hold more than Integer.MAX_VALUE elements,
    List<BigInteger> myList = new LinkedList<>();
    // Fill it with a few numbers.
    Random r = new Random();
    for (int i = 0; i < 1000; i++) {
        myList.add(BigInteger.probablePrime(10, r));
    }
    // Sort it - not sure if Collections.sort can handle > Integer.MAX_VALUE elements but worth a try.
    Collections.sort(myList);
    // Start at 0.
    BigInteger sum = BigInteger.ZERO;
    // Add  every other one.
    boolean addIt = false;
    for (BigInteger b : myList) {
        if (addIt) {
            sum = sum.add(b);
        }
        addIt = !addIt;
    }

I am not sure if Collections.sort can handle a list of numbers that big, let alone whether it will succeed in sorting within the age of the universe.

You may prefer to consider a database but again you might even have probelms there with this many numbers.

Community
  • 1
  • 1
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
0
boolean add = true;
for (Double doubleNum : myList) {
    if (add) {   
        tempNo = myStringWayToAdd(tempNo , doubleNum+"");
    }
   add = !add;
}

Using this way, you won't have to use index.

Ratshiḓaho Wayne
  • 743
  • 1
  • 5
  • 23