1

For context, I can't use anything that isn't taught in csc101 (what you learned may have been different) so I can't use things like vectors, structs, and classes. More context, I have an assignment which requests I have a function which takes an array numarray with random values, and removes the values from 20 to 40. As I understand it, the best way to do that is to make a new array and take the valid values from numarray and put them in a new array temparray. I tried implementing this the best way I could figure up, but it seems to only spit out a set number which is a long negative number over and over in a loop. I know it is this function because when not called I don't have a problem. The problem also doesn't occur if I comment out the while loop at the end of the function. I will first attach the function in question, and then the whole of the program for added context. Open to any criticism, but passing the class is my priority over elegance, and efficiency. If the professor wants something done a certain way, I must oblige. Thanks for your time.

The required function:

void Delete(int* numarray, int *temparray) {

    int arrayindex = 0;
    for (int index = 0; index < 100; index++) {
        if (numarray[index] < 20 && numarray[index] > 40) {
            temparray[arrayindex] = numarray[index];
        }   arrayindex++;
    }
    cout << arrayindex << endl;
    cout << temparray[arrayindex] << endl;
    while (arrayindex <! 0) {
        cout << temparray[arrayindex - 1] << endl;
   }
}

The whole project:

#include <iostream> 
#include <fstream>
#include <time.h>
#include <stdlib.h>
#include <cstddef>
#include <array> 


using namespace std;
ofstream randomData;
ifstream inputrandomData;
void randomgenerator();
void read(int *numarray);
void printArray(int *numarray);
void searchArray(int* numarray);
void Delete(int* numarray, int* temparray);


void randomgenerator() {
    srand(time(0));
    randomData.open("randomData.txt");
    for (int counter = 0; counter < 100; counter++) {
        randomData << rand() % 100+1 << endl;
    }
    randomData.close();

}


void read(int *numarray) {
    inputrandomData.open("randomData.txt");

    for (int i = 0; i < 100; i++) {
        inputrandomData >> numarray[i];

    }
    inputrandomData.close();

}



void printArray(int *numarray) {

    for (int index = 0; index < 100; index++) {
        cout << numarray[index] << endl;
    }

}

void searchArray(int* numarray) {
    int searchedArray[6] = {};
    for (int index=0; index < 100; index++) {
        if (numarray[index] > searchedArray[0]) {
            searchedArray[0] = numarray[index];
            searchedArray[1] = index;

        }
    }
    for (int index = 0; index < 100; index++) {
        if (numarray[index] > searchedArray[2] && numarray[index] < searchedArray[0]) {
            searchedArray[2] = numarray[index];
            searchedArray[3] = index;
        }
    }

    for (int index = 0; index < 100; index++) {
        if (numarray[index] > searchedArray[4] && numarray[index] < searchedArray[2]) {
            searchedArray[4] = numarray[index];
            searchedArray[5] = index;
        }
    }
    cout << "Largest Number: " << searchedArray[0] << " " << "Index: " << searchedArray[1] << endl;
    cout << "Second Largest Number: " << searchedArray[2] << " " << "Index: " << searchedArray[3] << endl;
    cout << "Third Largest Number: " << searchedArray[4] << " " << "Index: " << searchedArray[5] << endl;

}

void Delete(int* numarray, int *temparray) {

    int arrayindex = 0;
    for (int index = 0; index < 100; index++) {
        if (numarray[index] < 20 && numarray[index] > 40) {
            temparray[arrayindex] = numarray[index];
        }   arrayindex++;
    }
    cout << arrayindex << endl;
    cout << temparray[arrayindex] << endl;
    while (arrayindex <! 0) {
        cout << temparray[arrayindex - 1] << endl;
   }
}


