检查一个数组是否“正确”(C++)

5

一个正确的数组

假设我们有一个由大写字母A、B和C组成长度为N的数组。如果在数组中连续出现的两个C之间,A的数量大于B的数量,则称该数组为“正确的数组”。我的任务是发现给定的数组是否“正确”,如果是,我应该输出“RIGHT”,否则我应该打印出不符合条件(B的数量多于A的数量)的片段数(C之间的位置数)。

输入:第一行输入数组中字母的数量N(1 < N > 200)。在下一行输入数组,无空格。

输出:以单行形式输出答案。

例子:

  • 输入:16 ABBCAABCACBAAACB 输出:RIGHT

  • 输入:15 ABBCABCACBAAACB 输出:1

  • 输入:14 CABCABBCBAABBC 输出:3

现在,我已经尝试解决这个问题,但第三个例子对我来说没有起作用-我得到了一个输出为2,而正如上面所指示的,我应该得到3,除此之外-它可以完美地编译。

    #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;
}

4
char Ar[N]; 不是有效的 C++ 代码。 - user2100815
1
对于 _14 CABCABBCBAABBC_,输出为 2,而不是 3。 - bruno
1
“@N.T.‘对我不起作用’”不是一个有用的问题描述。你所说的“不起作用”是什么意思?它不能编译吗?如果是这样,那么错误信息是什么?如果不是,它的行为是否与您预期的不同?它有什么不同之处? - eerorika
1
各位,请停止抱怨代码不是标准的C++。他从未暗示过它是,而且他一直在重复他知道它不是。代码在他使用的编译器和选项下运行良好,并且根据他得到的答案,使用可变长度数组显然不是他代码的问题所在。当没有必要这样做时,您不必过于追求细节。 - Cássio Renan
1
@PaulMcKenzie,提及问题是一回事,但即便OP已经解释了他的原因,还继续骚扰他就另外一回事了。我真的怀疑你可以通过将VLA改为向量来“揭示问题”:这个更改本身并没有真正改变程序的语义值。关于他的课程:老师/教授可能考虑了他的选择,对于完全的初学者,VLAs比向量更容易理解。编程课的目标是教编程,而不是教C ++。无论如何,这样下去没有任何意义。欢迎回答此问题,但我不会在此发表评论了。 - Cássio Renan
显示剩余16条评论
4个回答

3
问题出现在这种情况下。
        } else if (Ar[j] == 'C') {
            i = j;
            break;
        }

原因是,一旦回到主循环,i 将会被增加,所以结尾的 C 不会被视为新组的开始。你的代码实际上只检查了每隔一个块。
你应该设置
i = j-1;

相反,这样在增加 i 后将会成为 C 的索引。

另外,在评估一个区域时应将 AB 重新初始化为零。


我尝试过,当我这样做时程序根本不起作用。我退出循环,我不确定如果在循环结束之前中断,i++是否仍然有效。 - N.T.
break 会退出内部循环,而不是外部循环。 - 6502
@N.T.: 还有另一个错误,你只在一开始将 AB 设为零了一次,实际上应该在外层循环内,在处理一个部分之前进行清零。 - 6502
我需要它跳出第二个循环,因为正是那个循环检查元素,而我将A和B设置为零,因为我不需要它们,我只需要它们用于比较,以知道是否将成功的代码片段添加到代码中,还是只是一个无用的尝试。 - N.T.

2

您有几个问题,如下面代码注释所述:

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;
}

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;
}

1

好的,你也可以稍微有所不同地处理这个问题:

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!";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接