Форум программистов, компьютерный форум CyberForum.ru

Перегрузка оператора *= для vector<int> - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 5.00
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
14.03.2010, 22:07     Перегрузка оператора *= для vector<int> #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <vector>
 
const long long base = 1000*1000*1000;
std::vector<int> &operator *= (std::vector<int> &a, std::vector<int> &b)
{
    std::vector<int> res(b.size() + a.size());
    for(int i = 0; i < a.size(); ++i)
    {
        for (int j = 0, carry = 0; j < b.size() || carry; ++j)
        {
            long long cur = res[i+j] + a[i] * long long( j < b.size() ? b[j] : 0 ) + carry;
            res[i+j] = cur % base;
            carry = cur / base;
        }
    }
    while (res.size() && !res.back()) res.pop_back();
    a = res;
    return res;
}
 
std::vector<int> BinPow(int a, int n)
{
    std::vector<int> res(1, 1), b(1, a);
    while (n) {
        if (n&1) --n, res *= b;
        else n >>= 1, b *= b;
    }
    return res;
}
 
int main()
{
    int a, n;
    std::cin >> a >> n;
    std::vector<int> res = BinPow(a, n);
    std::cout << res.back();
    for(int i = res.size()-2; i >= 0; --i) printf("%09d", res[i]);
    std::cout << std::endl;
    system("pause");
}
Меня смущает тот факт, что для сохранения значения умножения двух векторов нужно присвоить a = res; и потом еще раз его вернуть return res; разве, при возврате результаа он не должен сохранятся переменной строки 26-27 ??
Просто когда я убераю строку 18 результат вычислений пропадает. Можете сказать почему и как исправить?

И, по ходу дела, какой аналог printf("%09d", res[i]); у std::cout ??
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
14.03.2010, 22:53     Перегрузка оператора *= для vector<int> #2
Цитата Сообщение от outoftime Посмотреть сообщение
Меня смущает тот факт, что для сохранения значения умножения двух векторов нужно присвоить a = res; и потом еще раз его вернуть return res; разве, при возврате результаа он не должен сохранятся переменной строки 26-27 ??
По логике работы всё правильно: то, что возвращается, - это результат оператора. Например,
Код
qq = a *= b
В qq попадёт возвращённое значение, а на a оно не влияет. Только возвращать вроде надо ссылку на первый операнд, то есть a.
Цитата Сообщение от outoftime Посмотреть сообщение
И, по ходу дела, какой аналог printf("%09d", res[i]); у std::cout ??
Код
#include <iomanip>
...
std::cout << std::setfill('0') << std::setw(9) << res[i];
Добавлено через 11 минут
А ещё std::internal надо, чтобы нули были между знаком и цифрами, а не перед всем. setw действует на ближайшее, другие - на все.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
14.03.2010, 23:11  [ТС]     Перегрузка оператора *= для vector<int> #3
Цитата Сообщение от Somebody Посмотреть сообщение
По логике работы всё правильно: то, что возвращается, - это результат оператора.
В том то и проблема что логика а *= с это а = а * с;

Добавлено через 3 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <iomanip>
#include <vector>
 
typedef long long LL;
 
const long long base = 1000*1000*1000;
 
std::vector<int> &operator * (std::vector<int> &a, std::vector<int> &b)
{
    std::vector<int> res(b.size() + a.size());
    for(int i = 0; i < a.size(); ++i)
        for (int j = 0, carry = 0; j < b.size() || carry; ++j)
        {
            LL cur = res[i+j] + a[i] * LL( j < b.size() ? b[j] : 0 ) + carry;
            res[i+j] = cur % base;
            carry = cur / base;
        }
    while (res.size() && !res.back()) res.pop_back();
    return res;
}
 
std::vector<int> &operator *= (std::vector<int> &a, std::vector<int> &b)
{
    return a * b;
}
 
