Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Асмик Гаряка
Статус: Академик
Рейтинг: 10358
∙ повысить рейтинг »
Коцюрбенко Алексей aka Жерар
Статус: Академик
Рейтинг: 3880
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 2394
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / C/C++

Номер выпуска:1731
Дата выхода:07.04.2012, 22:00
Администратор рассылки:Киселёва Алёна aka Verena (Академик)
Подписчиков / экспертов:151 / 98
Вопросов / ответов:1 / 2

Консультация # 185755: Здравствуйте! У меня возникли сложности с таким вопросом: Из входного потока вводится непрямоугольная матрица целых чисел [aij], i=1,...j=1,....,ni. Значения m и ni заранее неизвестны и вводятся из входного потока. Сформировать ВЕКТОР {bi}, i=1,..,m, i-ый жлемент которого РАВЕН количеству элементов i-ой строки матрицы, отсутсвующих в (i+1)-ой ст...


Консультация # 185755:

Здравствуйте! У меня возникли сложности с таким вопросом: Из входного потока вводится непрямоугольная матрица целых чисел [aij], i=1,...j=1,....,ni. Значения m и ni заранее неизвестны и вводятся из входного потока.
Сформировать ВЕКТОР {bi}, i=1,..,m, i-ый жлемент которого РАВЕН количеству элементов i-ой строки матрицы, отсутсвующих в (i+1)-ой строке (Bm равен количеству элементов m-ой строки матрицы, отсутсвующих в первой строке).
Исходную матрицу и полученный вектор вывести в выходной поток. Дальше проконсультируйте в написании тела основной функции и функции вывода.

#include <iostream>
using namespace std;
//Для задания непрямоугольной матрицы
struct Line{
int n;
double *ar;
Line *matr;
};
//Функция ввода
istream&input(int&a){
while(!(cin>>a)){
if(cin.eof())
break;
cin.clear();
cin.ignore();
}
return cin;
}
//Ввод количества строк
int input(){
int n;
const char*pr="";
do{
cout<<pr<<endl;
pr="error!!!";
cout<<"enter number of int:";
input(n);
}while(n<=0);
return n;
}
//Ввод матрицы
int input(Line*&p){
int m=input();
p=new Line[m];
for(int i=0;i<m;++i){
p[i].n=input();
p[i].ar=new double[p[i].n];
for(int j=0;j<p[i].n,++j)
input(p[i].ar[j]);
}
return m;
}

Дата отправки: 04.04.2012, 21:17
Вопрос задал: Denis (Посетитель)
Всего ответов: 2
Страница онлайн-консультации »


Консультирует Micren (Профессор):

Здравствуйте, Denis!
Программа. C++. Тестировал GCC.

Код :
#include <iostream>
#include <stdexcept>
#include <locale>
#include <limits>

template<class T> class array;

// Тип данных с которым будем работать. По условию int.
typedef int data_t;

// Тип для формируемого вектора
typedef array<data_t> data_vector;


// Класс - массив

template<class T>
class array
{
public:
    // Конструкторы/деструктор
    array(size_t count = 0);
    array(const array<T>& r);
    virtual ~array();
    // Оператор присваивания
    const array<T> & operator=(const array<T>& r);
    // Изменение размера
    void resize(size_t count);
    // Размер
    size_t size() const;
    // Индексация массива
    T & operator[](size_t index);
    const T & operator[](size_t index) const;
private:
    void copy(const array<T>& r);
    void destroy();
    size_t _size;
    T* _data;
};


// Оператор вывода

template<class char_t, class traits_t, class T>
std::basic_ostream<char_t, traits_t> & operator<<(std::basic_ostream<char_t, traits_t>& stream, const array<T>& right)
{
    const std::ctype<char_t>& facet = std::use_facet< std::ctype<char_t> >(stream.getloc());
    for (size_t i = 0, end = right.size(); i < end; ++i)
    {
        stream << facet.widen(' ') << right[i];
    }
    return stream << std::endl;
}


// Используем для ввода данных

template<class T> T input()
{
    T result = T();
    std::cin >> result;
    if (std::cin.fail())
    {
        throw std::runtime_error("Ошибка ввода");
    }
    return result;
}


