Вы также можете использовать collections.deque()
для создания циклической очереди FIFO:
from collections import deque
L1 = ['A', 'B', 'C', 'D', 'E']
L2 = deque(['1', '2', '3'])
result = {}
for letter in L1:
number = L2.popleft()
result[letter] = number
L2.append(number)
print(result)
# {'A': '1', 'B': '2', 'C': '3', 'D': '1', 'E': '2'}
, которая выталкивает самый левый элемент в настоящее время в L2
и добавляет его в конец как только число добавляется в словарь.
Примечание: Оба collections.deque.popleft()
и collections.deque.append()
являются операциями O (1), поэтому выше все равно O (N) , так как вам нужно пройти все элементы в L1
.
Что-то вроде этого будет работать:
struct complex { double r,i; }
struct pair<T> { T p1, p2; }
pair<complex> GetResults(double a, double b, double c)
{
pair<complex> result={0};
if(a<0.000001) // ==0
{
if(b>0.000001) // !=0
result.p1.r=result.p2.r=-c/b;
else
if(c>0.00001) throw exception("no solutions");
return result;
}
double delta=b*b-4*a*c;
if(delta>=0)
{
result.p1.r=(-b-sqrt(delta))/2/a;
result.p2.r=(-b+sqrt(delta))/2/a;
}
else
{
result.p1.r=result.p2.r=-b/2/a;
result.p1.i=sqrt(-delta)/2/a;
result.p2.i=-sqrt(-delta)/2/a;
}
return result;
}
Таким образом, вы получите результаты одинаково как для реальных, так и для сложных результатов (в реальных результатах просто мнимая часть установлена на 0). Было бы еще красивее с бустом!
edit: исправлено дельта и добавлена проверка на вырожденные случаи, такие как a = 0. Бессонная ночь ftl!
Более или менее он у вас есть, просто проверьте, является ли часть, находящаяся внутри квадратного корня, отрицательной, а затем отслеживайте это отдельно в своих сокращениях.
Вы могли бы просто использовать std :: complex
вместо float
, чтобы получить поддержку комплексных чисел.
Отказ от идеи от Blindy:
typedef std::complex<double> complex;
using std::pair;
pair<complex> GetResults(double a, double b, double c)
{
double delta=(b*b-4*a*c);
double inv_2a = 1/2/a;
if(delta >= 0) {
double root = sqrt(delta);
return std::make_pair(
complex((-b-root)*inv_2a),
complex((-b+root)*inv_2a);
} else {
double root = sqrt(-delta);
return std::make_pair(
complex(-b*inv_2a, -root*inv_2a)),
complex(-b*inv_2a, +root*inv_2a)));
}
}
Важное примечание ко всему этому. Решения, показанные в этих ответах и в исходном вопросе, не являются надежными.
Хорошо известное решение (- b + - sqrt (b ^ 2 - 4ac)) / 2a , как известно, не является надежным. надежный в вычислениях, когда ac очень мало, по сравнению с b ^ 2 , потому что вы вычитаете два очень похожих значения. Лучше использовать менее известное решение 2c / (-b - + sqrt (b ^ 2 -4ac)) для другого корня.
Устойчивое решение можно рассчитать как:
temp = -0.5 * (b + sign(b) * sqrt(b*b - 4*a*c);
x1 = temp / a;
x2 = c / temp;
Использование знака (b) гарантирует, что мы не вычитаем два одинаковых значения.
Для OP,