std::vector<int> BinPow(int a, int n)
{
    std::vector<int> res(1, 1), b(1, a);
    while (n) {
        if (n&1) --n, res *= b;
        else n >>= 1, b *= b;
    }
    return res;
}
 
int main()
{
    int a, n;
    std::cin >> a >> n;
    std::vector<int> res = BinPow(a, n);
    std::cout << res.back();
    std::cout.fill('0'), std::cout.width(9);
    for(int i = res.size()-2; i >= 0; --i) std::cout << res[i];
    std::cout << std::endl;
    system("pause");
}
Вот такое чудо не пашет,
11 C:\Documents and Settings\Администратор\Рабочий стол\help.cpp [Warning] reference to local variable `res' returned
ISergey
Maniac
Эксперт С++
 Аватар для ISergey
1330 / 863 / 50
Регистрация: 02.01.2009
Сообщений: 2,622
Записей в блоге: 1
14.03.2010, 23:36     Перегрузка оператора *= для vector<int> #4
Как-то так..
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <iomanip>
#include <vector>
 
typedef long long LL;
 
const long long base = 1000*1000*1000;
 
std::vector<int> operator * (const std::vector<int> &a, const std::vector<int> &b)
{
    std::vector<int> res(b.size() + a.size());
    for(int i = 0; i < a.size(); ++i)
        for (int j = 0, carry = 0; j < b.size() || carry; ++j)
        {
            LL cur = res[i+j] + a[i] * LL( j < b.size() ? b[j] : 0 ) + carry;
            res[i+j] = cur % base;
            carry = cur / base;
        }
        while (res.size() && !res.back()) res.pop_back();
        return res;
}
 
std::vector<int> &operator *= (std::vector<int> &a, const std::vector<int> &b)
{
    return ( a = (a * b) );
}
 
std::vector<int> BinPow(int a, int n)
{
    std::vector<int> res(1, 1), b(1, a);
    while (n) {
        if (n&1) --n, res *= b;
        else n >>= 1, b *= b;
    }
    return res;
}
 
int main()
{
    int a = 10, n = 15;
    std::cin >> a >> n;
    std::vector<int> res = BinPow(a, n);
    std::cout << res.back();
    std::cout.fill('0'), std::cout.width(9);
    for(int i = res.size()-2; i >= 0; --i) std::cout << res[i];
    std::cout << std::endl;
    system("pause");
    return 0;
}
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
15.03.2010, 09:32  [ТС]     Перегрузка оператора *= для vector<int> #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <iomanip>
#include <vector>
 
typedef long long LL;
 
const long long base = 1000*1000*1000;
 
std::vector<int> &operator * (std::vector<int> &a, std::vector<int> &b)
{
    std::vector<int> res(b.size() + a.size());
    for(int i = 0; i < a.size(); ++i)
        for (int j = 0, carry = 0; j < b.size() || carry; ++j)
        {
            LL cur = res[i+j] + a[i] * LL( j < b.size() ? b[j] : 0 ) + carry;
            res[i+j] = cur % base;
            carry = cur / base;
        }
    while (res.size() && !res.back()) res.pop_back();
    return res;
}
 
std::vector<int> &operator *= (std::vector<int> &a, std::vector<int> &b)
{
    return a = a * b;
}
 
std::vector<int> BinPow(int a, int n)
{
    std::vector<int> res(1, 1), b(1, a);
    while (n) {
        if (n&1) --n, res *= b;
        else n >>= 1, b *= b;
    }
    return res;
}
 
int main()
{
    int a, n;
    std::cin >> a >> n;
    std::vector<int> res = BinPow(a, n);
    std::cout << res.back();
    std::cout.fill('0'), std::cout.width(9);
    for(int i = res.size()-2; i >= 0; --i) std::cout << res[i];
    std::cout << std::endl;
    system("pause");
}
11 C:\Documents and Settings\Администратор\Рабочий стол\help.cpp [Warning] reference to local variable `res' returned

Добавлено через 8 часов 54 минуты
Никто не знает как с этим бороться?
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
15.03.2010, 10:00     Перегрузка оператора *= для vector<int> #6
Ты возвращаешь ссылку на временный объект, который будет уничтожен после выхода из функции. Возвращай объект не по ссылке, а по значению, или выделяй для объекта память в куче
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
15.03.2010, 15:35     Перегрузка оператора *= для vector<int> #7
Цитата Сообщение от Nameless One Посмотреть сообщение
Возвращай объект не по ссылке, а по значению
А как же код типа
Код
vector<int>& foo = (bar *= baz);
который вообще со стандартными типами должен работать. Да ещё и лишнее копирование вектора будет, что не есть хорошо.
Цитата Сообщение от Nameless One Посмотреть сообщение
или выделяй для объекта память в куче
Кто где будет его удалять тогда?
Цитата Сообщение от outoftime Посмотреть сообщение
[Warning] reference to local variable `res' returned
Ну, я уже предложил
Код
a = res;
return a;
Вот ещё тут вариант, чтобы не копировать весь массив, учитывая, что старое значение a уже не нужно.
Код
a.swap(res);
return a;
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
15.03.2010, 15:55     Перегрузка оператора *= для vector<int> #8
Somebody, я к тому вел, что нельзя возвращать указатель или ссылку на временный объект. А это происходит не в перегруженном операторе *=, а в операторе *.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
15.03.2010, 18:57  [ТС]     Перегрузка оператора *= для vector<int> #9
Цитата Сообщение от Somebody Посмотреть сообщение
a.swap(res);
return a;
Я так и делал. А нельзя ли как-то по другому?

Добавлено через 1 час 49 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <algorithm>
 
typedef long long LL;
 
const long long base = 1000*1000*1000;
 
std::vector<int> &operator *= (std::vector<int> &a, std::vector<int> &b)
{
    std::vector<int> res(b.size() + a.size());
    for(int i = 0; i < a.size(); ++i)
        for (int j = 0, carry = 0; j < b.size() || carry; ++j)
        {
            LL cur = res[i+j] + a[i] * LL( j < b.size() ? b[j] : 0 ) + carry;
            res[i+j] = cur % base;
            carry = cur / base;
        }
    while (res.size() && !res.back()) res.pop_back();
    std::swap(a, res);
    return a;
}
 
std::vector<int> BinPow(int a, int n)
{
    std::vector<int> res(1, 1), b(1, a);
    while (n) {
        if (n&1) --n, res *= b;
        else n >>= 1, b *= b;
    }
    return res;
}
 
int main()
{
    int a, n;
    std::cin >> a >> n;
    std::vector<int> res = BinPow(a, n);
    
    std::fstream out;
    out.open("out.txt");
    out << res.back();
    out.fill('0'), out.width(9);
    for(int i = res.size()-2; i >= 0; --i) out << res[i];
    out << std::endl;
 
    system("pause");
}
Кто-то может подсказать почему не производится запись в файл??
Sekt
 Аватар для Sekt
156 / 155 / 10
Регистрация: 29.04.2009
Сообщений: 637
15.03.2010, 19:01     Перегрузка оператора *= для vector<int> #10
закрыть файл пробавали?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.03.2010, 19:15     Перегрузка оператора *= для vector<int>
Еще ссылки по теме:

C++ Перегрузка оператора = для указателей
C++ Перегрузка оператора + для стека
C++ Перегрузка оператора сравнения для строк

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
15.03.2010, 19:15  [ТС]     Перегрузка оператора *= для vector<int> #11
C++
1
2
3
4
5
6
    std::fstream out("out.txt");
    out << res.back();
    out.fill('0'), out.width(9);
    for(int i = res.size()-2; i >= 0; --i) out << res[i];
    out << std::endl;
    out.close();
Поправил, не пашет..
Yandex
Объявления
15.03.2010, 19:15     Перегрузка оператора *= для vector<int>
Ответ Создать тему
Опции темы

Текущее время: 05:23. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru