Хотя я попытался обобщить вопрос в заголовке, я думаю, что будет лучше, если я начну с примера проблемы:
Список простых чисел = {2 3 5 7 11 13}
Шаблон факторизации = {1 1 2 1}
Для вышеуказанного ввода программа должна генерировать следующий список чисел:
- 2.3.5 ^ 2.7
- 2.3.5 ^ 2,11
- 2.3.5 ^ 2,13
- 2.3.7 ^ 2,11
- 2.3.7 ^ 2,13
- 2.3.11 ^ 2,13
- 2.5.7 ^ 2,11
- 2.5.7 ^ 2,13
- 2.7.11 ^ 2,13
- 3.5.7 ^ 2,11
- 3.5.7 ^ 2,13
- 3.5.11 ^ 2,13
- 3.7.11 ^ 2,13
- 5.7.11 ^ 2,13
Пока я понимаю, что, поскольку длина шаблона произвольно велика (как и список простых чисел), мне нужно использовать рекурсивную функцию для получения всех комбинаций. Я действительно застрял в том, как сформулировать аргументы функции / когда вызывать и т.д. Это то, что я разработал до сих пор:
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
static const int factors[] = {2, 3, 5, 7, 11, 13};
vector<int> vFactors(factors, factors + sizeof(factors) / sizeof(factors[0]));
static const int powers[] = {1, 1, 2, 1};
vector<int> vPowers(powers, powers + sizeof(powers) / sizeof(powers[0]));
// currPIdx [in] Denotes the index of Power array from which to start generating numbers
// currFidx [in] Denotes the index of Factor array from which to start generating numbers
vector<int> getNumList(vector<int>& vPowers, vector<int>& vFactors, int currPIdx, int currFIdx)
{
vector<int> vResult;
if (currPIdx != vPowers.size() - 1)
{
for (int i = currPIdx + 1; i < vPowers.size(); ++i)
{
vector<int> vTempResult = getNumList(vPowers, vFactors, i, currFIdx + i);
vResult.insert(vResult.end(), vTempResult.begin(), vTempResult.end());
}
int multFactor = pow((float) vFactors[currFIdx], vPowers[currPIdx]);
for (int i = 0; i < vResult.size(); ++i)
vResult[i] *= multFactor;
}
else
{ // Terminating the recursive call
for (int i = currFIdx; i < vFactors.size(); ++i)
{
int element = pow((float) vFactors[i], vPowers[currPIdx]);
vResult.push_back(element);
}
}
return vResult;
}
int main()
{
vector<int> vNumList = getNumList(vPowers, vFactors, 0, 0);
cout << "List of numbers: " << endl;
for (int i = 0; i < vNumList.size(); ++i)
cout << vNumList[i] << endl;
}
Когда я запускаю вышеупомянутое, я получаю неправильный список:
List of numbers:
66
78
650
14
22
26
Я как-то натолкнулся на ментальный блок, так как не могу понять, как правильно изменить последний параметр в рекурсивном вызове (что, по-моему, и является причиной того, что моя программа не работает) !!
Было бы здорово, если бы кто-то был достаточно хорош, чтобы настроить мой код с отсутствующей логикой (или даже указать мне на это - я не ищу полное решение!). Буду очень признателен, если вы ограничите свой ответ стандартным C ++!
(В случае, если кто-то заметит, что я пропускаю перестановки данного шаблона, что может привести к другим числам, таким как 2.3.5.7 ^ 2 и т. Д. - не волнуйтесь, я намерен повторить этот алгоритм на всех возможных перестановках данного шаблона с помощью next_permutate!).
PS: не проблема домашней работы / собеседования, а лишь часть алгоритма для очень интересной задачи Project Euler (думаю, вы даже можете догадаться, какая именно:)).
РЕДАКТИРОВАТЬ: Я решил проблему самостоятельно - который я отправил в качестве ответа. Если вам это нравится, проголосуйте против (я не могу принять его как ответ, пока он не наберет больше голосов, чем другой ответ!) ...