// Сравнивает вектора и возвращает результат согласно условия

unsigned int compareRows(const data_vector& vec1, const data_vector& vec2)
{
    unsigned int result = 0;

    for (size_t i = 0, end_i = vec1.size(); i < end_i; ++i)
    {
        const data_t & item = vec1[i];
        size_t j, end_j;
        for (j = 0, end_j = vec2.size(); j < end_j && item != vec2[j]; ++j);
        result += j == end_j;
    }

    return result;
}

/*
 *
 */
int main(int argc, char** argv)
{
    try
    {
        std::locale::global(std::locale(""));
        // Ввод данных
        array< array<data_t> > matr(input<size_t > ());
        for (size_t row = 0, end = matr.size(); row < end; ++row)
        {
            matr[row].resize(input<size_t > ());
            for (size_t col = 0, end = matr[row].size(); col < end; ++col)
            {
                matr[row][col] = input<data_t > ();
            }
        }
        // Выведем для проверки
        std::cout << "Исходная матрица: " << std::endl << matr;

        // Формируем вектор
        data_vector vec(matr.size());
        for (size_t row = 0, end = matr.size(); row < end; ++row)
        {
            vec[row] = compareRows(matr[row], matr[(row + 1) % end]);
        }

        // Выводим вектор
        std::cout << "Вектор:" << std::endl << vec << std::endl;

        std::cout << std::endl;
    }
    catch (std::exception& ex)
    {
        std::cerr << ex.what() << std::endl;
    }
#ifdef _WIN32
    std::system("pause");
#endif
    return 0;
}


template<class T>
array<T>::array(size_t count)
: _data(0)
, _size(0)
{
    try
    {
        _data = new T[count];
        _size = count;
    }
    catch (std::bad_alloc&)
    {
        throw std::runtime_error("Не могу выделить память");
    }
}


template<class T>
array<T>::~array()
{
    destroy();
}


template<class T>
array<T>::array(const array<T>& r)
: _data(0)
, _size(0)
{
    copy(r);
}


template<class T>
const array<T>& array<T>::operator =(const array<T>& r)
{
    copy(r);
    return *this;
}


template<class T>
void array<T>::copy(const array<T>& r)
{
    if (this == &r)
    {
        return;
    }
    try
    {
        destroy();
        _data = new T[r._size];
        _size = r._size;
        for (size_t i = 0; i < _size; ++i)
        {
            _data[i] = r._data[i];
        }
    }
    catch (std::bad_alloc&)
    {
        throw std::runtime_error("Не могу выделить память");
    }
}


template<class T>
void array<T>::destroy()
{
    if (_data)
    {
        delete[] _data;
        _size = 0;
        _data = 0;
    }
}


template<class T>
void array<T>::resize(size_t count)
{
    try
    {
        T* newData = new T[count];
        for (size_t i = 0, end = std::min(_size, count); i < end; ++i)
        {
            newData[i] = _data[i];
        }
        delete[] _data;
        _size = count;
        _data = newData;
    }
    catch (std::bad_alloc&)
    {
        throw std::runtime_error("Не могу выделить память");
    }
}


template<class T>
size_t array<T>::size() const
{
    return _size;
};


template<class T>
T& array<T>::operator [](size_t index)
{
    if (index < _size)
    {
        return _data[index];
    }
    throw std::runtime_error("Выход за пределы диапазона");
}


template<class T>
const T& array<T>::operator [](size_t index) const
{
    if (index < _size)
    {
        return _data[index];
    }
    throw std::runtime_error("Выход за пределы диапазона");
}

Исходный файл данных(test.txt):
Код :
5
3
-5 1 4
4
-10 11 -3 -5
3
4 1 2
1
-1
6
-1 -2 -3 4 4 5

Формат исходных данных:
Количество строк. Далее перед каждой строкой количество элементов в этой строке, далее сами элементы и т.д.
Результат работы:
Код :
./185755 <test.txt 
Исходная матрица: 
  -5 1 4
  -10 11 -3 -5
  4 1 2
  -1
  -1 -2 -3 4 4 5

