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

Почему вместо вектора 2х5 выходит 2х9 - C++

Восстановить пароль Регистрация
 
Lopster92
3 / 3 / 0
Регистрация: 25.12.2009
Сообщений: 49
30.04.2012, 01:47     Почему вместо вектора 2х5 выходит 2х9 #1
Почему вместо вектора 2х5 выходит 2х9?

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 "wnd_rus.h"
#include <iostream>
#include <vector>
 
struct point {
    int dist, way;
};
 
typedef std::vector<point> path_v;
typedef std::vector<path_v> pathes_v;
 
 
int main() {
#if (defined(_MSC_VER) | defined(__MINGW32__) )
    beginWndRus();
#endif
 
    const size_t LIMIT_P = 5;
    const size_t LIMIT_PS = 2;
 
    point p = {0, 0};
    path_v pv;
    pathes_v psv;
 
    for(size_t j=0; j < LIMIT_PS; j++){
        for(size_t i=j; i < LIMIT_P; i++) {
            //p = {i, i+1};
            p.dist = i;
            p.way = i+1;
            pv.push_back(p);
        }
        psv.push_back(pv);
    }
 
    path_v::iterator pv_it;
    pathes_v::iterator psv_it;
 
    // ++p_v_it
    for(psv_it = psv.begin(); psv_it != psv.end(); psv_it++) {
        for(pv_it = pv.begin(); pv_it != pv.end(); pv_it++) {
            std::cout << "Dist: " << (*pv_it).dist << "; Way: "<< (*pv_it).way << ";\n";
        }
    }
 
#if (defined(_MSC_VER) | defined(__MINGW32__) )
    endWndRus();
#endif
    return 0;
}
Результат вывода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Dist: 0; Way: 1;
Dist: 1; Way: 2;
Dist: 2; Way: 3;
Dist: 3; Way: 4;
Dist: 4; Way: 5;
Dist: 1; Way: 2;
Dist: 2; Way: 3;
Dist: 3; Way: 4;
Dist: 4; Way: 5;
Dist: 0; Way: 1;
Dist: 1; Way: 2;
Dist: 2; Way: 3;
Dist: 3; Way: 4;
Dist: 4; Way: 5;
Dist: 1; Way: 2;
Dist: 2; Way: 3;
Dist: 3; Way: 4;
Dist: 4; Way: 5;
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
30.04.2012, 01:57     Почему вместо вектора 2х5 выходит 2х9 #2
Цитата Сообщение от Lopster92 Посмотреть сообщение
for(pv_it = pv.begin(); pv_it != pv.end(); pv_it++) {
Ошибка здесь
pv - это был временный вектор, который заталкивался в psv
после формирования psv о временном векторе pv надо было забыть и начальное значение итератора pv_it искать там, на что указывает psv
а именно
C++
1
for(pv_it = (*psv_it).begin(); pv_it != (*psv_it).end() ; pv_it++)
Как-то так. (Не силён в STL)
Bers
Заблокирован
30.04.2012, 02:03     Почему вместо вектора 2х5 выходит 2х9 #3
косяк здесь:
C++ (Qt)
1
2
3
4
5
* * for(psv_it = psv.begin(); psv_it != psv.end(); psv_it++) {
* * * * for(pv_it = pv.begin(); pv_it != pv.end(); pv_it++) {
* * * * * * std::cout << "Dist: " << (*pv_it).dist << "; Way: "<< (*pv_it).way << ";\n";
* * * * }
* * }
При выводе данных, в цикле сначала извлекай внутренний вектор path_v из вектора pathes_v
И уже потом толкай второй цикл, в котором будет вывод данных из path_v

Получится должно что-то вроде:


C++ (Qt)
1
2
3
4
5
6
7
8
9
* * for(psv_it = psv.begin(); psv_it != psv.end(); psv_it++) {
        
        path_v & agent = *psv_it; //извлечение очередного массива
* * * * 
        for(pv_it = agent .begin(); pv_it != agent .end(); pv_it++) {
 
* * * * * * std::cout << "Dist: " << (*pv_it).dist << "; Way: "<< (*pv_it).way << ";\n";
* * * * }
* * }
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
30.04.2012, 02:11     Почему вместо вектора 2х5 выходит 2х9 #4
Это был раз.
А второе это этот момент.
Цитата Сообщение от Lopster92 Посмотреть сообщение
C++
1
2
3
4
5
6
7
for(size_t i=j; i < LIMIT_P; i++) {
* * * * * * //p = {i, i+1};
* * * * * * p.dist = i;
* * * * * * p.way = i+1;
* * * * * * pv.push_back(p);
* * * * }
* * * * psv.push_back(pv);
Опять-таки не уверен, но похоже, перед созданием очередного вектора pv для заталкивания его в список векторов, из него не вынуты старые значения. То есть он вообще никак не сбрасывается.
вместо того, чтоб заполняться как
psv[0]={pv[0], pv[1], pv[2], pv[3], pv[4]}
psv[1]={pv[0], pv[1], pv[2], pv[3], pv[4]}
///...
Он заполняется так
psv[0]={pv[0], pv[1], pv[2], pv[3], pv[4]}
psv[1]={pv[0], pv[1], pv[2], pv[3], pv[4], pv[5], pv[6], pv[7], pv[8], pv[9]}
psv[1]={pv[0], pv[1], pv[2], pv[3], pv[4], pv[5], pv[6], pv[7], pv[8], pv[9], pv[10], pv[11], pv[12], pv[13], pv[14]}
///...
Bers
Заблокирован
30.04.2012, 02:18     Почему вместо вектора 2х5 выходит 2х9 #5
Ну да. Автор кода нарушил одну из заповедей "идеального кода": создавай переменные по месту использования:

C++ (Qt)
1
2
3
4
5
6
7
8
9
pathes_v psv;
for(size_t j=0; j < LIMIT_PS; j++){
    path_v pv;
    for(size_t i=j; i < LIMIT_P; i++) {
         point p = {i, i+1};  
         pv.push_back(p);
    }
    psv.push_back(pv);
 }
Lopster92
3 / 3 / 0
Регистрация: 25.12.2009
Сообщений: 49
30.04.2012, 02:34  [ТС]     Почему вместо вектора 2х5 выходит 2х9 #6
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
pv - это был временный вектор
for(pv_it = (*psv_it).begin(); pv_it != (*psv_it).end() ; pv_it++)
Цитата Сообщение от Bers Посмотреть сообщение
При выводе данных, в цикле сначала извлекай внутренний вектор path_v из вектора pathes_v
И уже потом толкай второй цикл, в котором будет вывод данных из path_v
ВОу)))) Упустил))) Благодарю)))


Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Опять-таки не уверен, но похоже, перед созданием очередного вектора pv для заталкивания его в список векторов, из него не вынуты старые значения. То есть он вообще никак не сбрасывается.
вместо того, чтоб заполняться как
psv[0]={pv[0], pv[1], pv[2], pv[3], pv[4]}
psv[1]={pv[0], pv[1], pv[2], pv[3], pv[4]}
///...
Он заполняется так
psv[0]={pv[0], pv[1], pv[2], pv[3], pv[4]}
psv[1]={pv[0], pv[1], pv[2], pv[3], pv[4], pv[5], pv[6], pv[7], pv[8], pv[9]}
psv[1]={pv[0], pv[1], pv[2], pv[3], pv[4], pv[5], pv[6], pv[7], pv[8], pv[9], pv[10], pv[11], pv[12], pv[13], pv[14]}
///...
Угу, понял) Спасиб:-)

Цитата Сообщение от Bers Посмотреть сообщение
Автор кода нарушил одну из заповедей "идеального кода": создавай переменные по месту использования:
Ага)) А разве сбросить не лучше будет, чем каждый раз новый создавать?
Bers
Заблокирован
30.04.2012, 02:57     Почему вместо вектора 2х5 выходит 2х9 #7
Цитата Сообщение от Lopster92 Посмотреть сообщение
Ага)) А разве сбросить не лучше будет, чем каждый раз новый создавать?
Зависит от ситуации.

Вектор при сбрасывании не чистит память. Если это не критично, то дешевле его сбрасывать, а не создавать каждый раз заново.

С другой стороны, в твоём случае вектора используются с заранее известным количеством элементов.А в этом случае, выгоднее один раз создать вектора нужных размеров, и в последствии работать с ними, как с обычными массивами.

А у тебя в данный момент времени при заполнении массива происходит постоянный реаллок памяти, в результате которого убивается производительность.

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
pathes_v psv;
for(size_t j=0; j < LIMIT_PS; j++){
    path_v pv;
    for(size_t i=j; i < LIMIT_P; i++) {
         point p = {i, i+1};  
         pv.push_back(p);
    }
    //при добавлении очередного вектора, массив расширяется.
    //Что является дорогостоящей операцией
    psv.push_back(pv); 
 }
