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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.83
Peperovich
43 / 43 / 4
Регистрация: 17.05.2011
Сообщений: 162
#1

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

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

Всем привет.
Имеетмся матрица, реализованная как 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++):

Выскакивает out_of_range - C++
Добрый День! Не пойму в чем проблема, дальше return false не уходит, вылетает окно &quot;Необработанное исключение в &quot;0x75a2d36f&quot; в &quot;bbb.exe&quot;:...

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

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

Обработка события Click, вставка html после генерации и обработка этого кода - jQuery
Подскажите пожалуйста как заставить работать эту часть кода 18 строка $(&quot;.image&quot;).click(function() { alert (1); ...

Обработка одномерных массивов и Обработка двухмерных массивов. - Visual Basic
Всем привет, У меня большие проблемы... нужно сделать 2 лабораторные работы по информатике, но я ничегошеньки в VB не понимаю... ...

Обработка на 7 - 1С
Здравствуйте, написал простенькую обработочку для 8, теперь столкнулся что мне она понадобится и в 7ке. С семерошным языком не знаком т.к....

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

Вы еще ни единой строчки не привели
ну при заходе в catch я же уже не смогу вернуться, чтобы продолжить. Придется писать 8 условий проверять нахождение у границ и в углах матрицы. код не написал, так как с телефона сижу. а вообще это мне нужно для задачи Игра Жизнь.
Croessmah
Модератор
Эксперт CЭксперт С++
13134 / 7397 / 828
Регистрация: 27.09.2012
Сообщений: 18,227
Записей в блоге: 3
Завершенные тесты: 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 ;
   }
}
ninja2
231 / 187 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
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;
}
}
Croessmah
Модератор
Эксперт CЭксперт С++
13134 / 7397 / 828
Регистрация: 27.09.2012
Сообщений: 18,227
Записей в блоге: 3
Завершенные тесты: 1
25.09.2013, 20:31 #8
Цитата Сообщение от ninja2 Посмотреть сообщение
Чо вы ему тут насоветовали?
Цитата Сообщение от Peperovich Посмотреть сообщение
чтобы просто игонорировалось исключение out of range и дальше шло сложение.

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

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

Добавлено через 5 минут
Croessmah, Не ну у тебя вариант тоже понятный, от щас разобрал, прикольный вариант. Мой уступает потому что нужно все условия вручную проверять. Его даже можно переделать легко для подсчета элементов у которых 8 соседей.
Бендерродригез
Сгибальщик
42 / 42 / 3
Регистрация: 18.05.2013
Сообщений: 220
Завершенные тесты: 1
25.09.2013, 20:47 #10
Можно просто исключить из расчётов крайние клетки поля. Таки да, они всегда пустые + дополнительная памят на неиспользуемые в игре клетки, но не надо делать проверок на границы и обрабатывать исключения.
Заодно можно и простым массивом обойтись.
Peperovich
43 / 43 / 4
Регистрация: 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
Croessmah
Модератор
Эксперт CЭксперт С++
13134 / 7397 / 828
Регистрация: 27.09.2012
Сообщений: 18,227
Записей в блоге: 3
Завершенные тесты: 1
26.09.2013, 10:32 #12
C++
1
const field_life::Point field_life::directions []={
без static
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
26.09.2013, 12:09 #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  [ТС] #15
Перегрузка оператора [] для std::vector? Для него же есть своя реализация перегрузки []. Какая из них будет вызываться?

CheshireCat полностью согласен с Вашим постом. Просто хотелось попробовать через исключение.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.09.2013, 12:33
Привет! Вот еще темы с ответами:

1C 8.x Обработка ТО - 1С
Где найти обработку торговое оборудование?

1C 8.x Обработка - 1С
Народ! Впервые пишу обработку по загрузке данных из файла. Подскажите, как брать данные из файла. Вот я выбираю файл &amp;НаКлиенте Процедура...

обработка - C++ Qt
добрые вечер! подскажите как провернуть: идет показ картинок и пользователь должен выбрать 1 из 3-х предложенных вариантов... показ...

Обработка 1с 8 - 1С
Собственно проблема-то не в системе, а в мозге :) На форме обработки имеется таблица, поля таблицы описаны в тексте обработки...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
26.09.2013, 12:33
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru