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

Обработка out_of_range - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.83
Peperovich
43 / 43 / 4
Регистрация: 17.05.2011
Сообщений: 162
25.09.2013, 18:34     Обработка out_of_range #1
Всем привет.
Имеетмся матрица, реализованная как std::vector <std::vector <int>>. Мне нужно найти сумму всех соседних элементов для каждого элемента матрицы. В общем случае это сумма 8 элементов, но для граничных элементов это количество меньше. Как мне написав алгоритм для общего случая обрабатывать выход за границу, так чтобы при выходе за границу просто сситались след элементы.
Знаю есть vector <T>::at () , но как им пользоваться не понимаю.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.09.2013, 18:34     Обработка out_of_range
Посмотрите здесь:

Обработка ошибок C++
Обработка текста C++
C++ обработка строк.
C++ Выскакивает out_of_range
Обработка двумерных массивов. Обработка матриц C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11841 / 6820 / 771
Регистрация: 27.09.2012
Сообщений: 16,911
Записей в блоге: 2
Завершенные тесты: 1
25.09.2013, 18:39     Обработка out_of_range #2
Перед обращением к элементам для сложения проверять координаты
Peperovich
43 / 43 / 4
Регистрация: 17.05.2011
Сообщений: 162
25.09.2013, 18:42  [ТС]     Обработка out_of_range #3
Этот способ очевиден, но порождает кучу условий и кода, я же хочу чтобы просто игонорировалось исключение out of range и дальше шло сложение.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11841 / 6820 / 771
Регистрация: 27.09.2012
Сообщений: 16,911
Записей в блоге: 2
Завершенные тесты: 1
25.09.2013, 18:45     Обработка out_of_range #4
Цитата Сообщение от Peperovich Посмотреть сообщение
исключение out of range и дальше шло сложение.
тогда обрабатывайте исключение.
Цитата Сообщение от Peperovich Посмотреть сообщение
но порождает кучу условий и кода
Вы еще ни единой строчки не привели
Peperovich
43 / 43 / 4
Регистрация: 17.05.2011
Сообщений: 162
25.09.2013, 18:53  [ТС]     Обработка out_of_range #5
Цитата Сообщение от Croessmah Посмотреть сообщение
тогда обрабатывайте исключение.

Вы еще ни единой строчки не привели
ну при заходе в catch я же уже не смогу вернуться, чтобы продолжить. Придется писать 8 условий проверять нахождение у границ и в углах матрицы. код не написал, так как с телефона сижу. а вообще это мне нужно для задачи Игра Жизнь.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11841 / 6820 / 771
Регистрация: 27.09.2012
Сообщений: 16,911
Записей в блоге: 2
Завершенные тесты: 1
25.09.2013, 19:22     Обработка out_of_range #6
Цитата Сообщение от Peperovich Посмотреть сообщение
ну при заходе в catch я же уже не смогу вернуться, чтобы продолжить. Придется писать 8 условий проверять нахождение у границ и в углах матрицы. код не написал, так как с телефона сижу. а вообще это мне нужно для задачи Игра Жизнь.
Как вариант:
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
size_t GetSumm ( std :: vector < std :: vector < int > > & vec , size_t x , size_t y ) {
   struct Point {
      int x ;
      int y ;
   } ;
   static const Point directions [ ] = {
     { -1 , -1 } ,
     { 0 , -1 } ,
     { 1 , - 1 } ,
     { -1 , 0 } ,
     { 1 , 0 } ,
     { -1 , 1 } ,
     { 0 , 1 } ,
     { 1 , 1 }
   };
   static const size_t directionsCount = sizeof ( directions ) / sizeof ( *directions ) ;
   size_t summ = 0 ;
   for ( size_t d = 0 ; d < directionsCount ; ++d ) {
      try {
         summ += vec.at ( x + directions[d].x ).at ( y + directions[d].y ) ;
      }
      catch ( std::out_of_range& e ) {
      }
   }
   return summ ;
}
Для вызова передаете вектор и проверяемую клетку. Получаете сумму восьми соседей.
Например:
C++
1
2
3
4
5
6
7
8
9
10
11
12
int main( ) {
   std :: vector < std :: vector < int > > vec {
      { 1 , 1 , 1 } ,
      { 1 , 1 , 1 } ,
      { 1 , 1 , 1 } ,
   };
   for ( size_t i = 0 ; i < vec.size ( ) ; ++i ) {
      for ( size_t j = 0 ; j < vec.at ( i ).size ( ) ; ++j )
        std :: cout << std :: setw ( 3 ) << GetSumm ( vec , i , j ) ;
      std :: cout << std :: endl ;
   }
}
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
25.09.2013, 20:15     Обработка out_of_range #7
Чо вы ему тут насоветовали? Я прочитал фиг что понял.
Просто в цикле проверяй условие что бы элемент был не граничный допустим матрица 10 на 10 от простой кодец:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for(int i=0;i<v.size();i++)
for(int j=0;j<v[i].size();i++)
{
if(i==0||i==v.size()-1||j==0||j==v[i].size-1)
{
//будут элементы граничные для них не нужно считать
}
else if(i!=0&&i!=v.size()-1&&j!=0&&j!=v[i].size-1)
{
//нужный элемент, у него есть 8 соседа
//считаем сумму
int ii=i;intjj=j;
int sum=v[i][j-1]+v[i][j+1]+v[i-1][j-1]+v[i-1][j]+v[i-1][j+1] + v[i+1][j-1]+v[i+1][j]+v[i+1][j+1];
cout <<"sum= "<<sum<<endl;
}
}
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11841 / 6820 / 771
Регистрация: 27.09.2012
Сообщений: 16,911
Записей в блоге: 2
Завершенные тесты: 1
25.09.2013, 20:31     Обработка out_of_range #8
Цитата Сообщение от ninja2 Посмотреть сообщение
Чо вы ему тут насоветовали?
Цитата Сообщение от Peperovich Посмотреть сообщение
чтобы просто игонорировалось исключение out of range и дальше шло сложение.

Цитата Сообщение от ninja2 Посмотреть сообщение
Я прочитал фиг что понял.
ну это сугубо Ваши проблемы то

Добавлено через 13 минут
Цитата Сообщение от ninja2 Посмотреть сообщение
//будут элементы граничные для них не нужно считать
И, кстати, кто сказал что не нужно считать? Просто у них меньше соседей.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
25.09.2013, 20:43     Обработка out_of_range #9
Я так понял пассажиру только нужно сумму посчитать только тех элементов у которых 8 соседей, а те у которых меньше не нужно считать.

Добавлено через 5 минут
Croessmah, Не ну у тебя вариант тоже понятный, от щас разобрал, прикольный вариант. Мой уступает потому что нужно все условия вручную проверять. Его даже можно переделать легко для подсчета элементов у которых 8 соседей.
Бендерродригез
Сгибальщик
 Аватар для Бендерродригез
42 / 42 / 3
Регистрация: 18.05.2013
Сообщений: 220
Завершенные тесты: 1
25.09.2013, 20:47     Обработка out_of_range #10
Можно просто исключить из расчётов крайние клетки поля. Таки да, они всегда пустые + дополнительная памят на неиспользуемые в игре клетки, но не надо делать проверок на границы и обрабатывать исключения.
Заодно можно и простым массивом обойтись.
Peperovich
43 / 43 / 4
Регистрация: 17.05.2011
Сообщений: 162
26.09.2013, 10:23  [ТС]     Обработка out_of_range #11
Спасибо Croessmah, Вы правильно поняли, что мне нужно.

Добавлено через 7 минут
Только ругается при компиляции

field_life.h
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
#ifndef FIELD_LIFE_H
#define FIELD_LIFE_H
 
#include <vector>
 
class field_life
{
public:
    field_life();
    void print() const;
    void next_gen();
    bool be_or_not_to_be(std::vector<std::vector<int>> &,int,int);
    bool is_born(std::vector<std::vector<int> > &,int,int);
private:
    std::vector<std::vector<int> > field;
    int size_field; 
    struct Point
    {
        int x;
        int y;
    } ;
    static const Point directions [8];
};
#endif
filed_life.cpp
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
#include "field_life.h"
#include <fstream>
#include <iostream>
 
static const field_life::Point field_life::directions []={
     { -1 , -1 } ,
     { 0 , -1 } ,
     { 1 , - 1 } ,
     { -1 , 0 } ,
     { 1 , 0 } ,
     { -1 , 1 } ,
     { 0 , 1 } ,
     { 1 , 1 }
   };
 
field_life::field_life()
{
    ...
}
 
void field_life::print() const
{
    ...
}
 
void field_life::next_gen()
{
    std::vector<std::vector<int> > temp_f(field);
    for(int i=0;i<size_field;i++)
    {
        for(int j=0;j<size_field;j++)
            if (temp_f[i][j]) field[i][j]=be_or_not_to_be(temp_f,i,j);
            else field[i][j]=is_born(temp_f,i,j);
        std::cout<<std::endl;
    }
}
 
bool field_life ::be_or_not_to_be (std::vector<std::vector<int>> &vec , int a ,int b )
{
    ...
}
 
