Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/47: Рейтинг темы: голосов - 47, средняя оценка - 4.57
43 / 43 / 13
Регистрация: 17.05.2011
Сообщений: 162
1

Обработка out_of_range

25.09.2013, 18:34. Показов 8408. Ответов 26
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет.
Имеетмся матрица, реализованная как std::vector <std::vector <int>>. Мне нужно найти сумму всех соседних элементов для каждого элемента матрицы. В общем случае это сумма 8 элементов, но для граничных элементов это количество меньше. Как мне написав алгоритм для общего случая обрабатывать выход за границу, так чтобы при выходе за границу просто сситались след элементы.
Знаю есть vector <T>::at () , но как им пользоваться не понимаю.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.09.2013, 18:34
Ответы с готовыми решениями:

Std::out_of_range
Доброго всем времени суток! Никак не пойму в чем проблема.. обрабатываю большой файл, примерно...

Выскакивает out_of_range
Добрый День! Не пойму в чем проблема, дальше return false не уходит, вылетает окно &quot;Необработанное...

Исключение Microsoft C++: std::out_of_range
Вызывается исключение в функции, не пойму в чем дело, помогите объяснить, только начала работу с...

Runtime ошибка - terminate called after throwing an instance of 'std::out_of_range'
Пишу что-то вроде компилятора. Так как никакой литературы по созданию компилятора не читал в моём...

26
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
25.09.2013, 18:39 2
Перед обращением к элементам для сложения проверять координаты
0
43 / 43 / 13
Регистрация: 17.05.2011
Сообщений: 162
25.09.2013, 18:42  [ТС] 3
Этот способ очевиден, но порождает кучу условий и кода, я же хочу чтобы просто игонорировалось исключение out of range и дальше шло сложение.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
25.09.2013, 18:45 4
Цитата Сообщение от Peperovich Посмотреть сообщение
исключение out of range и дальше шло сложение.
тогда обрабатывайте исключение.
Цитата Сообщение от Peperovich Посмотреть сообщение
но порождает кучу условий и кода
Вы еще ни единой строчки не привели
0
43 / 43 / 13
Регистрация: 17.05.2011
Сообщений: 162
25.09.2013, 18:53  [ТС] 5
Цитата Сообщение от Croessmah Посмотреть сообщение
тогда обрабатывайте исключение.

Вы еще ни единой строчки не привели
ну при заходе в catch я же уже не смогу вернуться, чтобы продолжить. Придется писать 8 условий проверять нахождение у границ и в углах матрицы. код не написал, так как с телефона сижу. а вообще это мне нужно для задачи Игра Жизнь.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
25.09.2013, 19:22 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 ;
   }
}
1
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
25.09.2013, 20:15 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;
}
}
1
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
25.09.2013, 20:31 8
Цитата Сообщение от ninja2 Посмотреть сообщение
Чо вы ему тут насоветовали?
Цитата Сообщение от Peperovich Посмотреть сообщение
чтобы просто игонорировалось исключение out of range и дальше шло сложение.

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

Добавлено через 13 минут
Цитата Сообщение от ninja2 Посмотреть сообщение
//будут элементы граничные для них не нужно считать
И, кстати, кто сказал что не нужно считать? Просто у них меньше соседей.
1
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
25.09.2013, 20:43 9
Я так понял пассажиру только нужно сумму посчитать только тех элементов у которых 8 соседей, а те у которых меньше не нужно считать.

Добавлено через 5 минут
Croessmah, Не ну у тебя вариант тоже понятный, от щас разобрал, прикольный вариант. Мой уступает потому что нужно все условия вручную проверять. Его даже можно переделать легко для подсчета элементов у которых 8 соседей.
0
Сгибальщик
42 / 42 / 4
Регистрация: 18.05.2013
Сообщений: 220
25.09.2013, 20:47 10
Можно просто исключить из расчётов крайние клетки поля. Таки да, они всегда пустые + дополнительная памят на неиспользуемые в игре клетки, но не надо делать проверок на границы и обрабатывать исключения.
Заодно можно и простым массивом обойтись.
0
43 / 43 / 13
Регистрация: 17.05.2011
Сообщений: 162
26.09.2013, 10:23  [ТС] 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
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
26.09.2013, 10:32 12
C++
1
const field_life::Point field_life::directions []={
без static
1
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
26.09.2013, 12:09 13
Можно перегрузить оператор [] (subscript) и в нем контролировать выход за границу.
1
CheshireCat
26.09.2013, 12:21
  #14

Не по теме:

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

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

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

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

CheshireCat полностью согласен с Вашим постом. Просто хотелось попробовать через исключение.
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
26.09.2013, 12:46 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(...)
{
 
}
Просто это удобно.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
26.09.2013, 12:48 17
Цитата Сообщение от ninja2 Посмотреть сообщение
Ну знаешь можно использовать исключения так как удобно,
удобно, но не разумно
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
26.09.2013, 12:48 18
По другому что бы выйти нам нужно использовать какой нить флаг, либо goto, но мне это не нравиться проще сгенерировать исключение и спокойно выйти туда куда нужно.
0
43 / 43 / 13
Регистрация: 17.05.2011
Сообщений: 162
26.09.2013, 12:50  [ТС] 19
Вообще break тоже подходит для выхода из цикла.
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
26.09.2013, 12:53 20
Цитата Сообщение от Croessmah Посмотреть сообщение
удобно, но не разумно
Если мне память не подводят в книгах говориться что исключения можно использовать для управления программ, это не запрещено, помоему даже есть целая глава.

Вообще таваришь ТС не смотри ты на эти все стерертипы, а делай всегда так как тебе удобно потому что нету правил которые говорят что этот оператор именно так нужно использовать, да как хочешь так и используй.
Да есть правила хорошего тона или как их там называют, но их не сложно соблюдать если в команде пишешь, если твой код никто читать не будет, ты сам себе хозяин, ты не для когото пишешь, а для себя, пиши так как тебе лучше и ни кого не слушай, без запретов нивчом себя не ограничивай. Это просто мой тебе совет, я сам ему стараюсь следовать.
0
26.09.2013, 12:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.09.2013, 12:53
Помогаю со студенческими работами здесь

Unhandled exception at at 0x75E717D2 in ConsoleApplication24.exe: Microsoft C++ exception: std::out_of_range at memory l
Здравствуйте, помогите пожалуйста, при проходе через последний цикл выдаёт вот такую ошибку:...

Как в MS Visual Studio отключить сообщение "std::out_of_range at memory location"?
это сообщение появляется, в моем случае, когда считываются символы не входящие в нужный диапазон по...

out_of_range exaptions и условные операторы
Меня интересует следущее: почему этот код не выдает ошибок типа &quot;индекс вне границ массива&quot; if (a...

Std::out_of_range
здравствуйте. не могу понять, из за чего возникают ошибки. вот код: void...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru