Невозможно обновить переменную-член внутри для l oop метода в классе c ++ - PullRequest
0 голосов
/ 19 апреля 2020

Я пытаюсь создать python подобный генератор с классом c ++, который будет предоставлять делители числа. Вот класс:

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 не обновляется в течение l oop. Также, поскольку i не увеличивается, время становится бесконечным и останавливается на cnt.

1 Ответ

0 голосов
/ 19 апреля 2020

В своем посте вы пишете о делителе с. Я боюсь, что вы имеете в виду (основные) факторы. Это потому, что вы начинаете с 2 и пытаетесь go до квадрата root числителя.

Но делители разные. Делителями для 10 являются: 1, 2, 5, 10, где 1 и 10 - тривиальный делитель.

Ваш стиль программирования выглядит как "соревновательное программирование" - стиль. Я надеюсь, что это не так, потому что вы никогда не научитесь кодированию на C ++ в этих задачах.

В вашем for -l oop вы всегда return i до i++ из 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...