首页 > 解决方案 > 无法更新c ++类中方法的for循环内的成员变量

问题描述

我正在尝试使用 c++ 类创建一个类似 python 的生成器,它将提供一个数字的除数。这是课程:

using ull = unsigned long long int;
class Divisors {
  public:
  ull x;
  vector<ull> divs;
  ull i;
  bool end;
  Divisors(const ull &x) : x(x), i(2), end(false) {
  }
  ull next() {
    for(; i*i<=x;i++) {
      if(x%i == 0) {
        divs.emplace_back(i);
        if(!((i+1)*(i+1)<x+1))
          end = true;
        return i;
      }
    }
    return 0;
  }
};

主要功能在这里:

int main() {
  Divisors divs(10);
  int cnt = 0; // Just for safety if while loop goes infinite
  while(!divs.end && cnt < 100) {
    auto div = divs.next();
    cout << div << endl;
    cnt++;
  }
  return 0;
}

但问题是,它总是打印 2。这意味着值i在 for 循环中没有更新。同样,由于i不增加,while 无限并停止cnt

标签: c++loops

解决方案


在您的帖子中,您正在撰写有关除数的文章。我担心你的意思是(主要)因素。这是因为您从 2 开始并尝试直到分子的平方根。

但是,除数不同。10 的除数是:1、2、5、10,其中 1 和 10 是平凡除数。

您的编程风格看起来像“竞争性编程”风格。我希望不是这样,因为你永远不会在这些挑战中学习 C++ 编码。

在你的for-loop 中,你总是return ii++for会发生之前。它将恰好运行一次,值为 2。然后返回。下次一样。等等等等。

您还有其他逻辑错误。你应该重构你的代码。

你可以看看下面的例子,了解如何实现这样的事情。请注意,此代码将永远无法用于任何竞争性挑战。它应该只是给你一些提示。. .

#include <iostream>
#include <vector>

// Whatever integral data type
using MyType = unsigned long long int;

// CLass for calculartin divisors incrementally
struct Divisors {

    // Here we store the originally given numerator
    MyType numerator{};

    // Persistent copy of the test value
    MyType testValue{ 1 };

    // And here we will stor all divisors
    std::vector<MyType> allDivisors{};

    // Constructor. Set all values to start
    Divisors(MyType number) : numerator(number), testValue(1), allDivisors{} {}

    // And a similar function to reset the class, in case we want to use it for an additional computation
    void reset(MyType number) { numerator = number; testValue = 1; allDivisors.clear(); }

    // Function, that will get the next divisor
    MyType nextDivisor() {

        // Here we will stor the result of the function. If we cannot 
        // find a result any longer, then0 ist returned
        MyType result{};

        // We run the loop until we have have found some divisor
        bool found{ false };

        // Or until we are at the end
        while (!found && testValue <= numerator) {

            // Check if this value is a divisor
            if ((numerator % testValue) == 0) {

                // Yes, it is a divisor. Set flag to terminate the loop
                found = true;

                // Set the return value, so, the devisor
                result = testValue;

                // And store the divisor in our vector for later use
                allDivisors.push_back(testValue);
            }
            // Continue with next test value
            ++testValue;
        }
        // A valid divisor or 0, if no new divisors can be found
        return result;  
    }
};

// Some test code
int main() {

    // We want to incrementally create divisors
    Divisors divisors(100ULL);

    // Call the next function for the divisor, until everything is found
    for (MyType d = divisors.nextDivisor(); d; d = divisors.nextDivisor())

        std::cout << d << '\n'; // Show one divisor in each loop run

    return 0;
}

推荐阅读