c ++ умножение Карацубы с использованием векторов

Итак, я пытался написать алгоритм для алгоритма умножения Карацубы, и я пытался использовать векторы в качестве моей структуры данных для обработки действительно длинных чисел, которые будут вводиться …

Моя программа может делать меньшие числа хорошо, однако она действительно борется с большими числами, и я получаю дамп ядра (ошибка сегмента). Он также выдает странные результаты, когда номер левой стороны меньше, чем номер правой стороны.

Есть идеи? Вот код.

#include <iostream>
#include <string>
#include <vector>

#define max(a,b) ((a) > (b) ? (a) : (b))

using namespace std;

vector<int> add(vector<int> lhs, vector<int> rhs) {
int length = max(lhs.size(), rhs.size());
int carry = 0;
int sum_col;
vector<int> result;

while(lhs.size() < length) {
lhs.insert(lhs.begin(), 0);
}
while(rhs.size() < length) {
rhs.insert(rhs.begin(), 0);
}

for(int i = length-1; i >= 0; i--) {
sum_col = lhs[i] + rhs[i] + carry;
carry = sum_col/10;
result.insert(result.begin(), (sum_col%10));
}
if(carry) {
result.insert(result.begin(), carry);
}
int x = 0;
while(result[x] == 0) {
x++;
}
result.erase(result.begin(), result.begin()+x);
return result;
}

vector<int> subtract(vector<int> lhs, vector<int> rhs) {
int length = max(lhs.size(), rhs.size());
int diff;
vector<int> result;

while(lhs.size() < length) {
lhs.insert(lhs.begin(), 0);
}
while(rhs.size() < length) {
rhs.insert(rhs.begin(), 0);
}

for(int i = length-1; i >= 0; i--) {
diff = lhs[i] - rhs[i];
if(diff >= 0) {
result.insert(result.begin(), diff);
} else {
int j = i - 1;
while(j >= 0) {
lhs[j] = (lhs[j] - 1) % 10;
if(lhs[j] != 9) {
break;
} else {
j--;
}
}
result.insert(result.begin(), diff+10);
}
}
int x = 0;
while(result[x] == 0) {
x++;
}
result.erase(result.begin(), result.begin()+x);
return result;
}

vector<int> multiply(vector<int> lhs, vector<int> rhs) {
int length = max(lhs.size(), rhs.size());
vector<int> result;

while(lhs.size() < length) {
lhs.insert(lhs.begin(), 0);
}
while(rhs.size() < length) {
rhs.insert(rhs.begin(), 0);
}

if(length == 1) {
int res = lhs[0]*rhs[0];
if(res >= 10) {
result.push_back(res/10);
result.push_back(res%10);
return result;
} else {
result.push_back(res);
return result;
}
}

vector<int>::const_iterator first0 = lhs.begin();
vector<int>::const_iterator last0 = lhs.begin() + (length/2);
vector<int> lhs0(first0, last0);
vector<int>::const_iterator first1 = lhs.begin() + (length/2);
vector<int>::const_iterator last1 = lhs.begin() + ((length/2) + (length-length/2));
vector<int> lhs1(first1, last1);
vector<int>::const_iterator first2 = rhs.begin();
vector<int>::const_iterator last2 = rhs.begin() + (length/2);
vector<int> rhs0(first2, last2);
vector<int>::const_iterator first3 = rhs.begin() + (length/2);
vector<int>::const_iterator last3 = rhs.begin() + ((length/2) + (length-length/2));
vector<int> rhs1(first3, last3);

vector<int> p0 = multiply(lhs0, rhs0);
vector<int> p1 = multiply(lhs1,rhs1);
vector<int> p2 = multiply(add(lhs0,lhs1),add(rhs0,rhs1));
vector<int> p3 = subtract(p2,add(p0,p1));

for(int i = 0; i < 2*(length-length/2); i++) {
p0.push_back(0);
}
for(int i = 0; i < (length-length/2); i++) {
p3.push_back(0);
}

result = add(add(p0,p1), p3);

int x = 0;
while(result[x] == 0) {
x++;
}
result.erase(result.begin(), result.begin()+x);
return result;
}

int main() {
vector<int> lhs;
vector<int> rhs;
vector<int> v;

lhs.push_back(2);
lhs.push_back(5);
lhs.push_back(2);
lhs.push_back(5);
lhs.push_back(2);
lhs.push_back(5);
lhs.push_back(2);
lhs.push_back(5);

rhs.push_back(1);
rhs.push_back(5);
rhs.push_back(1);
rhs.push_back(5);
rhs.push_back(1);
rhs.push_back(5);
rhs.push_back(1);v = multiply(lhs, rhs);

for(size_t i = 0; i < v.size(); i++) {
cout << v[i];
}
cout << endl;

return 0;
}

-1

Решение

Есть несколько проблем с subtract, Поскольку у вас нет способа представить отрицательное число, если rhs больше, чем lhs Ваша логика заимствования будет иметь доступ до начала данных для lhs,

Вы также можете пройти через конец result при удалении ведущих нулей, если результат равен 0.

Ваш расчет по кредиту неверен, так как -1 % 10 вернет -1, а не 9, если lhs[j] равно 0. Лучший способ вычислить это добавить 9 (на единицу меньше значения, на которое вы делите), lhs[j] = (lhs[j] + 9) % 10;,

В несвязанной заметке вы можете упростить свои вычисления итерации диапазона. поскольку last0 а также first1 имеют одинаковое значение, вы можете использовать last0 для обоих, и last1 является lhs.end(), Это упрощает lhs1 в

vector<int> lhs1(last0, lhs.end());

и вы можете избавиться от first1 а также last1, То же самое касается rhs итераторы.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]