bool field_life :: is_born ( std :: vector < std :: vector < int > > &vec , int a ,int b )
{
    ...
}
выдает field_life.cpp(5) : error C2720: 'field_life::directions' : 'static ' storage-class specifier illegal on members
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11841 / 6820 / 771
Регистрация: 27.09.2012
Сообщений: 16,911
Записей в блоге: 2
Завершенные тесты: 1
26.09.2013, 10:32     Обработка out_of_range #12
C++
1
const field_life::Point field_life::directions []={
без static
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
26.09.2013, 12:09     Обработка out_of_range #13
Можно перегрузить оператор [] (subscript) и в нем контролировать выход за границу.
CheshireCat
26.09.2013, 12:21
  #14

Не по теме:

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

Исключения правильно использовать там, где возможность некоей исключительной ситуации предусматривается, но заранее невозможно предсказать, когда и при каких условиях она наступит. Примитивный пример: разрыв сетевого соединения. Он может возникнуть в непредсказуемый момент просто потому, что в 500 километрах от сервера пьяный экскаваторщик Петя задел ковшом магистральный кабель. Заранее предсказать момент наступления такого события невозможно, равно как невозможно предсказать состояние сетевого стека, обработчиков протоколов и прочего.... Вот тут - грамотно будет выбросить исключение, и пусть код верхнего уровня разбирается, что делать дальше.

Наоборот, в описанной задаче - можно для каждого краевого элемента заранее описать и предусмотреть условия выхода за диапазон. Ну и зачем тут исключения? Достаточно обычных проверок типа if(...).

Peperovich
43 / 43 / 4
Регистрация: 17.05.2011
Сообщений: 162
26.09.2013, 12:33  [ТС]     Обработка out_of_range #15
Перегрузка оператора [] для std::vector? Для него же есть своя реализация перегрузки []. Какая из них будет вызываться?

CheshireCat полностью согласен с Вашим постом. Просто хотелось попробовать через исключение.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.09.2013, 12:46     Обработка out_of_range #16
Цитата Сообщение от CheshireCat Посмотреть сообщение
Наоборот, в описанной задаче - можно для каждого краевого элемента заранее описать и предусмотреть условия выхода за диапазон. Ну и зачем тут исключения? Достаточно обычных проверок типа if(...).
Ну знаешь можно использовать исключения так как удобно, тут они используются как управляющие конструкции что ли. В книгах не написано что так делать нельзя, а как раз наоборот, если это позволяет упростить код сделать его более понятным и легче в поддержке, то нужно именно так делать как будет более просто.

Да конечно исключения для обработки ошибок кажется логично, но и для управления программ тоже используются, например можно делать выход из взоженного цикла из там допустим:

C++
1
2
3
4
5
6
7
8
9
10
11
try
{
for(int i=0;i<3;i++)
for(int j=8;j<10;j++)
for(int k=4;k<10;k++)
throw;//выход из цикла
}
catch(...)
{
 
}
Просто это удобно.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11841 / 6820 / 771
Регистрация: 27.09.2012
Сообщений: 16,911
Записей в блоге: 2
Завершенные тесты: 1
26.09.2013, 12:48     Обработка out_of_range #17
Цитата Сообщение от ninja2 Посмотреть сообщение
Ну знаешь можно использовать исключения так как удобно,
удобно, но не разумно
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.09.2013, 12:48     Обработка out_of_range #18
По другому что бы выйти нам нужно использовать какой нить флаг, либо goto, но мне это не нравиться проще сгенерировать исключение и спокойно выйти туда куда нужно.
Peperovich
43 / 43 / 4
Регистрация: 17.05.2011
Сообщений: 162
26.09.2013, 12:50  [ТС]     Обработка out_of_range #19
Вообще break тоже подходит для выхода из цикла.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.09.2013, 12:53     Обработка out_of_range
Еще ссылки по теме:

Обработка исключений C++
Обработка мыши VS C++ C++
Std::out_of_range C++

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

Или воспользуйтесь поиском по форуму:
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.09.2013, 12:53     Обработка out_of_range #20
Цитата Сообщение от Croessmah Посмотреть сообщение
удобно, но не разумно
Если мне память не подводят в книгах говориться что исключения можно использовать для управления программ, это не запрещено, помоему даже есть целая глава.

Вообще таваришь ТС не смотри ты на эти все стерертипы, а делай всегда так как тебе удобно потому что нету правил которые говорят что этот оператор именно так нужно использовать, да как хочешь так и используй.
Да есть правила хорошего тона или как их там называют, но их не сложно соблюдать если в команде пишешь, если твой код никто читать не будет, ты сам себе хозяин, ты не для когото пишешь, а для себя, пиши так как тебе лучше и ни кого не слушай, без запретов нивчом себя не ограничивай. Это просто мой тебе совет, я сам ему стараюсь следовать.
Yandex
Объявления
26.09.2013, 12:53     Обработка out_of_range
Ответ Создать тему
Опции темы

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