Checking if an array is 'right' (C++)
Asked Answered
N

4

5

A right array

Let's assume we have an array with an N length, made of capital letters A, B, and C. We call the array 'a right array' if between every two C letters which come one after another in the array, there are more A letters than B letters. My job is to discover whether or not a given array is 'right' and if so, I should print out "RIGHT", else I should print for how many pieces (places between to Cs) the given condition is untrue (there are more Bs than As).

Input: In the first line we enter the number of lettes in the array N (1 < N > 200). In the next line we enter the array without empty spaces in-between.

Output: Print out the answer in a single line.

Examples:

  • Input: 16 ABBCAABCACBAAACB Output: RIGHT

  • Input: 15 ABBCABCACBAAACB Output: 1

  • Input: 14 CABCABBCBAABBC Output: 3

Now, I have tried solving this problem, but the third example isn't working for me - I get an output of 2 and as given above I should get 3, other than that - it compiles perfectly fine.

    #include <iostream>

using namespace std;

int main()
{
    int N;
    cin >> N;
    char Ar[N];
    int A = 0;
    int B = 0;
    int piece = 0;
    int attempt = 0;

    for (int i = 0; i < N; i++) {
        cin >> Ar[i];
    }

    for (int i = 0;  i < N; i++) {
        if (Ar[i] == 'C') {
            for (int j = i + 1; i < N; j++) {
                if (Ar[j] == 'A') {
                    A++;
                } else if (Ar[j] == 'B') {
                    B++;
                } else if (Ar[j] == 'C') {
                    i = j;
                    break;
                }
            }
            if (A > B) {
                piece++;
                attempt++;
            } else if (A <= B) {
                attempt++;
            }
            A = 0;
            B = 0;
        }
    }


    if (piece == attempt) {
        cout << "RIGHT";
    } else {
        cout << attempt - piece;
    }

    return 0;
}
Nutt answered 2/3, 2019 at 18:44 Comment(21)
char Ar[N]; is not valid C++Alphabetic
@NeilButterworth I have been told that before, but this is the way we're taught in class. It's running completely fine so far, I just need to find why the third example isn't working.Nutt
for 14 CABCABBCBAABBC the output is 2, not 3Vigorous
@Vigorous It displays 2 for me as well, but it should be 3 since CABC is the first piece where A = 1 and B = 1 and they’re equal, so A isn’t greater than B.Nutt
@Nutt so Output must be Expected output in the question to put it clear ^^Vigorous
@Vigorous Examples are given in the problem, not by me.Nutt
@Nutt "isn't working for me" is not a useful problem description. What do you mean by "isn't working"? Does it not compile? If so, what is the error message? If not, does it behave different than you expected? How is it different?Inhesion
@Inhesion I have stated above that it compiles perfectly fine, and that the third example’s output doesn’t match. My output’s 2 although as given in the problem examples it should be 3. I’m looking for someone to help me find the mistake in my code.Nutt
@Nutt put the relevant information in the question.Inhesion
@Nutt I have been told that before, but this is the way we're taught in class -- Then you are not being taught C++, plain and simple.Lauranlaurance
@Lauranlaurance I am fully aware. It’s a bit devastating but I can’t do much since it’s a class in my school, not a class I have chosen or paid for.Nutt
1 < N > 200 is visibly false looking at the examples (else N > 200 is enough ), probably is 1 < N < 200Vigorous
Why do you think your output should be 3 instead of 2? I'd love to answer your question, but it appears that i can't quite follow your logic here. Could you clarify that a bit? Aside from that, even though you learned it the wrong way you should probably still use the "right way" of creating an array on runtime.Anthropocentric
@Anthropocentric As stated above and in my question, it is a problem and the example is a part of the problem - so I haven’t made it up or thought it out.Nutt
If you are using GCC or Clang get used to using the options -std=c++17 -Wall -W -pedantic which would have warned you warning: ISO C++ forbids variable length arrayWolfish
@Nutt The problem is easily solved by accumulating the characters in-between the 'C' characters using a stack or stack-like data structure, and after the "terminating C" character is reached, go through the stack and count the number of A and B characters. If not a stack, a temporary substring of the characters between the C's, and just merely count the number of A and B characters in the substring (the substring has to be cleared on each count, but that would be part of the logic). In other words, clear your mind and rethink your approach to the problemLauranlaurance
Guys, please stop complaining about the fact that the code isn't standard C++. He never implied it was, and he keeps repeating that he is aware it isn't. The code works fine with the compiler and options he is using, and, as per the answers he got, the use of VLAs is clearly not the problem with his code. You don't have to be pedantic when there's no need to do so.Openminded
@CássioRenan The comment section is for comments, so comments are made. The answer section is where answers go. Second, many here who would like to help will require a minimal reproducible example, so that we can take the code, compile it, and see the results ourselves. If the code is full of non-standard C++, and the persons willing to help use, say, the most used compiler in the world, Visual Studio, we are now at a disadvantage since VS adheres to ANSI compliance w.r.t VLA's. That's why it is pointed out that the code is not valid C++, and to possibly change the code to use std::vector or equivalent.Lauranlaurance
@Lauranlaurance the code is still verifiable, only not in VS. Acording to your argument, Java developers are at a "disadvantage", too, since a Java compiler also can't compile the example. There are plenty of online compilers available that can compile this just fine. If you feel you can't help because you can't use your favorite compiler, you can just move on to another question. There are other users willing to help, as the number of answers on this question proves. What bothers me most is that he gave a very reasonable reason to use non-standard C++, but you keep insisting on this non-issue.Openminded
C++ is not Java. Stop introducing that strawman. The tag on the question is C++. If you feel you can't help because you can't use your favorite compiler, you can just move on to another question -- No. If the question just requires one or two changes to make it viable for all compilers, why not mention it? Also, many times I've had to change a questioner's code so that vector is used instead of VLA's, and guess what? The problem becomes revealed by making that simple change.Lauranlaurance
@Lauranlaurance one thing is to mention it, another is to keep harassing the OP even after he explained his reasons. I seriously doubt you can "reveal the problem" by changing a VLA to a vector: This change, by itself, doesn't really alter the semantic value of the program. About his class: The teacher/professor probably considered his options and VLAs are much simpler to grasp than vectors, at least for complete beginners. The goal of a programming class is to teach programming, not to teach C++. Anyway, this is going nowhere. Feel free to answer this, but I'm not going to comment here again.Openminded
S
2

You have several problems, as outlined in the code comments below:

int N;
cin >> N;
std::vector<char> Ar(N);

for (int i = 0; i < N; i++) {
    cin >> Ar[i];
}

int piece = 0;
int attempt = 0;

for (int i = 0;  i < N - 1; i++) {
    if (Ar[i] != 'C') {
        // Skip letters until the first C
        continue;
    }
    int A = 0;
    int B = 0;
    int j = i + 1;
    for (; j < N; j++) {
        if (Ar[j] == 'A') {
            A++;
        } else if (Ar[j] == 'B') {
            B++;
        } else if (Ar[j] == 'C') {
            // We only account for blocks between Cs
            attempt++;
            if (A > B) {
                piece++;
            }
            break;
        }
    }
    // Next piece starts at j, i will be incremented by outer loop
    i = j - 1;
}
Snowdrift answered 2/3, 2019 at 19:27 Comment(0)
B
3

The problem is in the case

        } else if (Ar[j] == 'C') {
            i = j;
            break;
        }

the reason is that once you get back to the main loop i will be incremented, so the ending C will not be considered to be the start of a new group. Your code is basically checking every other block.

You should set

i = j-1;

instead, so that after incrementing i will be the index of the C.

Also you should re-initialize A and B to zero when evaluating a section.

Beget answered 2/3, 2019 at 18:54 Comment(4)
I tried, the program doesn’t work at all when I do that. I break out of the loop, I’m not sure if i++ works even if you break before the loop has finished.Nutt
break exits the inner loop, not the outer one.Beget
@N.T.: there's also another error, you only set A and B to zero once, it should be done instead inside the outer loop, before processing a section.Beget
I need it to break out of the second loop because it’s that loop which checks the elements, and I set the A and B to zero because I don’t need them I just need them for a comparason to know whether or not to add a successful piece to the code or just a useless attempt.Nutt
S
2

You have several problems, as outlined in the code comments below:

int N;
cin >> N;
std::vector<char> Ar(N);

for (int i = 0; i < N; i++) {
    cin >> Ar[i];
}

int piece = 0;
int attempt = 0;

for (int i = 0;  i < N - 1; i++) {
    if (Ar[i] != 'C') {
        // Skip letters until the first C
        continue;
    }
    int A = 0;
    int B = 0;
    int j = i + 1;
    for (; j < N; j++) {
        if (Ar[j] == 'A') {
            A++;
        } else if (Ar[j] == 'B') {
            B++;
        } else if (Ar[j] == 'C') {
            // We only account for blocks between Cs
            attempt++;
            if (A > B) {
                piece++;
            }
            break;
        }
    }
    // Next piece starts at j, i will be incremented by outer loop
    i = j - 1;
}
Snowdrift answered 2/3, 2019 at 19:27 Comment(0)
K
1
#include <iostream>

using namespace std;

int main() {
  int numChars;
  cin >> numChars;

  char array[numChars];

  for (int i = 0; i < numChars; ++i) {
    cin >> array[i];
  }

  int numBrokenPieces = 0;
  int numAs = 0;
  int numBs = 0;

  bool inPiece = false;
  for (int i = 0; i < numChars; ++i) {
    if (array[i] == 'C') {
      if (!inPiece) {
        inPiece = true;
        continue;
      } else {
        if (numBs >= numAs) {
          ++numBrokenPieces;
        }
        numAs = 0;
        numBs = 0;
      }
    } else {
      if (inPiece) {
        if (array[i] == 'A') {
          ++numAs;
        } else if (array[i] == 'B') {
          ++numBs;
        }
      }
    }
  }

  if (numBrokenPieces == 0) {
    cout << "RIGHT";
  } else {
    cout << numBrokenPieces;
  }

  return 0;
}
Kershner answered 2/3, 2019 at 19:54 Comment(0)
A
1

Well, you could also approach this a bit differently:

string str;
bool counting = false;
int counter = 0, notRightCounter = 0;

cout << "String: ";
cin >> str;                                  // user enters whole string at once 

for (char& c : str) {                        // for each char in string
    if (c == 'C') {                          // start or stop counting when C is found
        counting = !counting;
        if (!counting && counter <= 0) {     // Check if piece between Cs is right
            notRightCounter++;
            counting = !counting;
        }
        counter = 0;
        continue;                            // Continue to next char after 'C'
    }

    if (counting)                            // Keeping count of A's and B's
        switch (c) {
            case 'A':
            counter++;
            break;
        case 'B':
            counter--;
            break;
        }
}

// Print results
if (notRightCounter != 0)                   
    cout << "Not right! " << "Not right counter: " << notRightCounter;
else
    cout << "Right!";
Actinouranium answered 2/3, 2019 at 20:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.