【问题标题】:Comparing two array values in C比较C中的两个数组值
【发布时间】:2019-03-22 17:17:27
【问题描述】:

我正在用 C 为学校项目编写一个程序,它比较两个数组的值并根据用户的输入给出具体的结果。基本上我的输出值为两个,correctPositioncorrectValue

correctValue 是在 valuesArray 中但不在 inputArray 中正确位置的值,例如;值“4”位于 valuesArray 的索引 1,但位于 inputArray 的索引 2。

correctPositionvaluesArrayinputArray 中相同索引处的值。例如;值“3”位于 valuesArrayinputArray

的索引 1

如果两个数组之间的 x 值匹配,则它可以是正确的值或正确的位置。这是一个视觉表示:

valuesArray: 2 3 3
------------------
inputArray:  1 2 3
Answer: correctPosition = 1, correctValue = 1.

inputArray:  2 1 3
Answer: correctPosition = 2, correctValue = 0.

inputArray:  2 3 3
Answer: correctPosition = 3, correctValue = 0.

这是我为此编写的代码:

#include <stdio.h>

int main() {

  int inputArray[3], valuesArray[3];
  int correctNumber = 0, positionMatch = 0;
  int x, y;
  int visitedMatch[3];

  valuesArray[0] = 2;
  valuesArray[1] = 3;
  valuesArray[2] = 3;
  inputArray[0] = 1;
  inputArray[1] = 2;
  inputArray[2] = 3;

  for( x = 0; x < 3; x++) {
    visitedMatch[x] = 0;
  }

  for(x = 0; x < 3; x++) {
    for(y = 0; y < 3; y++) {
      if (inputArray[x] == valuesArray[y] && visitedMatch[y] == 0) {
        if (x == y) { positionMatch++; } else { correctNumber++; }
        visitedMatch[y] = 1;
        break;
      }
    }
  }

  printf("correctPosition = %d, ", positionMatch);
  printf("correctValues = %d\n", correctNumber);
  return 0;
}

问题在于,对于输入 1 2 3,它首先取 1 并检查 valuesArray 并找不到任何东西,因此结果保持为 0。然后在 x = 1 的第二次迭代中,它取 2 并检查它是否在数组但不在正确的索引处,因此正确值计数器变为 1。现在在 x = 2 的最终迭代中,它需要 3 并通过循环并在索引 2 处找到第一个值“3”,因为它之前从未被访问过,所以最终结果变为正确位置 = 0,正确值 = 2。如果我将输入写为 2 3 3,那么它工作正常,输出正确位置 = 3,正确值 = 0。我该如何解决这个问题,我错过了什么在这里?

任何帮助将不胜感激。

【问题讨论】:

  • 你能试着澄清一下这里的实际任务吗?也许只有我一个人,但我很难弄清楚
  • 我建议您以不同的方式处理问题。首先扫描两个数组以找到精确匹配(即positionMatch)。然后使用基于直方图的方法计算valueMatch 的初步版本:计算valuesArray 中每个符号的数量以及inputArray 中每个符号的数量,并计算所有符号的总和这两个值的最小值。然后,从初步的valueMatch 中减去positionMatch,以消除否则会出现的重复计算。
  • 我建议先检查它是否是正确的位置,然后再寻找其他不太具体的情况。使用“短路”逻辑。
  • @TormundGiantsbane 这是一款名为 Master Mind 的棋盘游戏,我们需要使用树莓派来制作它。因此生成了一个秘密值数组(valuesArray),用户必须使用物理按钮输入猜测正确的序列。
  • 那么我现在尝试的方式是不是不可能?

标签: c search logic


【解决方案1】:

正如我在 cmets 中所写,我建议采用不同的方法。你的算法有点混乱,因为从逻辑上讲,positionMatch 贡献者的评估涉及将每个输入值与一个对应的其他位置进行比较,而valueMatch 贡献者的评估涉及将每个输入值与整个板进行比较。

如果分开,它们会更干净。如果您不得不担心处理非常大的电路板,那么将这两个步骤分开可以产生一种解决方案,其成本与电路板的尺寸成线性关系,而不是二次方。具体来说,我建议的方法是

  1. 扫描两个数组以计算 positionMatch 计数并为每个数组构建每个符号出现次数的直方图。

  2. 扫描两个直方图,计算每个符号在两个直方图中该符号计数的最小值的总和。这会产生正确数字的总数,但不会区分正确位置的数字和错误位置的数字。

  3. 从 (2) 中计算的总和中减去 (1) 中计算的 positionMatch,得到 correctNumber

