【问题标题】:Comparing characters in strings using pointers to arrays使用指向数组的指针比较字符串中的字符
【发布时间】:2020-08-17 13:42:55
【问题描述】:

我正在完成一项任务以完成bool isEven(char* s, char* v) 的功能。该函数的目的是计算字符串(由s 表示)中指定的某些字母(由v 表示)的出现次数。 sv 是指向包含字符的数组的指针。

如果在s 中找到来自v 的字母的实例数是偶数,则该函数返回true。例如,给定字符串"once upon a time"和要计算的字母字符串,如元音"aeiou",它会返回false,因为有7个元音(元音只是一个例子,它可以是任何随机字符串字母)。

我有一个变量count 来计算v 中的任何字母出现在s 中的实例。当我运行我的程序时,我的计数总是返回为0。我究竟做错了什么?谁能告诉我如何更正我的代码来解决这个问题?

我也尝试使用嵌套的 while 循环并得到相同的结果。

bool isEven(char* s, char* v) {
    int count = 0;
    // iterate through de-referenced strings
    for (int i = 0; *(s+i) != '\0'; i++) {
        for (int j = 0; *(v+j) != '\0'; j++) {
            if (*(s+i) == *(v+j)) {
                count++;
            }
        }
    }

    // check count output
    std::cout << count;

    if (count % 2 == 0) {
        return true;
    }
    else {
        return false;
    }
}

【问题讨论】:

  • std::cout &lt;&lt; count; -- 因为上面的return 语句,这永远不会被执行
  • 你弄错了赋值运算符 = 和比较运算符 == -- 应该用 ==!= 替换 for 循环中的所有 =
  • for (int i = 0; *(s+i) = '\0'; i++) ...我猜他的意思是:for (int i = 0; *(s + i) != '\0'; i++) - 不等于。
  • @lenik 我会解决这个问题 - 但我正在测试函数而不是 bool(作为 int 类型),只是为了看看我的计数器是否在工作,然后返回计数时我仍然得到 0。
  • @LinuXMan 是的,你是对的 - 我刚刚解决了这个问题,但我的计数仍然返回 0。

标签: c++ arrays string pointers char


【解决方案1】:

下面的代码对我有用,可能对你有一个答案:

#include <iostream>

bool isEven(char[], char[]);

int main(void)
{
    bool flag = isEven("Hello Worldo", "aeiou");

    if (flag)
        std::cout << "Even" << std::endl;
    else
        std::cout << "Not even." << std::endl;
}

bool isEven(char toCheck[], char from[])
{
    int count = 0;

    for (int i = 0; toCheck[i] != '\0'; i++)
    {
        for (int j = 0; from[j] != '\0'; j++)
        {
            if (toCheck[i] == from[j])
            {
                count++;
            }
        }
    }
    std::cout << count << std::endl;

    return (count % 2 == 0) ? true : false;
}

输出

4
Even

字符数组字符串Hello Worldo 将显示4Even,如果在toCheck 中找到from 的元音或任何输入字符,它将计算并确定它是否可以被2整除. 如果不是,则返回 false(非偶数),否则返回 true(偶数)。

【讨论】:

  • 不幸的是,我不允许更改指针中的参数,因为这是教授给出的。但我确实了解您的代码,并了解它是如何完美运行的。感谢您抽出宝贵时间!
【解决方案2】:

这是我的编译器的问题,而不是代码的问题,一旦我在我的 for 循环中修复了 !=,所以这里和上面的代码是正确的。感谢所有花时间提供帮助的人!

bool isEven(char* s, char* v) {
    int count = 0;
    // iterate through de-referenced strings
    for (int i = 0; *(s+i) != '\0'; i++) {
        for (int j = 0; *(v+j) != '\0'; j++) {
            if (*(s+i) == *(v+j)) {
                count++;
            }
        }
    }
    //check count 
    std::cout << count << '\n';

    if (count % 2 == 0) {
        return true;
    }
    else {
        return false;
    }
}

【讨论】:

    【解决方案3】:

    该程序可以正常工作,只需对类型进行一些小的修改以避免出现警告。

    PS:我尝试使用最新的 gcc (9.3),下面是实时示例的链接:https://gcc.godbolt.org/z/WWHecV

    【讨论】:

      【解决方案4】:

      两级循环是O(M*N)解。由于最多只有 256 个可能的字符,所以通常最优化的方法是使用 256 个整数的数组来统计每个字符的出现次数,然后遍历v 中的字符并总结这些字符的出现次数。

      这个方案只需要遍历sv一次,复杂度是O(M+N)。当输入 s 非常大(例如,哈利波特书籍)时,性能差异非常显着。

      bool isEven(char* s, char* v) {
          int counts[256];  // counter for each possible letters.
          for (int i = 0; i < 256; ++i) counts[i] = 0;
          char* p = s;
          while (*p) ++counts[static_cast<uint8_t>(*p++)];  // count occurrence of each letter.
          p = v;
          int count = 0;
          while (*p) count += counts[static_cast<uint8_t>(*p++)];  // accumulate total occurrence
          return (count % 2 == 0);
      }
      

      【讨论】:

        猜你喜欢
        • 2021-10-27
        • 1970-01-01
        • 2021-06-28
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多