GateKiller, как насчет того, чтобы добавить break
к тому if
в foreach
цикл? Это ускорило бы вещи много , потому что, если как 6 является делимым 2, Вы не должны сверяться 3 и 5. (Я проголосовал бы за Ваше решение так или иначе, если бы у меня было достаточно репутации:-)...)
ArrayList primeNumbers = new ArrayList();
for(int i = 2; primeNumbers.Count < 10000; i++) {
bool divisible = false;
foreach(int number in primeNumbers) {
if(i % number == 0) {
divisible = true;
break;
}
}
if(divisible == false) {
primeNumbers.Add(i);
Console.Write(i + " ");
}
}
Мульти-диспетчеризация - это возможность выбирать, какую версию функции вызывать, в зависимости от типа времени выполнения аргументов, переданных в вызов функции.
Вот пример, который не работает прямо в C ++ (непроверено):
class A { };
class B : public A { };
class C : public A { }
class Foo
{
virtual void MyFn(A* arg1, A* arg2) { printf("A,A\n"); }
virtual void MyFn(B* arg1, B* arg2) { printf("B,B\n"); }
virtual void MyFn(C* arg1, B* arg2) { printf("C,B\n"); }
virtual void MyFn(B* arg1, C* arg2) { printf("B,C\n"); }
virtual void MyFn(C* arg1, C* arg2) { printf("C,C\n"); }
};
void CallMyFn(A* arg1, A* arg2)
{
// ideally, with multi-dispatch, at this point the correct MyFn()
// would be called, based on the RUNTIME type of arg1 and arg2
pFoo->MyFn(arg1, arg2);
}
...
A* arg1 = new B();
A* arg2 = new C();
// Using multi-dispatch this would print "B,C"... but because C++ only
// uses single-dispatch it will print out "A,A"
CallMyFn(arg1, arg2);
Множественная отправка - это когда выполняемая функция зависит от типа времени выполнения более чем одного объекта.
В C ++ есть одиночная отправка, потому что когда вы используете виртуальные функции, фактическая функция, которая запускается, зависит только от типа времени выполнения объекта слева от -> или. оператор.
Я изо всех сил пытаюсь придумать реальный случай программирования для множественной отправки. Может быть, в игре, где разные персонажи сражаются друг с другом.
void Fight(Opponent& opponent1, Opponent& opponent2);
Победитель боя может зависеть от характеристик обоих противников, поэтому вы можете захотеть, чтобы этот вызов отправлялся одному из следующих, в зависимости от типов времени выполнения обоих аргументов:
void Fight(Elephant& elephant, Mouse& mouse)
{
mouse.Scare(elephant);
}
void Fight(Ninja& ninja, Mouse& mouse)
{
ninja.KarateChop(mouse);
}
void Fight(Cat& cat, Mouse& mouse)
{
cat.Catch(mouse);
}
void Fight(Ninja& ninja, Elephant& elephant)
{
elephant.Trample(ninja);
}
// Etc.
То, что делает функция, зависит от типов обоих аргументов, а не только одного. В C ++ вам, возможно, придется написать это как некоторые виртуальные функции. Виртуальная функция будет выбрана в зависимости от одного аргумента (указателя this). Затем виртуальной функции может потребоваться включить переключатель или что-то особенное для другого аргумента.
См. Этот документ, написанный Б. Страуструпом: Открытые мульти-методы для C ++
В одиночной отправке выполняемая функция зависит только от типа объекта. В двойная отправка выполняемая функция зависит от типа объекта и параметр.
В следующем примере функция Area ()
вызывается с использованием
одинарная отправка, а Intersect ()
полагается на двойную отправку, потому что для этого требуется
Параметр формы.
class Circle;
class Rectangle;
class Shape
{
virtual double Area() = 0; // Single dispatch
// ...
virtual double Intersect(const Shape& s) = 0; // double dispatch, take a Shape argument
virtual double Intersect(const Circle& s) = 0;
virtual double Intersect(const Rectangle& s) = 0;
};
struct Circle : public Shape
{
virtual double Area() { return /* pi*r*r */; }
virtual double Intersect(const Shape& s);
{ return s.Intersect(*this) ; }
virtual double Intersect(const Circle& s);
{ /*circle-circle*/ }
virtual double Intersect(const Rectangle& s);
{ /*circle-rectangle*/ }
};
Пример основан на этой статье .