不过,话虽如此,您应该能够调整当前代码以计算正确的结果。缺少的主要内容是避免使用应该提供positionMatchvaluesArray 元素来代替提供correctNumber。但这是您可以测试的情况。当您检测到匹配项 (inputArray[x] == valuesArray[y] &amp;&amp; visitedMatch[y] == 0) 时,您目前会执行仅有的两个备选方案之一,具体取决于 x == y 是否。要正确计算计数,您应该使用三个:

  • 如果x == y 则递增positionMatch 并从内部循环中断。 (您也可以标记访问过的位置,但您不需要这样做。)
  • 否则,如果inputArray[y] == valueArray[y] 然后什么也不做valueArray 的那个元素对positionMatch 有贡献,所以它不应该对correctNumber 有贡献。继续下一个内循环迭代。
  • 否则递增correctNumber,标记位置y已访问,并从内部循环中断

或者,您可以调整当前的方法来模拟我建议的方法,而无需实际构建物理直方图。需要进行这些更改:

  • 在外循环中,判断是否增加positionMatch。继续往内循环。
  • 在内循环中,忽略是否x == y,而是增加correctNumber,并在找到匹配项时标记访问的位置。这是计算和评估直方图的替代品。
  • 最后,在报告结果之前从correctNumber 中减去positionMatch

【讨论】:

  • 我将尝试根据您的建议修复我当前的方法,以了解我做错了什么,然后实施更有意义的第一个建议。感谢您的帮助!
  • 当我发表我的答案时,您的答案已经被接受,我不认为 OP 会改变主意,为了公平起见,我赞成您的答案 ;-)
【解决方案2】:

另一种解决方案,比 John Bollinger 算法简单一点:

  • 计算精确匹配并在两个数组中指出要忘记的这些位置

  • 对于来自 inputArray 的每个非遗忘位置,搜索 valuesArray

    的非遗忘位置中的值
    • 如果发现第一次增加correctNumber,并在valuesArray中指出这个位置被遗忘
    • 如果找到但不是第一次,只需在 valuesArray 中指明该位置即可忘记

实现可以是(因为我现在很懒,我通过预处理器标识符I给_inputArray的值,参见编译)

#include <stdio.h>

#define SZ 3

int main() {
  int valuesArray[SZ] = { 2,3,3 };
  int inputArray[SZ] = { I };
  int correctNumber = 0, positionMatch = 0;
  int x, y;
  int forgetValues[SZ] = { 0 }; /* useless to give more value because want 0 for the others */
  int forgetInput[SZ] = { 0 }; /* useless to give more value because want 0 for the others */

  /* count the exact matches */
  for (x = 0; x < SZ; x += 1) {
    if (inputArray[x] == valuesArray[x]) {
      positionMatch += 1;
      printf("correct match %d index %d\n", inputArray[x], x);
      forgetValues[x] = forgetInput[x] = 1; /* do not consider that position later */
    }
  }

  /* count correct values */
  for (x = 0; x < SZ; x += 1) {
    if (!forgetInput[x]) {
      int v = inputArray[x];
      int found = 0;

      for(y = 0; y < SZ; y += 1) {
        if (!forgetValues[y] && (valuesArray[y] == v)) {
          if (!found) {
            /* first time, count it */
            correctNumber += 1;
            found = 1;
            printf("correct value %d index %d / %d\n", v, x, y);
          }
          forgetValues[y] = 1; /* do not consider it later */
        }
      }
    }
  }

  printf("correctPosition = %d, ", positionMatch);
  printf("correctValues = %d\n", correctNumber);
  return 0;
}

编译和执行;

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall -DI=1,2,3 c.c
pi@raspberrypi:/tmp $ ./a.out
correct match 3 index 2
correct value 2 index 1 / 0
correctPosition = 1, correctValues = 1
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall -DI=2,1,3 c.c
pi@raspberrypi:/tmp $ ./a.out
correct match 2 index 0
correct match 3 index 2
correctPosition = 2, correctValues = 0
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall -DI=2,3,3 c.c
pi@raspberrypi:/tmp $ ./a.out
correct match 2 index 0
correct match 3 index 1
correct match 3 index 2
correctPosition = 3, correctValues = 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多