int main() {
    int numarray[100] = {};
    int temparray[100] = {};
    randomgenerator();
    read(numarray);
    printArray(numarray);
    searchArray(numarray);
    Delete(numarray, temparray);

    return 0;
}
  • 1
    There are multiple bugs in the shown code. Let's start with the first bug: "if (numarray[index] < 20 && numarray[index] > 40)". Can you give me any number that's less than 20 and more than 40? What kind of a number would this be? Remember the Golden Rule Of Computer Programming: "your computer always does exactly what you told it to do instead of what you want it to do". What did you tell your computer to do here? – Sam Varshavchik Feb 06 '20 at 03:49
  • Ah dang. i want to facepalm so hard right now. Overthinking again. Thanks very much. – killerkody gaming Feb 06 '20 at 03:51
  • That's not the only one, there's more that you will have to find and fix. Just remember The Goldern Rule, and it should be easy to figure everything out. – Sam Varshavchik Feb 06 '20 at 03:53
  • @SamVarshavchik I fixed that. Now I see why even when I called a specific index like temparray[1] I was still getting a dummy value. Alright, now I know my problem lies in the way I am incrementing, because if there is no value on the index printed, it will output a dummy value. – killerkody gaming Feb 06 '20 at 03:54
  • I believe you are missing the point of the exercise by using temparray. I will write up a quick answer for you. By the way, you wrote a nicely formatted question that makes it easy to help you. – okovko Feb 06 '20 at 03:57
  • I got it to increment correctly. I made another for loop with an int named newindex. I set the condition to newindex < arrayindex because array index will only increase when something is written to temparray. It runs correctly now, but I am open to any ideas @okovko – killerkody gaming Feb 06 '20 at 04:00
  • @killerkodygaming Now that I'm making a point, I'd recommend you to gain reputation by reading in depth resources on C / C++, and posing meaningful questions about these resources that generate discussion (and reputation without wasting anyone's time, including your own). I would recommend [Agner Fog's](https://www.agner.org/optimize/) books, or [this](https://lwn.net/Articles/250967/), or [that](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html). – okovko Feb 06 '20 at 06:09
  • @killerkodygaming As an example, I posted [about Agner Fog's Optimizing C++](https://stackoverflow.com/questions/54743186/do-static-variables-impede-data-caching), and Agner Fog himself answered me on StackOverflow. At least, don't bother fabricating some "debugging" process in the comments before copy pasting your prepared solution. – okovko Feb 06 '20 at 06:11
  • @okovko, are you suggesting that I had already figured out my solution before posting the question? I have no desire for reputation or badges. I just want to learn to program, and right now passing my CSC classes are the way I am doing that. Sometimes communicating with other people can prompt my thought process to change and I can then see what I am doing wrong. – killerkody gaming Feb 06 '20 at 22:39

3 Answers3

1

Here was the solution I was prompted to come up with. There were a couple logical flaws. First, my conditional would never be true as I used the && operator which means the number would have to be lower than 20 AND greater than 40. Changed that to || operator to check for one or the other. Then, as stated in the comments, I had been overthinking it by creating another array. You have to have two different index counters in order to read from the original data set, and to write the new data set in behind it. Now, when ran, the numarray takes values at the numarray[arrayindex] which is only incremented when the conditional is called, and reads from numarray[index] which increments on every for loop. Here is the edited function below:

void Delete(int* numarray) {

    int arrayindex = 0;
    for (int index = 0; index < 100; index++) {
        if (numarray[index] < 20 || numarray[index] > 40) {
            numarray[arrayindex] = numarray[index];
            arrayindex++;
        }   
    }
    cout << arrayindex << endl;
    for (int newindex = 0; newindex < arrayindex; newindex++) {
        cout << numarray[newindex] << endl;
    }
}

I removed temparray from the program entirely. Thanks for the help.

0

You can break up the problem into many pieces at first so that it is easier to program and understand. If you're struggling, keep splitting up the task into smaller simpler functions, like this:

// remove a range of values from arr
void remove_range(int *arr, int size, int from, int to) {
  for (int r = from; r <= to; r++) {
    remove_all(arr, size, r);
  }
}    

// remove all of a single value from arr
void remove_all(int *arr, int size, int value) {
  for (int i = 0; i < size; i++) {
    if (arr[i] == value) {
      remove_one(arr, size, value);
    }
  }
}

// remove the first occurrence of a value from arr
void remove_one(int *arr, int size, int value) {
  for (int i = 0; i < size; i++) {
    if (arr[i] == value) {
      remove_i(arr, size, value);
    }
  }
}
// remove the value at an index of arr by shifting all the entries after it left one
// and putting a 0 at the end in case this is the first removal
void remove_i(int *arr, int size, int i) {
  for (; i < size - 1; i++) {
    arr[i] = arr[i + 1];
  }
  arr[i] = 0;
}
okovko
  • 1,851
  • 14
  • 27
0

If I'm understanding your project correctly, you have the following main objectives:

  • Without using std::vector or other classes/structs, copy an array into another
  • The copied-to array must not contain values from 20-40 (assuming inclusive)

With that in mind, there are some other things you may want to keep in mind. For example, does speed or memory matter more?

If speed matters more, you can create an array (named copy_to) with equal size of copy_from array. Then, just test every value in copy_from to make sure it's not within [20, 40] before copying it to copy_to. However, If memory management matters more, not only would I do everything from the "speed" method, but I would also keep track of how many elements are being added to copy_to. After they are copied, make a new array (copy_to_final) of the exact size needed, copy copy_to to copy_to_final, and delete copy_to.

Here's what the code would look like for the speed method:

int* make_prejudice_array(int[] copy_from, size_t size)
{
    // Make array to store new values in
    int* copy_to = new int[size];

    size_t copy_to_size = 0;
    // Copy valid values into 'copy_to'
    for (size_t i = 0; i < size; ++i)
    {
        if (copy_from[i] < 20 || copy_from[i] > 40)
        {
            copy_to[copy_to_size] = copy_from[i];
            copy_to_size++;
        }
    }

    return copy_to;
}

And, for the memory management way, just a small addition:

int* make_prejudice_array(int[] copy_from, size_t size)
{
    int* copy_to = new int[size];

    size_t copy_to_size = 0;
    for (size_t i = 0; i < size; ++i)
    {
        if (copy_from[i] < 20 || copy_from[i] > 40)
        {
            copy_to[copy_to_size] = copy_from[i];
            copy_to_size++;
        }
    }

    // Make new array to hold the exact number of elements needed
    int* copy_to_final = new int[copy_to_size];
    for (size_t i = 0; i < copy_to_size; ++i)
        copy_to_final[i] = copy_to[i];

    // Don't forget to delete 'copy_to' to prevent a mem leak
    delete[] copy_to;
    copy_to = nullptr;

    return copy_to_final;
}

If I missed something from your question. Let me know and I'll do my best to incorporate it. Hope that helps!

Drake Johnson
  • 640
  • 3
  • 19