目前我有两个功能:
它们被编码(在C ++中):
prime_list erato_sieve(ul_it upper_limit)
{
prime_list primes;
if (upper_limit < 2)
return primes;
primes.push_back(2); // Initialize Array, and add 2 since its unique.
for (uit i = 3; i <= upper_limit; i += 2) // Only count odd numbers
{
flag is_prime = true;
for (uit j = 0; j < primes.size(); ++j)
{
if ((i % primes[j]) == 0)
{
is_prime = false;
break;
}
}
if (is_prime)
{
primes.push_back(i);
}
}
return primes;
}
和
prime_list erato_sieve_num(ul_it MAX)
{
prime_list primes;
if (MAX == 0)
return primes;
primes.push_back(2); // Initialize Array, and add 2 since its unique.
uit i = 3;
while (primes.size() < MAX) // Only count odd numbers
{
flag is_prime = true;
for (uit j = 0; j < primes.size(); ++j)
{
if ((i % primes[j]) == 0)
{
is_prime = false;
break;
}
}
if (is_prime)
{
primes.push_back(i);
}
++i;
}
return primes;
}
定义了以下类型:
typedef bool flag;
typedef unsigned int uit;
typedef unsigned long int ul_it;
typedef unsigned long long int ull_it;
typedef long long int ll_it;
typedef long double ld;
typedef std::vector<ull_it> prime_list;
(如果你愿意,可以随意使用它们。发现 - 替换会照顾它。我用它们来使代码更多地读取我的想法)
我试图将这些变成一个重载的“函数”,但它们两个有相似的参数。我担心它们之间的选择将归结为单独输入,这将导致难以调试的问题。
我的第二个选择是创建一个类,但我很尴尬地说..,我以前从未使用过类。完全没有。所以我不知道该怎么做,文档有点......稀疏?
无论如何,如果有人会介意帮助我一点点,我将不胜感激。文档总是有用的,也欢迎任何指针。
正如我所说,我的部分选项是一个类。我完全相信如何组成一个课程来结合这两个。
答案 0 :(得分:1)
永远不要给具有不同语义的函数赋予相同的名称。超载的目的不是为了这个目的。这两个都取整数,如果你可以重载它们,你怎么知道在erato_sieve(5)
调用哪个函数?
给他们不同的名字,例如erato_sieve_up_to
和erato_sieve_count
。
好吧,如果你仍然想让事情变得更糟(请不要),你可以让他们超载(请不要),只是让他们期待不同类型的论点。例如,将一个整数包装到一个类中并传递该类,如
class CountWrapper {
public:
CountWrapper(int n) { n_ = n; }
operator int() { return n_; }
private:
int n_;
};
prime_list erato_sieve(const CountWrapper& MAX) {
// function's body stays the same
并称之为
my_list = erato_sieve(CountWrapper(5));
但又一次:请不要!
要对函数进行分组,可以将它们定义为类的静态方法:
class PrimeGenerator {
public:
static prime_list EratoSieveUpTo(ul_it upper_limit) {
// body
}
static prime_list EratoSieveAmount(ul_it MAX) {
// body
}
};
并调用类似
的函数list1 = PrimeGenerator::EratoSieveUpTo(5);
list2 = PrimeGenerator::EratoSieveAmount(10);
答案 1 :(得分:0)
如果要创建重载函数,则需要为每个函数定义使用不同的参数列表。在实际使用的参数是相同类型的情况下,可以使用以下技巧:
typedef struct {} flag_type_1;
typedef struct {} flag_type_2;
...
typedef struct {} flag_type_n;
prime_list erato_sieve(ul_it boundary, flag_type_1) { ... }
prime_list erato_sieve(ul_it boundary, flag_type_2) { ... }
...
prime_list erato_sieve(ul_it boundary, flag_type_n) { ... }
这个想法是每个类型定义的结构具有不同的类型签名。这为每个函数重载创建了完全不相关的参数列表。此外,由于类型是虚拟持有人,您不关心内容。这就是为什么你只需要在函数定义的参数列表中包含类型。
我从第9频道回来了一段时间。非常巧妙。
答案 2 :(得分:0)
这不是您问题的直接答案,但它有助于回答您的问题。
您似乎正在尝试实施Eratosthenes筛选。该筛子的基本算法如下:
1) Create a list of numbers from 2 to N (N is the maximum value you are looking for)
2) Start at 2, and eliminate all other even numbers (they are non-prime) less than or equal to N
3) Move to the next non-eliminated number.
4) Eliminate all multiples of that number less than or equal to N.
5) Repeat steps 3 and 4 until you reach the square root of N.
将其翻译成C ++代码,它看起来像这样(未优化):
std::vector<unsigned int> sieve_of_eratosthenes(unsigned int maximum)
{
std::vector<unsigned int> results; // this is your result set
std::vector<bool> tests(maximum + 1); // this will be your "number list"
// initialize the tests vector
for (unsigned int i = 0; i <= maximum; ++i)
{
if (i == 0 || i == 1)
tests[i] = false;
else
tests[i] = true;
}
// eliminate all even numbers but 2
for (unsigned int i = 4; i <= maximum; i += 2)
{
tests[i] = false;
}
// start with 3 and go to root of maximum
unsigned int i = 3;
while (i * i <= maximum)
{
for (unsigned int j = i + i; j <= maximum; j += i)
{
tests[j] = false;
}
// find the next non-eliminated value
unsigned int k = i + 1;
while (!tests[k])
{
k++;
}
i = k;
}
// create your results list
for (unsigned int j = 0; j <= maximum; ++j)
{
if (tests[j])
{
results.push_back(j);
}
}
return results;
}
由于筛网需要最大值,因此您不希望为此算法提供许多素数。还有其他主要生成算法可以做到这一点,但是Eratosthenes的Sieve没有。