Я бы сделал так:


C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
//создаю вектор с заранее явно указанными размерами
pathes_v psv(LIMIT_PS, path_v (LIMIT_P)); 
for(size_t j=0; j < LIMIT_PS; j++){
 
     path_v & agent = psv[j]; //извлекаем внутренний вектор
 
    for(size_t i=j; i < LIMIT_P; i++) {
         point& p = agent[i]; //извлекли данные из внутреннего вектора
         p.dist = i;
         p.way = i+1;
    }
 }
Или даже вот так:



C++ (Qt)
1
2
3
4
5
6
7
8
9
//создаю вектор с заранее явно указанными размерами
pathes_v psv(LIMIT_PS, path_v (LIMIT_P)); 
for(size_t j=0; j < LIMIT_PS; j++){
    for(size_t i=j; i < LIMIT_P; i++) {
         point& p = psv[j][i]; //работаем, как с обычным двухмерным массивом
         p.dist = i;
         p.way = i+1;
    }
 }
Lopster92
3 / 3 / 0
Регистрация: 25.12.2009
Сообщений: 49
30.04.2012, 04:25  [ТС]     Почему вместо вектора 2х5 выходит 2х9 #8
Написал функцию для поиска кротчайшего пути из вектора. Компилятор ругается на последнюю строчку:
return *(shortest->first);
"conversion from 'std::vector<point, std::allocator<point> >' to non-scalar type 'pathes_v' requested"

