Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создать класс с динамическим двумерным массивом, конструктор копирования... 
V
    Опции темы
Recev
  Дата 4.12.2010, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 18.10.2010

Репутация: нет
Всего: нет



Нужно создать класс в котором будут такие поля:
Динамический двумерный массив 
Размер массива
И такие методы:
Конструктор по умолчанию
Конструктор с параметрами
Конструктор копирования
Деструктор ввода значений элементов массива
Вывод массива
Обработка массива: отсортировать элементы массива методом выбора.
 smile 
Как такое сделать?
Помогите! Или хотя-бы в двух словах напишите что и как.

 smile 
PM MAIL   Вверх
Чoо
Дата 4.12.2010, 18:55 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



Recev, вот рыба:
Код

struct d_array{
    int **a, //массив
        n,
        m;
    //конструктор по умолчанию
    d_array() {
        //инструкции по выделению памяти
    }
    d_array(const int x, const int y) //сообщаем размер массива
    {
        //инструкции по выделению памяти (столько, сколько просят в x и y
    }
    //конструктор копирования
    d_array(const d_array &p)
    {
        //инструкции по выделению памяти для a, ориентируясь на p.n, p.m
    }
    
    //метод сортировки
    void sort()
    {
        //сортируем так же, как и обычный динамический двумерный массив
    }
    
    //деструктор
    ~d_array()
    {
        delete []a;
    } 
};


Реализацией занимайтесь сами ;).
Если непонятно, читайте чем отличается класс от структуры (подскажу, что по сути ни чем, кроме умалчиваемого уровня доступа), потом начальные сведения о классах, далее, что должен делать конструктор копирования smile


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
Recev
  Дата 4.12.2010, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 18.10.2010

Репутация: нет
Всего: нет



Цитата(Чoо @ 4.12.2010,  18:55)
Recev, вот рыба:
Код

struct d_array{
    int **a, //массив
        n,
        m;
    //конструктор по умолчанию
    d_array() {
        //инструкции по выделению памяти
    }
    d_array(const int x, const int y) //сообщаем размер массива
    {
        //инструкции по выделению памяти (столько, сколько просят в x и y
    }
    //конструктор копирования
    d_array(const d_array &p)
    {
        //инструкции по выделению памяти для a, ориентируясь на p.n, p.m
    }
    
    //метод сортировки
    void sort()
    {
        //сортируем так же, как и обычный динамический двумерный массив
    }
    
    //деструктор
    ~d_array()
    {
        delete []a;
    } 
};


Реализацией занимайтесь сами ;).
Если непонятно, читайте чем отличается класс от структуры (подскажу, что по сути ни чем, кроме умалчиваемого уровня доступа), потом начальные сведения о классах, далее, что должен делать конструктор копирования smile

Просветите как выделить память под этот массив в конструкторе по умолчанию и конструкторе копирования.

Добавлено через 4 минуты и 44 секунды
А также в конструкторе с параметрами.

PM MAIL   Вверх
Чoо
Дата 4.12.2010, 20:55 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



Recev, 
с двумерным массивом можно работать как с одномерным. Следовательно можно написать так:
Код

    int M = 3, N = 3, i, j;
    int **m;
    m = new int*[M*N];
    //заполняем массив
    int c = 0;
    for(i = 0; i < M; i++)
        for(j = 0; j<N; j++, c++)
            m[i*N+j] = new int(c);

    //вывод массива:
    for(i = 0;i<M;i++)
    {
        for(j = 0; j < N; j++)
            printf("%d  ", *m[i*N+j]);
        printf("\n");
    }


Добавлено через 4 минуты и 13 секунд
следовательно в конструкторе по-умолчанию можно определить какие-нибудь значение для размерности М и N. 
В конструкторе с параметрами эти значения брать из d_array(const int x, const int y) , а конкретней из х и у. 
в констуркторе копирования размерность определять по p.n, p.m, а значения брать из p.a

Добавлено через 12 минут и 14 секунд
p.s. Может я ошибаюсь, конечно, ведь **p - это указатель на указатель, следовательно, мы определяем его как одномерный, а потом еще инициализируем память для каждой ячейки. 
Честно говоря, другого способа создавать двумерные динамические массивы в памяти я не знаю.

Добавлено через 12 минут и 54 секунды
**p - это я в общем смысле про такое объявление


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
Recev
  Дата 4.12.2010, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 18.10.2010

Репутация: нет
Всего: нет



Вот написал какой-то бред:
Код

#include <conio.h>
#include <iostream>

using namespace std;

class mass{
    int **mas, 
        i,
        j;
    public:

    mass() {
    int M=0, N=0;          
    mas = new int*[M*N];  
    }
    mass(const int x, const int y)
    {
    int i1, j1;
    i=x;
    j=y;
    mas = new int*[i*j];
    for(i1 = 0; i1 < i; i1++){
     for(j1 = 0; j1 < j; j1++)
     {
      cin>>mas[i1][j1]; cout<<endl;
      }}}

    mass(const mass &p)
    {
 
    }
    
 
    void sort()
    {
        
    }
    
