tired
tired

Reputation: 9

How to get consecutive numbers in array set to 0 C++

This is what it's supposed to do: This function should take a 2D array and should check each row and each column for any value that is repeated/matched 3 times consecutively on a row or column. It should also recognize if there are more than 3 and should consider it all 1 match. The matched values should all be set to zero. Use the same const size. You do not know what the values could be (in the example below they are 1,2 and 3 but it could be any value other than zero). void checkMatches(int[ARRAY_SIZE][ARRAY_SIZE] arr)

This is what I have rn:

const int ARRAY_SIZE=8;
void checkMatches(int arr9[ARRAY_SIZE][ARRAY_SIZE]) {
    
    int count = 0;

    //check each row
    for (int row = 0; row < ARRAY_SIZE; row++) {
        int i = arr9[row][0];
        for (int col = 1; col < ARRAY_SIZE; col++) {
            if ( arr9[i] == arr9[i + 1]) {
                count++;
                if (count >= 3) {
                    i = 0;
                }
            }
            else {
                count = 0;
            }
        }
    }
    //check each column
    for (int col = 0; col < ARRAY_SIZE; col++) {
        int i = arr9[0][col];
        for (int row = 1; row < ARRAY_SIZE; row++) {
            if (arr9[i] == arr9[i + 1]) {
                count++;
                if (count > +3) {
                    i = 0;
                }
            }
            else {
                count = 0;
            }
        }
    }

}

int main(){
    int val;
    int arr9test[8][8];

    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            cout << "Enter number to populate the array (include a few consecutive numbers): ";
            cin >> val;
            arr9test[j][i] = val;
        }
    }
    checkMatches(arr9test);
    cout << "Replacing consecutive numbers with 0's: " << arr9test << endl;

}

Any tips would be much appreciated!

This is the output I'm getting. (very much not an array) enter image description here

Upvotes: 0

Views: 549

Answers (1)

John
John

Reputation: 827

There are many things wrong with your code at the moment.

void checkMatches(int arr9[ARRAY_SIZE][ARRAY_SIZE]) // 01
{
    int count = 0;

    //check each row
    for (int row = 0; row < ARRAY_SIZE; row++) {
        int i = arr9[row][0]; // 02
        for (int col = 1; col < ARRAY_SIZE; col++) {
            if ( arr9[i] == arr9[i + 1]) { // 03
                count++;
                if (count >= 3) {
                    i = 0; // 04, 05
                }
            }
            else {
                count = 0;
            }
        }
    }
    //check each column
    for (int col = 0; col < ARRAY_SIZE; col++) {
        int i = arr9[0][col]; // 02
        for (int row = 1; row < ARRAY_SIZE; row++) {
            if (arr9[i] == arr9[i + 1]) { // 03
                count++;
                if (count > +3) {
                    i = 0; // 04, 05
                }
            }
            else {
                count = 0;
            }
        }
    }
}

I have marked the problematic lines with // xx, where xx is the problem number as below:

  1. You are passing in an array without dimensions. Try passing in the dimensions too. For example:
void checkMatches(int[][] myArray, size_t xSz, size_t ySz)
  1. You are creating a stack variable that serves no purpose. Remove it.
  2. You are comparing the "future" address. This is incompatible with your loop (start with 1), and will result in out of bounds behaviour. This should be fixed to use the "past" address:
if (arr9[row][col] == arr9[row][col - 1]) {
  1. You are writing to the temporary variable 'i' which serves no purpose. You need to write to the table itself.
arr9[row][col] = 0;

However, this is a problem in itself, as it will only write the 0 on the 3rd match, and will effectively reset count, as the next compare will compare against the 0 just written.

  1. You are writing results before doing the second pass. Consider the table below:
1 2 3 4 5 6 7
2 3 4 4 4 4 6
3 2 1 4 1 2 3

You desire the following, if I understand you correctly:

1 2 3 0 5 6 7
2 3 0 0 0 0 6
3 2 1 0 1 2 3

This means you should record the addresses as you read, and perform updates at the end.

Here's a pseudo-code rewrite of your method. I have used C# tuple notation for brevity:

void checkMatches(int[][] arr9, size_t ySz, size_t xSz) // 01
{
    std::vector<(y, x)> lst; // a vector of some type of tuple structure.
    int count = 0;

    //check each row
    for (size_t row = 0; row < ySz; row++)
    {
        for (size_t col = 1; col < xSz; col++)
        {
            if ( arr9[row][col] != arr9[row][col - 1])
            {
                if (count > 3)
                {
                    size_t cl = col - 1;
                    while (count-- > 0)
                    {
                        lst.push_back(row, cl--);
                    }
                }
                else
                {
                     count = 0;
                }
             }
             else
             {
                 count++;
             }
        }

        if (count > 3)
        {
            size_t cl = xSz - 1;
            while (count-- > 0)
            {
                lst.push_back(row, cl--);
            }
        }
    }

    // check each column
    // TODO: apply the above code to check columns this time.  I won't copy/paste here, you can do that.  Keep adding to lst.

    // Update the table.
    for ((size_t, size_t) xy : lst)
    {
        arr9[xy.y][xy.x] = 0;
    }
}

Upvotes: 1

Related Questions