Вектор:
 2 4 3 0 4

Или с ручным вводом(черный - ввод пользователя, синий - вывод программы):
5
3
-5 1 4
4
-10 11 -3 -5
3
4 1 2
1
-1
6
-1 -2 -3 4 4 5
Исходная матрица:
-5 1 4
-10 11 -3 -5
4 1 2
-1
-1 -2 -3 4 4 5

Вектор:
2 4 3 0 4

Консультировал: Micren (Профессор)
Дата отправки: 05.04.2012, 22:13
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Консультирует Бизин Михаил Анатольевич (1-й класс):

Здравствуйте, Denis!
Ещё один вариант ответа (компилятор GCC C++), где используются Ваши же функции, и добавлено тело основной функции с комментариями в коде.
Также добавил функцию ввода вещественного числа, т.к. у Вас элементы матрицы - вещественные числа.
Если есть вопросы, спрашивайте.

Код :
#include <iostream>
using namespace std;

//Для задания непрямоугольной матрицы
struct Line{
  int n;
  double *ar;
//  Line *matr;
};

//Функция ввода целого числа
istream& input(int&a) {
  while(!(cin>>a)){
    if(cin.eof()) break;
    cin.clear();
    cin.ignore();
  }
  return cin;
}

//Функция ввода вещественного числа
istream& input(double&a) {
  while(!(cin>>a)){
    if(cin.eof()) break;
    cin.clear();
    cin.ignore();
  }
  return cin;
}

//Ввод количества строк
int input() {
  int n;
  const char *pr="";
  do{
    cout<<pr;
    pr="error!!!";
    cout<<"enter number of int:";
    input(n);
  } while(n<=0);
  return n;
}

//Ввод матрицы
int input(Line*&p)
{
  int m=input();
  p=new Line[m];
  for(int i=0; i<m; ++i){
    p[i].n=input();
    p[i].ar=new double[p[i].n];
    for(int j=0; j<p[i].n; ++j) input(p[i].ar[j]);
  }
  return m;
}

int main() {
  Line *a;             //Переменная для матрицы
  int m=input(a);      //Ввод матрицы, вернуть количество строк
  int *b = new int[m]; //Выделить память под вектор
  for(int k=0;k<m;k++) { //Цикл по строкам
    b[k]=a[k].n;         //Начальное значение элемента вектора для строки
    for(int i=0;i<a[k].n;i++) { //Цикл по элементам текущей строки
      int l=k+1;         //Номер следующей строки
      if (l==m) l=0;     //Последняя строка сравнивается с нулевой строкой
      for(int j=0;j<a[l].n;j++) { //Цикл по элементам следующей строки
        if (a[k].ar[i]==a[l].ar[j]) { //Если элементы совпадают,
          b[k]--;                 //значит несовпадающих на 1 меньше
          break;       //Дальше можно не смотреть, переходим к следующему элементу текущей строки
        }
      }
    }
  }
  //Вывод содержимого матрицы
  cout<<endl<<"a=";
  for (int i=0;i<m;i++) {
    cout<<endl<<"(";
    for (int j=0;j<a[i].n;j++) {
      cout<<a[i].ar[j]<<" ";
    }
    cout<<")";
  }
  cout<<endl;
  
  //Вывод содержимого вектора
  cout<<endl<<"b=(";
  for (int i=0;i<m;i++) {
    cout<<b[i]<<" ";
  }
  cout<<")"<<endl;
}


Итог работы программы с теми же исходными данными как у предыдущего ответа от Micren:
Код :
bizin:~/RFpro/185755$ ./matrix 
enter number of int:5
enter number of int:3
-5 1 4
enter number of int:4
-10 11 -3 -5
enter number of int:3
4 1 2
enter number of int:1
-1
enter number of int:6
-1 -2 -3 4 4 5

a=
(-5 1 4 )
(-10 11 -3 -5 )
(4 1 2 )
(-1 )
(-1 -2 -3 4 4 5 )

b=(2 4 3 0 4 )

Консультировал: Бизин Михаил Анатольевич (1-й класс)
Дата отправки: 06.04.2012, 07:28
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!



В избранное