    void printm()
    {
     cout<<"Massiv ["<<i<<"]["<<j<<"]: "<<endl;
     for (int i1=0; i1<i; i1++){ 
      for (int j1=0; j1<j; j1++)
       {
        if (i1==i)
        cout<<mas[i1][j1]<<"\n";
        else
        cout<<mas[i1][j1]<<" ";}
         }    
         }
    

    ~mass()
    {
        delete []mas;
    } 
};  

int main()
{
 int r;
 cout<<"Input razmer: ";
 cin>>r;
 mass m1(r,r);
 m1.printm(); 
 getch();
 return 0;
}


Поправите плиз.

 

PM MAIL   Вверх
toxx
Дата 4.12.2010, 22:52 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



какой смысл в этом?
Код

 mass() {
    int M=0, N=0;          
    mas = new int*[M*N];  
    }

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

mass(const int x, const int y)
    {
    int i1, j1;
    i=x;
    j=y;
    mas = new int*[i*j];
    for(i1 = 0; i1 < i; i1++){
     for(j1 = 0; j1 < j; j1++)
     {
      cin>>mas[i1][j1]; cout<<endl;
      }}}

Да, и отформатируйте код, он нечитаем..
PM MAIL   Вверх
Чoо
Дата 4.12.2010, 23:38 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



Код

    mass() {
    int M=0, N=0;          
    mas = new int*[M*N];  
    }

зачем выделять память с параметром 0? 
вместо этого можно:
Код

    mass() {
    int M=0, N=0;  
    mas = 0;

но тут вопрос, зачем нам тогда индесы i,j в привате? Следовательно, нужно так:
Код

  i =0; j=0; mas = 0;


вообще все имена переменных делаем по вкусу.  Далее буду писать в контексте того, как вы интерпретировали рыбу.

Далее. 18 строка. В принципе не нужно объявлять переменные, которые будут только использоваться в циклах 22й и 23й строки. Вместо этого их можно определить в инструкции for:
Код

    for(int i1 = 0; i1 < i; i1++)
    {
         for(int j1 = 0; j1 < j; j1++)
             
    }


Потом смотрим что в цикле. 25 строка: поскольку мы работаем с массивом как с одномерным, то нельзя к нему обращаться как мы это делали в статических двумерных массивах (тоесть [индексА][индексБ]). Если это сильно необходимо, то нужно перегружать оператор [][]. Возни много.
Но. Даже если бы это и было возможно, то вы записываете по адресу, память по которому еще не выделена, какие-то числа. Так делать нельзя.
Значит вместо [][] используем, как я писал выше
Код

m[i1*j+j1]

вообще мне трудно, когда имена переменных одинаковые, а отличаются только циферкой на конце smile, но ладно.
Если вы вместо имен переменных на каждой интерации цикла будете подставлять фактические значения переменных, то вы поймете, что вы последовательно с [0] по [8] элементы записываете какие-то данные. Это не трудно. 

замечание по стилю:
Код

      cin>>mas[i1][j1]; cout<<endl;
      }}}

мне ужасно лень считать закрывающие скобки. Используйте форматирование. Самому же проще будет ориентироваться. 

Так вот. Нам надо сначала выделить память, а потом уже записывать в нее какие-либо данные, итак имеем:
Код

    for(int i1 = 0; i1 < i; i1++)
         for(int j1 = 0; j1 < j; j1++)
        {
             int c;
             cin >>c;
             m[i1*j+j1] = new int(c); //выделяем и сразу инициализируем
        }

endl выводить не надо, так как после ввода цифры, курсор и так перейдет на новую строку.

Впринципе, теперь вы должны понять, если внимательно прочли, где ошибки в printm  и сможете их исправить самостоятельно.

Замечание по классу:
методы можно выносить за пределы объявления классов. Если их определение (реализация) большое, то логичней их вынести, что бы улучшить читаемость класса.
void printm () можно вынести так:
Код

void mass::printm()
{
  /*реализация*/
}


и еще одно замечание:
mass(const int x, const int y)
это конструктор инициализации. он не предназначен, для вбивания данных. А предназначен для инициализации объекта данными, которые ему передают при определении объекта:
Код

int main
{
  mass a(100,500);
  return 0;
}

соответственно, конструктору требуется выделить 100 * 500 ячеек памяти для a.mas и запомнить эти значения. Может быть, еще понадобится заполнить эти ячейки нулями. Это по желанию. Но вбивать данные в конструкторе... нет.. 
Что бы забить данные, делайте еще метод add, например. Можно и в методе вбивать данные, а можно "вбитие" оставить в main, тогда нам еще понадобится хранить текущие индексы.
Еще надо будет создать деструктор, что бы освободить память, но это потом. 
Если матеирал ООП кажется вам трудным, поищите книгу Бондарева "Самоучитель С++". Я по ней язык только третью неделю изучаю, всё толково расписано. До этого с си и с++ вообще не был знаком.

Добавлено через 1 минуту и 47 секунд
Цитата(toxx @  4.12.2010,  22:52 Найти цитируемый пост)
и не нужно плодить лишние переменные

i,j - это приватные поля класса. В них хранится размерность массива. В конструкторе надо сохранить эти данные.

