поиск элемента в двумерном динамическом массиве на C++

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
настя_87
Сообщения: 10
Зарегистрирован: 17 дек 2009, 15:38

пробую создать программу ,находящую в двумерном целочисленном динамическом массиве заданный с клавиатуры элемент,размерность массива тоже задается с клавиатуры(N,M)
массив в памяти размещен динамически (с помощью new,delete)
ввод исходных данных и вывод полученных результатов выполнить в основной функции,а решение задачи оформить в виде отдельной функции,не использовать глобальных переменных...

вот код того ,что я сделала:

Код: Выделить всё

#include <iostream.h>
#include <stdio.h>

using namespace std;
void poisk_elementa(int n,int m,int a[n][m],int c,int g)
{int i,j;
int b[n][m];
a[n][m]=b[n][m];
for (int i=1;i<n;i++)
        for(int j=1;j<m;j++){
        if (b[i][j]==c)
        g=1;
        else
        g=0;

 }
}


int main()
{
int n,m,c,g=-1;
cout<<"Vvedite razmer 2-umernogo massiva\n";
cin>>n>>m;
int *a=new int[n,m];
cout<<"Vvedite elementi massiva!!\n";
for (int i=0;i<n;i++)
        for(int j=0;j<m;j++)
cin >> a[i][j];
cout<<"Vvedite element dlya poiska\n";
cin>>c;
poisk_elementa(n,m,int a[n][m],int c);
if (g==1)
        cout<<"element naiden!!!\n";
else
        cout<<"element ne naiden!!!\n";
delete a;
return 0;}
уже совсем запуталась,проблема с массивами,скорее всего не правльно объявлены...помогите плз,очень интересно просто :rolleyes:
1nclude
Сообщения: 22
Зарегистрирован: 14 дек 2009, 10:15

Тут проблема далеко не только с массивами Настя...)) Кто ж это Вас учил имена функций и переменных транслитом писать? ))

Значит так, давайте разберёмся что такое массив. Массив это некая область памяти; Резервируется компилятором во время объявления, то есть :

Код: Выделить всё

T array[size];


- встретив такое в исходном коде компилятор выделяет область памяти достаточную для размещения size элементов типа T. Именно потому что выделение памяти для такого массива происходит во время компиляции, size массива должен быть константным значением.
Важно понимать что имя массива есть указатель на первый(то есть нулевой) его элемент. Казалось бы вот безнадёга - а что делать когда заранее неизвестно сколько мы элементов будем хранить в этом массиве?
На такой случай в С++ предусмотренны средства для динамического выделения памяти, то есть во время выполнения.
Чтобы получить массив элементов типа T размером N полученным в runtime откуда то,надо проделать следующие телодвижения:

Код: Выделить всё

T* array = new T[N]; // массив элементов типа T размера N
А итерироваться по элементам такого массива можно например вот так:

Код: Выделить всё

for(int i=0;i<N;++i)
{
array+i; //Это альтернативная запись array[i];
}  


Двумерный массив это массив указателей на массивы,
то есть это массив каждый элемент которого тоже является массивом(помним что имя массива есть указатель на его первый(нулевой) элемент).
Самый очевидный пример двумерного массива это массив строк.

Что такое строка? В простейшем случае это обычный массив элементов типа char, и создаётся он динамически точно так же как и массив любого другого типа:

Код: Выделить всё

char* string = new char[N];
А как же создать массив строк? Помня что строка это char* создаём:

Код: Выделить всё

/*
Создаём массив размером N каждый елемент которого char*
*/
char** string_array = new char*[N];


"Ух ты как просто!" - скажете Вы и будете неправы. Да, мы создали массив указателей на char. Но указатели эти неинициализированны, а обращение по неинициализированному указателю ведёт к разным нехорошим последствием - от GPF до порчи чужих данных;
Следовательно надо их инициализировать,вот таким вот образом:

Код: Выделить всё

for(int i=0;i<N;++i)
{
/*
N указателей на char инициализируются массивами типа char 
длинной L
*/
string_array[i] = new char[L]; 
}
Вот теперь всё, у нас есть двумерный массив элементов типа char NxL;
Соответственно таким же образом можно создать двумерный массив для любого типа данных.Кстати, после окончания работы с памятью выделенной динамически, её необходимо освободить. В C++ это делается так:

Код: Выделить всё

/*
Освобождаем память, ранее выделенную под массив;
*/
delete[] array;

Код: Выделить всё

/*
Освобождаем память, ранее выделенную под двумерный массив
*/
for(int i=0;i<N;++i)
{
delete[] string_array[i]; //Сначала для каждого массива в массиве ;)
}

delete[] string_array; //А затем и для самого массива
Поиск элемента в массиве. Элементарно пробегаем каждый массив в нашем массиве(помним что каждый элемент нашего массива тоже массив) сравнивая каждый элемент с заданным K:

Код: Выделить всё

for(int i=0;i<N;++i)
{
     for(int j=0;j<L;++j)
         {
              if(string_array[i][j] == K)
                {
cout<<"Искомый элемент найден в позиции "<<'['<<i<<','<<j<<']'<<endl;
                }
         }
}
1nclude
Сообщения: 22
Зарегистрирован: 14 дек 2009, 10:15

В Вашем случае текст программы мог бы выглядеть например так:

Код: Выделить всё

/*
Простенькая функция для проверки корректности входных данных
*/
bool check_input(istream &stream,int &var) 
  {
  while(!(stream >> var))
    {
    cerr << "Ошибка ввода!" << endl; 
    stream.clear();
    stream.ignore(256,'\n');
    return false;
    }
  return true;
  }

void search(int** array,int N,int L,int K) //Наша функция поиска
{
    /*
    Ищем K
    */
    for(int i = 0; i < N; ++i)
        {
        for(int j=0; j < L; ++j)
            {
              if(array[i][j] == K)
                {
cout<<"Искомый элемент найден в позиции "<<'['<<i<<','<<j<<']'<<endl;
                }
            }
        }
}

int main()
{
    setlocale(LC_ALL,"rus"); //Что бы печатать по человечески ;)

    int N = 0, L = 0, K = 0;   //Это спрашиваем у пользователя

    /*
    Смотрим что бы N ,было корректным числом > 0 
    */
    do{
     cout << "Введите N:";
     }
     while(!check_input(cin,N) || N <= 0);

      /*
      То же самое для L 
      */
      do{
     cout << "Введите L:";
     }
     while(!check_input(cin,L) || L <= 0);

     int** array = new int*[N]; //создаём массив указателей на int

     for(int i=0;i<N;++i)
     {
   array[i] = new int[L]; //инициализируем указатели массивом размера L
     }

     /*
     Заполняем массив тем что пользователь введёт :) 
     */
     for(int i = 0; i < N; ++i)
     {      
     for(int j = 0; j < L; ++j)
       {
       do{
          cout << "Введите значение элемента [" << i << ',' << j << "] :";
           }
       while(!check_input(cin,array[i][j]));            
        }     
      }

     /*
     Теперь просим пользователя ввести искомое K
    */
     do{
     cout << endl << "Введите значение K:";
      }
   while(!check_input(cin,K));

   search(array,N,L,K);
    
   /*
   Освобождаем выделенную ранее память
   */
   for(int i = 0; i < N; ++i)
   {
    delete[] array[i]; 
   }   
   delete[] array;
}
Ну вот собственно и всё. Надеюсь разжевал понятно. Удачи Вам. :)
настя_87
Сообщения: 10
Зарегистрирован: 17 дек 2009, 15:38

спасибо большое =)
просто я с C++ знакомлюсь сама =) некому научить =) вот чему за 3 дня научилась =)то и написала %)
спасибо большое человеческое :)
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
хм =) товарищ инклуд,вы такой умный,может смогли бы также мне подсказать,если вам не трудно,
каким образом можно выполнить такую задачу....необходимо ввести массив чисел и реализовать функцию которая во второй массив записывает все числа 1-ого массива,сумма цифр в десятичном изображении которых кратна трем.элементами массива могут быть или короткие, или длинные целые числа
я помнила проверку кратности...но думаю мой код вам мало чем поможет,судя из предыдущих постов :rolleyes:
извините за назойливость =(
1nclude
Сообщения: 22
Зарегистрирован: 14 дек 2009, 10:15

Если я правильно понял условие задачи то текст программы может выглядеть например так:

Код: Выделить всё

/*
Простенькая шаблонная функция для проверки входных данных
*/
template<typename T> 
bool check_input(istream &stream,T &var)
  {
  while(!(stream >> var))
    {
    cerr << "Ошибка ввода!" << endl; 
    stream.clear();
    stream.ignore(256,'\n');
    return false;
    }
  return true;
  }

/*
Функция которая обрабатывает исходный масив, 
в соответствии с условием задачи
long int array[] - наш исходный массив
int size_of_array - его размер
*/
void array_handler(long int array[],int size_of_array) 
  {
    //Массив для чисел сумма разрядов которых кратна 3 
    long int* second_array = new long int[size_of_array];

    //Счётчик элементов этого массива 
    int   size_of_second_array = 0; 
  
    //Этим счётчиком двигаемся по разрядам числа              
    long int  counter = 0; 

    //Здесь будут промежуточные результаты вычислений                 
    long int  tmp = 0;                                         
    
    for(int i = 0; i < size_of_array; ++i)
      {
      counter = array[i];         //получим i-тый элемент входного массива
      do
        {
          // Двигаемся по числу от младшего к старшему разряду
          // складывая их,
          tmp += (counter % 10); 
          // переменная tmp в конечном счёте содержит сумму всех 
          // разрядов
          counter /= 10;                                
        }
        while( counter != 0 );   //Пока не закончились разряды

        if((tmp%3) == 0)      //Если сумма разрядов числа кратна 3
          {
          //Запишем это число в наш массив
          second_array[size_of_second_array] = array[i];
         // и увеличим счётчик элементов
          ++size_of_second_array;                        
          }
        tmp = 0;   // обнулим переменную для промежуточный результатов
      }

    cout << "Содержимое второго массива: ";
    for(int i = 0; i < size_of_second_array; ++i)
      {
      cout << second_array[i] << '  ';
      }

      delete[] second_array; //освободим выделенную ранее память
  }

int main()
{   
  setlocale(LC_ALL,"rus");

  int size_of_array = 0;
  
  do
    {
    cout << "Введите размер массива:";
    }
    while(!check_input<int>(cin,size_of_array)|| size_of_array <= 0);

    //Наш исходный массив
    long int* array = new long int[size_of_array];
    
    for(int i = 0;i < size_of_array;++i)
      {
      do
        {
        cout << "Введите элемент массива [" << i << "]:";
        }
        while(!check_input<long>(cin,array[i]));
      }

    cout << "Исходный массив: ";

    for(int i = 0; i < size_of_array; ++i)
      {
      cout << array[i] << ' ';
      }

    cout << endl;

    array_handler(array,size_of_array);
    
    //Здесь конечно можно вообще про delete забыть, но не будем :)
    delete[] array;

    return 0;
}
Вот как то так. :)
настя_87
Сообщения: 10
Зарегистрирован: 17 дек 2009, 15:38

даааа =)
ну вы наверно где-то преподаете %)
знаете пипец хорошо %)
обалдеть можно просто =)
была 1 ошибка,я её исправила
но в общем пипец здорово =)а главное как будто лекцию посидела на курсах =)
спасибо огромнейшее ;)
1nclude
Сообщения: 22
Зарегистрирован: 14 дек 2009, 10:15

А, ну да...вот тут - cout << second_array << ' '; - ошибка, слишком дофига пробелов понаставил..)
настя_87
Сообщения: 10
Зарегистрирован: 17 дек 2009, 15:38

блин извиняюсь =) я потеря,знаю
товарищ инклуд,может спасете меня ещё раз,а то остальные все молчат :
Для каждого x, изменяющегося от a до b с шагом h, найти значения функции Y(x), суммы S(x)=((-1)^k)*(x^(2k+1)/(2k+1)!) при (k=o;k<=n;k++) и |Y(x)–S(x)| и вывести в виде таблицы. Значения a, b, h и n вводятся с клавиатуры.
умоляю помогите исправить код,у меня уже голова взрывается...

Код: Выделить всё

#include <iostream.h>
#include <math.h>
#include <Math.hpp>

using namespace std;
unsigned long fact(unsigned long n)
{
if (n <= 1)
return 1;
else
return n * fact(n - 1);
}

int main()
{double a=0,b=0,h=0,n=0,k=0,m=1,x=0,s=0,z=0,l;
cout<<"Vvedite neobhodimie dlya reweniya elementi...\n";
cout<<"a:"<<endl;
cin>>a;
cout<<"b:"<<endl;
cin>>b;
cout<<"h:"<<endl;
cin>>h;
cout<<"n:"<<endl;
cin>>n;
x = a;
do
{
m=2*k+1;
 s+=pow(-1,k)*pow(x,(2*k+1))/fact(m);
  double y = sin(x);
  z=fabs(y-s);
  cout<< "sin(x)     =    | "<< y << endl;
  cout<< "s(x)      =     | "<< s << endl;
  cout<< "|s(x)-sin(x)| = | "<< z <<endl;
  cout<<"------------------------------------------"<<endl;
  x += h;
  k++;

}
while ((x <= b)&&(k < n));
cin>>l;
return 0;}
формула суммы,вернее сама сумма совсем не равна синусу,оч прошу подскажете что же я сделала не так???
заранее спасибо
у меня уже нервы кончились... :mad:
licenok
Сообщения: 14
Зарегистрирован: 25 авг 2010, 17:08

эт Настя сама с собой общается ??
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Она общалась с господином 1nclude, который был впоследствии забанен и все его сообщения были автоматически удалены. Обычные пользователи не видят удалёных сообщение, посему создалась видимость монолога.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить