【问题标题】:If statement failing to activate如果语句未能激活
【发布时间】:2017-02-02 14:55:25
【问题描述】:

我正在尝试创建一个应该执行以下操作的函数:

- 取两个字符数组,一个比另一个小,并确定较小的字符数组是否是较大数组的子集。举个例子: 数组 A:{"s","c","h","o","o","l"};数组 B:{"c","h"}。我有义务使用指针递增/递减操作。这是我生成的代码:

int locator(char *Bigptr, char *Smallptr) {
int count = 0;
    for (; *Bigptr != '\0'; Bigptr++) {
        if (*Smallptr == *Bigptr) {
            for (; (*Smallptr == *Bigptr) != '\0'; Smallptr++, Bigptr++) {}
            if (*Smallptr == '\0') {
                return count;
            }
            else {
                cout << "small is not the subset of big" << endl;
                return 0;
            }
        }
        count++;
    }
return 0; 

这就是我认为代码应该运行的方式:

将两个指向字符数组的指针作为函数'locator'的参数。变量 count 是我为了告诉我 A 中出现的第一个字符的下标是什么而放置的(例如,“school”和“ch”将是元素 1,因此 A[1])。第一个 for 循环确保较大数组的第一个值是实际字符。 if 语句在找到共同字符时返回 true。然后第二个 for 循环检查是否所有较小的数组都存在于较大的数组中。当我的程序编译时,所有这些都按预期工作。嵌套 if 语句出现问题。实际上,如果较小的数组是较大数组的子集,我希望它是正确的。为什么不是这样?以“school”和“ch”为例。 *Smallptr 最初指向数组 B 的第一个元素(即“ch”),因此是“c”。然后将其与“学校”中的“c”进行比较。然后这两个指针递增,以便它们都指向各自数组中的“h”。同样,它们再次递增,因此*Bigptr 指向“o”,*Smallptr 指向“\0”。不是这样吗?为什么函数总是输出else语句?

【问题讨论】:

  • 您的参数是字符数组的数组,而不是字符数组。您需要提供一个完整的示例。
  • 当我运行它时,它达到了返回计数,其中 count == 1。我可能通过传递正确的数据类型搞砸了。您对 A 和 B 的声明听起来是错误的。

标签: c++ arrays function c++11 char


【解决方案1】:

您对第二个for 循环的理解不正确。

if (*Smallptr == *Bigptr) {
    for (; (*Smallptr == *Bigptr) != '\0'; Smallptr++, Bigptr++) {}

由于您已经确定(在if 条件该语句中)*Smallptr == *Bigptr,因此该比较给出非零 (true) 结果。

测试(*Smallptr == *Bigptr) != '\0' 将该非零结果与值为零的char 进行比较。非零值永远不会与零比较(至少,不与标准整数类型相比,包括bool),因此循环无效。

与您的描述一致的循环是

for (; (*Smallptr == *Bigptr) && *SmallPtr != '\0'; Smallptr++, Bigptr++) {}

检查两个字符是否相等,并且都非零。

【讨论】:

  • 感谢您的回复,我明白您的意思,但我有几个跟进。首先,您提到循环没有效果。那是什么意思?我使用我的原始代码创建了一个虚拟变量,以查看循环是否正常工作并且它确实“循环”。此外,即使在测试了您的建议之后,for 循环后面的 if 语句仍然是错误的。为什么会这样?您建议的改进不应该确保 *Smallptr 确实“指向”“\ 0”。再次感谢您的回复,非常感谢。
  • for 语句的结束条件在达到之前为真。因此,循环体(在您的情况下,什么都不做)和延续语句(在您的情况下,Smallptr++, Bigptr++)都不会被执行。正如我所描述的,如果*SmallPtr != *BigPtr*SmallPtr 为零,则循环将停止。如果这不是您想要的,请修改以适合。
【解决方案2】:

鉴于这是 C++,您可能希望利用标准库中已有的功能。我会按这个顺序做点什么:

bool is_subset(std::string big, std::string small) { 

    std::sort(big.begin(), big.end());
    std::sort(small.begin(), small.end());

    std::string result;
    std::set_difference(small.begin(), small.end(),
                        big.begin(), big.end(),
                        std::back_inserter(result));
    return result.empty();
}

这不满足使用指针的要求,但 IMO 是一种更好的方式来完成这项工作。

【讨论】:

    【解决方案3】:

    行中使用的逻辑

    for (; (*Smallptr == *Bigptr) != '\0'; Smallptr++, Bigptr++) {}
    

    不正确。

    你需要的是:

    for (; (*Smallptr == *Bigptr) && *SmallPtr != '\0'; Smallptr++, Bigptr++)
    {
       ++count;
    }
    

    【讨论】:

      【解决方案4】:

      你做错了一些事情。 看看这个返工:

      int locator(char *Bigptr, char *Smallptr) {
          int count = 0;
          for (; *Bigptr != '\0'; Bigptr++) {
              if (*Smallptr == *Bigptr) {
                  for (; *Smallptr == *Bigptr && *Bigptr!='\0'; Smallptr++, Bigptr++) {
                      count++;
                  }
                  if (*Smallptr == '\0') {
                      return count;
                  }
                  break; //this is necesary in order not to stay in the main for loop
              }
          }
          std::cout << "small is not the subset of big" << std::endl;
      
          return count;
      }
      

      编辑:在主函数中测试代码,它运行良好:

      int main(int argc, const char * argv[]) {
      
          std::cout << locator("hello","ohl"); //this prints "small is not the subset of big"
          std::cout << locator("hello","ell"); //this prints "3" (the count of matching characters)
          return 0;
      }
      

      【讨论】:

      • 嘿何塞,我没有能力投反对票或投赞成票,因为我是新成员,所以不是我。但是,我确实尝试了您的代码,但问题仍然存在。因此,这可能是其他人对您的评论投反对票的原因。
      • 你是对的。我错过了一个“休息”。此外,我认为返回计数总是更有趣。所以用户总能得到匹配字符的数量。现在代码已经过测试,它确实做了它应该做的事情。
      猜你喜欢
      • 2021-06-02
      • 1970-01-01
      • 2018-04-10
      • 2019-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-08
      • 2011-02-24
      相关资源
      最近更新 更多