Добавлено через 4 минуты и 32 секунды
кстати я не случайно использовал struct, вместо class. Как я писал выше, по суте и то и то класс. Они не имеют отличий, кроме политики доступа по-умолчанию. 
Если уж так, сделали, и планируете работать с классом не только с использованием его методов, то надо сделать методы, которые будут возвращать размерность массива и при необходимости создавать копию самого массива.


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
toxx
Дата 5.12.2010, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



Код

i,j - это приватные поля класса. 

ясное дело что это, но я хотел чтоб ТС сам до этого дошел и сделал инициализацию и выделение памяти в одном конструкторе.
PM MAIL   Вверх
Чoо
Дата 5.12.2010, 01:13 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



ТС старается выполнить задание, это радует smile. 
кстати вот, ради интереса набросал конструктор инициализации (просто с двумерными массивами в классах не работал, а тут захотелось попробовать), ну и для демонстрации пришлось написать метод show. Получилось неплохо, для первого раза:
Код

#include <stdio.h>
#include <stdarg.h>

class array{
    int **a;
    int N,M; //размерность
public:
    array() {a = 0; N = M =0;}
    array(const int line,const int column, ...);
    void show();
};
array::array(const int line, const int column, ...)
{
    N = line;
    M = column;
    va_list ap;
    va_start(ap,column);
    a = new int*[N*M];
    /*заполняем*/
    for(int i=0; i<N; ++i)
        for(int j=0; j<M; ++j)
            a[i*M+j] = new int(va_arg(ap,int));
    va_end(ap);
}
void array::show()
{
    for(int i=0; i<N; ++i)
    {
        for(int j=0; j<M; ++j)
            printf("%4d",*a[i*M+j]);
        printf("\n");
    }
}

int main()
{
    array a(3,4,1,2,3,4,5,6,7,8,9,10,11,12);
    a.show();
}


По идее бы и деструктор бы нужен, но это будет уже  почти решением задания smile

Добавлено через 2 минуты и 13 секунд
да и проверку бы в конструктор не мешало бы включить smile. Но направление должно быть понятно. Нету цели обрабатывать ошибочные данные. Не контрольная ж smile


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
toxx
Дата 5.12.2010, 01:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



Чoо
Раз уж у нас классы, то для красоты можно было бы перегрузить операторы ввода вывода smile 

Это сообщение отредактировал(а) toxx - 5.12.2010, 01:26
PM MAIL   Вверх
Чoо
Дата 5.12.2010, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



toxx, честно говоря, не вижу, что бы тут можно было перегрузить smile


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
toxx
Дата 5.12.2010, 01:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



operator>>, <<  smile 
PM MAIL   Вверх
Чoо
Дата 5.12.2010, 01:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 22.9.2009

Репутация: 4
Всего: 4



toxx, ааа. Ну вообще да, но именно что только для краосты smile


--------------------
user posted image

OS: Debian Squeeze (kernel 3.8.2)
IDE: qtCreator 1.3.1; Eclipse SDK 3.5.2
PM MAIL   Вверх
toxx
Дата 5.12.2010, 01:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



Чoо
да именно для красоты, главное правило проектирования не делать того чего не просят =)
PM MAIL   Вверх
Recev
  Дата 5.12.2010, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 18.10.2010

Репутация: нет
Всего: нет



Написал сортировку элементов массива методом выбора:

Код

#include <iostream.h>
#include <conio.h>

int main()
{
int mas[4][4];
int i,j,maxj,minel,min_i,temp;
for (i=0;i<4;i++)
{
for (j=0;j<4;j++)
{
mas[i][j] = rand() % 10;    
cout << mas[i][j]<<" "; 
    } 
 cout<<"\n";   
    } 
 i=0; j=0; 
   minel=mas[i][j];
for (i=0;i<4;i++)   
{ for (j=0;j<4;j++) 
{ if (mas[i][j]<minel)
{
minel=mas[i][j];
maxj=j;                    
     }  else {}  
    }}
cout << "\nMin elem = " << minel;              
cout << "; Stolbec = " << maxj<<endl; 
for(i = 0; i <4-1;++i)
{
  min_i = i;
  for (int i1=i+1; i1<4;++i1)
  {
      if (mas[i1][maxj] < mas[min_i][maxj]){
         min_i = i1;  } }
temp = mas[i][maxj];
mas[i][maxj] = mas[min_i][maxj];                               
mas[min_i][maxj] = temp; }
cout << "Ryadok: "<<endl;           
for (i=0;i<4;i++)
{
  cout <<mas[i][maxj]<<"\n";   
    }            
                                      
getch();   
return 0;
}



А как обращаться к массиву в моем случае? В классе идет mas[i1*j+j1], а я умею оперировать только с mas[i][j].
Вообщем нужно эту программу сделать методом моего класса.

Добавлено через 6 минут и 10 секунд
PS
Алгоритм метода выбора:
Находим минимальное значение (пусть это первый элемент массива), выполняем перемещение этого значения на место того значения, которое стоит на первой не отсортированной  позиции. Продолжаем сортировку.

user posted image
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0639 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.