0

I am working on homework which requires:

Create a dynamic array of 1,000,000 ints. Each int is randomly generated between -50,000 and 50,000. As each int is generated, it is inserted into the array in sorted order. Do NOT fill the array and then sort it.

I kind of figure it out but still have two problems with it.

~ IDE shows Thread 1: EXC_BAD_ACCESS when I set the size to 1,000,000 or 100,000.

It surprised me because 100,000 integers only take less than half meg of space, right?

~ 10,000 integers take 1m25s to compile, and 20,000 take 12m.

Is it normal that time increases this much when I double the size? is my algorithm O(n).

I haven't taken any DS class, and not allowed to use vector. Really don't know what to do besides shifting elements when inserting an element into array.

Any help will be really appreciated.

const int SIZE = 10000;

int randBetween(const int &, const int &);
int findIndex(const int, array<int, SIZE>, int begin, int end);

int main(int argc, const char * argv[]) {
    srand(time(0));
    int randomNum = 0;
    int index = 0;
    int numOfElements = 0;  // number of random number generated
    int count = 0;          // number of elments get printed
    int hours = 0;
    int minutes = 0;
    int seconds  = 0;
    const int min = -50000;
    const int max = 50000;

    auto start = std::chrono::high_resolution_clock::now();
    array<int, SIZE> intArray;
    intArray.at(0) = randBetween(min, max);
    numOfElements++;

    cout << "in progress..." << endl;

    for(auto it = intArray.begin() + 1; it != intArray.end(); it++){
        numOfElements++;
        randomNum = randBetween(min, max);
        index = findIndex(randomNum, intArray, 0, numOfElements - 1);
        // shift all elements after index of randomNum by 1
        for (int i = (numOfElements - 1); i > index ; i--){
            intArray.at(i) = intArray.at(i - 1);
        }
        // insert randomNum into array at index found
        intArray.at(index) = randomNum;
    }
    cout << endl << "begin: " << endl;
    for (auto it = intArray.begin(); it != intArray.end(); it++) {
        count++;
        cout << right << setw(6) << *it << " ";
        if((count) % 10 == 0) cout << endl;
    }
    cout << "end..." <<endl;

    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = end - start;
    seconds = static_cast<int>(elapsed.count()) % 60;
    minutes = elapsed.count() / 60;
    hours = minutes / 60;
    cout << fixed << hours << " Hours, " << minutes << " Minutes, " << seconds << " Seconds elapsed.";

    return 0;
}
int randBetween(const int &min, const int &max){
    return (rand()% (max - min + 1) + min);
}

int findIndex(const int num, array<int, SIZE> intArray, int begin, int end){
    int index = 0;
    while (begin <= end) {
        index = (begin + end )/ 2;
        if (num == intArray.at(index)) {
            break;
        }else if (num < intArray.at(index)){
            if (index == begin){
                break;
            }else if (num >= intArray.at(index - 1)) {
                break;
            }
            end = index;
            findIndex(num, intArray, begin, end);
        }else if (num > intArray.at(index)){
            if ((index + 1 )== end){
                index++;
                break;
            }else if (num <= intArray.at(index)) {
                index++;
                break;
            }
            begin = index;
            findIndex(num, intArray, begin, end);
        }
    }
    return index;
}

Zhihan L
  • 35
  • 7
  • `array intArray;` -- This is not a dynamic array. You are more than likely exhausting the stack memory declaring SIZE as `1000000`. – PaulMcKenzie Apr 16 '20 at 04:03
  • In C++ dynamic array is spelled [`std::vector`](https://en.cppreference.com/w/cpp/container/vector). You may be required to work without `std::vector` as a lesson in memory management. In this case your best option is usually two write your own version of `std::vector` To write a `vector` it is important to be [familiar with RAII](https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii) and with [The Rule of Three (and friends)](https://en.cppreference.com/w/cpp/language/rule_of_three) – user4581301 Apr 16 '20 at 04:10
  • 1
    As to your assignment -- you may be defeating the whole purpose of binary search if the data happens to be coming in almost sorted, but in a descending order, and you're inserting in an ascending order. Imagine if the data you get is 1000000, 999999, 999998, … with the last items may be small values. You are spending time having to shift almost a million numbers "up" when inserting the small numbers so as to make space for the inserted number. It can degenerate into an `O(n*n)` time complexity. That's why loading the entire data, and then sorting, is usually a better option. – PaulMcKenzie Apr 16 '20 at 04:16
  • 2
    Maybe the assignment is to show you how trying to maintain a sorted list by trying to sort the list as the numbers come in is not a good approach, and simply getting all the numbers and then calling a single sort is usually more efficient.. – PaulMcKenzie Apr 16 '20 at 04:25
  • 1
    @PaulMackenzie is probably right. Try running your program and printing numOfElements with every loop. You will see that the first few thousand numbers fly in, then the rate starts to decrease. I imagine that is why the number of hours is tracked. For the case that Paul described, it could take that long. – Matt Fenlon Apr 16 '20 at 04:28
  • Note that you can maintain a sorted list, but a simple array, or even `std::vector` is not the container for this job. A balanced binary search tree would be more efficient. – PaulMcKenzie Apr 16 '20 at 04:36
  • Thanks for all your reply. very helpful to me. – Zhihan L Apr 16 '20 at 04:53

0 Answers0