Попробовал даже приведение типов явное сделать, но нифига((

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <cstdio>
#include <vector>
#include <numeric>
 
 
 
struct point {
    int dist, way;
};
 
typedef std::vector<point> path_v;
typedef std::vector<path_v> pathes_v;
 
pathes_v getShortest(pathes_v & psv);
 
int main() {
 
    const size_t LIMIT_P = 5;
    const size_t LIMIT_PS = 2;
 
    pathes_v psv;
    for(size_t j=0; j < LIMIT_PS; j++){
        path_v pv;
        for(size_t i=j; i < LIMIT_P; i++) {
            point p = {i, i+1};
            pv.push_back(p);
        }
        psv.push_back(pv);
    }
 
    path_v::iterator pv_it;
    pathes_v::iterator psv_it;
 
    for(psv_it = psv.begin(); psv_it != psv.end(); psv_it++) {
        for(pv_it = (*psv_it).begin(); pv_it != (*psv_it).end(); pv_it++) {
            std::cout << "Dist: " << (*pv_it).dist << "; Way: "<< (*pv_it).way << ";\n";
        }
    }
 
    pathes_v shortest = getShortest(psv);
 
    return 0;
}
 
 
pathes_v getShortest(pathes_v & psv) {
    //=====================Accumulate summ=========================
 
    size_t sum = 0;
    std::vector<std::pair<pathes_v::iterator, size_t > > summs;
    for(pathes_v::iterator its = psv.begin(); its != psv.end(); its++) {
        for(path_v::iterator it = its->begin(); it != its->end(); it++) {
            sum += (*it).dist;
            std::cout << sum << std::endl;
        }
        std::pair<pathes_v::iterator, size_t> pair(its, sum);
        summs.push_back(pair);
    }
 
    // or
 
    /*
    std::vector<std::pair<pathes_v::iterator, size_t > > summs;
    for(pathes_v::iterator its = psv.begin(); its != psv.end(); its++) {
        size_t sum = std::accumulate( (its->begin())->dist, (its->end())->dist, 0);
        std::cout << sum << std::endl;
        std::pair<pathes_v::iterator, size_t> pair(its, sum);
        summs.push_back(pair);
    }
    */
 
    //=====================Find shortest way=========================
 
    std::vector<std::pair<pathes_v::iterator, size_t > >::iterator shortest = summs.begin();
    for(std::vector<std::pair<pathes_v::iterator, size_t > >::iterator it = summs.begin();
            it != summs.end(); it++) {
        if(it->second < shortest->second) {
            shortest = it;
        }
    }
 
    return *(shortest->first); // returns  *(pathes_v::iterator) , it means "pathes_v"
}
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
30.04.2012, 04:43     Почему вместо вектора 2х5 выходит 2х9 #9
getShortest возвращает path_v, а не pathes_v
*(pathes_v::iterator) есть path_v&

вообще код убийственный
нужно больше стандартных алгоритмов и typedef'ов
складывание итераторов одного контейнера в другой контейнер - чтото очень суровое
Lopster92
3 / 3 / 0
Регистрация: 25.12.2009
Сообщений: 49
30.04.2012, 05:06  [ТС]     Почему вместо вектора 2х5 выходит 2х9 #10
Цитата Сообщение от alex_x_x Посмотреть сообщение
getShortest возвращает path_v, а не pathes_v
*(pathes_v::iterator) есть path_v&
Почему path_v возвращает то?
C++
1
2
std::vector<std::pair<pathes_v::iterator, size_t > >::iterator shortest = summs.begin();
return *(shortest->first);
Разименование возвращает
C++
1
std::pair<pathes_v::iterator, size_t >
, а shortest->first уже извлекает из этого pathes_v...

================================================================================

или же по другому
C++
1
*((*shortest).first))
Разименовываем, получаем
C++
1
std::pair<pathes_v::iterator, size_t >
, далее извлекаем first, получаем pathes_v::iterator и еще раз разименовываем.


Может я чего-то перепутал?? Но по логике вроде без ошибок((
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
30.04.2012, 05:09     Почему вместо вектора 2х5 выходит 2х9 #11
Цитата Сообщение от Lopster92 Посмотреть сообщение
shortest->first
возвращает pathes_v::iterator
*(pathes_v::iterator) возвращает path_v

pathes_v::iterator - ходит по элементам pathes_v, этими элементами являются path_v
код такой вырвиглазный, что тут право без пол литра не разберешься
Lopster92
3 / 3 / 0
Регистрация: 25.12.2009
Сообщений: 49
30.04.2012, 06:32  [ТС]     Почему вместо вектора 2х5 выходит 2х9 #12
Цитата Сообщение от alex_x_x Посмотреть сообщение
код такой вырвиглазный, что тут право без пол литра не разберешься
Ахахахах))) Есть такое дело))) Я чет окончательно запутался, а как мне тогда вернуть pathes_v?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.05.2012, 14:48     Почему вместо вектора 2х5 выходит 2х9
Еще ссылки по теме:

C++ Почему выходит ошибка (структура)
C++ Почему рандом не выходит?
Почему выходит за пределы массива? C++

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

Или воспользуйтесь поиском по форуму:
Lopster92
3 / 3 / 0
Регистрация: 25.12.2009
Сообщений: 49
01.05.2012, 14:48  [ТС]     Почему вместо вектора 2х5 выходит 2х9 #13
Цитата Сообщение от Lopster92 Посмотреть сообщение
Ахахахах))) Есть такое дело))) Я чет окончательно запутался, а как мне тогда вернуть pathes_v?
А все разобрался...Спасибо большое:-)
Yandex
Объявления
01.05.2012, 14:48     Почему вместо вектора 2х5 выходит 2х9
Ответ Создать тему
Опции темы

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