Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Вопросы начинающих программистов
Перезагрузить страницу Нахождение количества элементов в двухмерном массиве
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
Charlie Rat Charlie Rat вне форума
Member
 
Сообщений: 47
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.11.2007
По умолчанию Нахождение количества элементов в двухмерном массиве - 13.12.2007, 02:35

Здравствуйте!
Прошу помощи в решении задачи.
Условие задачи:
Дан двухмерный массив размерностью 3X4. Необходимо найти количество элементов, значение которых равно нулю.

Код:
#include<iostream>
#include<stdlib.h> // в этом файле содержатся функции rand и srand
#include<time.h> // в этом файле содержится функция time

using namespace std;

void main()
{
    // задаем размерность массива
    const int a = 3;
    const int b = 4;
    int A[a][b];  // объявляем двумерный массив
int null_element;
    // заполнение массива случайными числами и показ на экран

    // перебираем отдельные строки (одномерные массивы в совокупности)
    for(int i=0; i<a; i++)
    {
        // перебираем отдельные элементы каждой строки
        for(int j=0; j<b;j++)
        {
            // инициализация элементов значениями в диапазоне от 0 до 100
            A[i][j]=rand()%100;

            // показ значений на экран
            printf("%d\t", A[i][j]);
        }
        // переход на другую строку матрицы
        cout<<"\n\n";
    }
    cout << "\n\n";

    // поиск в строках нулевого элемента

    // перебираем отдельные строки (одномерные массивы в совокупности)
    for (int i=0; i<a; i++){

        // поиск нулевого элемента в текущей строке
        null_element=A[0][0];
        // изменение индекса столбца для текущей строки
        for (int j=0; j<b; j++)  
        {
            
            if (A[i][j]=0)
                null_element=A[i][j];
        }
        }
    printf("%s%d%s", "cardinality of relation 0=", null_element, "\n");
}
Т.е. ноль программа находит, но количество нулей в массиве не считает.
Ответить с цитированием
  (#2 (permalink)) Старый
Arachnelis Arachnelis вне форума
Member
 
Сообщений: 1,324
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.07.2007
По умолчанию 13.12.2007, 02:47

Цитата:
Т.е. ноль программа находит, но количество нулей в массиве не считает.
Ну правильно, а с какой стати она должна считать?
Где здесь хоть одна операция инкремента, за исключением заголовков циклов?

Вот:
Код:
unsigned nNullCount = 0;
for ( unsigned i = 0; i < a; i++ )
{
    for ( unsigned j = 0; j < b; j++ )  
    {
        if ( A[i][j] == 0 )
            nNullCount++;
    }
}
Кстати, ошибка - в заголовке if() присваивание стояло.
Ответить с цитированием
  (#3 (permalink)) Старый
Charlie Rat Charlie Rat вне форума
Member
 
Сообщений: 47
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.11.2007
По умолчанию 13.12.2007, 03:00

А почему надо использовать беззнаковый тип?
Ответить с цитированием
  (#4 (permalink)) Старый
Charlie Rat Charlie Rat вне форума
Member
 
Сообщений: 47
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.11.2007
По умолчанию 13.12.2007, 03:04

И, если можно, второй вопрос.
Как правильно инициализировать символьный многомерный массив?
Ответить с цитированием
  (#5 (permalink)) Старый
Arachnelis Arachnelis вне форума
Member
 
Сообщений: 1,324
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.07.2007
По умолчанию 13.12.2007, 13:14

Цитата:
А почему надо использовать беззнаковый тип?
Сугубо IMHO. Не вижу смысла использовать знаковый, если значение заведомо не может быть отрицательным. Простая логика вещей.

Цитата:
Как правильно инициализировать символьный многомерный массив?
Напиши пример, поправлю ошибки, станет ясно.
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
Charlie Rat Charlie Rat вне форума
Member
 
Сообщений: 47
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.11.2007
По умолчанию 14.12.2007, 01:21

Насколько я знаю, символьный массив объявляют как char iArr[][]
Код:
#include<iostream>
#include<stdlib.h> 

using namespace std;
void main()
{
    
    char iArr[][];  
    char a;    
    scanf("%c", &a);
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m;j++)
        iArr[i][j]=a;
    }
        printf("%5c", a);
        }
Ответить с цитированием
  (#7 (permalink)) Старый
Arachnelis Arachnelis вне форума
Member
 
Сообщений: 1,324
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.07.2007
По умолчанию 14.12.2007, 13:17

Очень подробно.

Цитата:
Насколько я знаю, символьный массив объявляют как char iArr[][]
Нет, компилятор этого не допустит.

1. Создание статического многомерного массива обязательно должно содержать все размерности. Либо все явно, либо одну самую левую размерность можно опустить при условии наличия инициализатора (в этом случае компилятор посчитает размерность автоматически, но по-прежнему определит ее на этапе компиляции.

(кстати, где ты взял такой префикс - 'i'? Тогда уж, или для всех целых использовать 'n' ('noun' - целое), или для символьного - 'c', а для строки уж лучше 'cs' - 'char string'. Для массива настоятельно рекомендую добавить 'A')
Код:
char AcsFirst[][];  //- не правильно
char AcsSecond[10][10];  //- правильно
char AcsThird[n][m];  //- не правильно - 'n' и 'm' - переменные, а требуются константы
char AcsSecond[][10] = { "First", "Second", "Third" };  //- в целом правильно, но...
Последний вариант использовать нужно осторожно, я лично его не применяю вообще.

При работе со статическим массивом память под него очистит сам компилятор, когда закончится время жизни объекта (== самого массива).

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

Преимущества второго варианта:
1. Все размерности массива могут быть неизвестны на этапе компиляции (например, вводиться с клавиатуры)
2. В общем случае "столбцы" могут иметь разную длину, и это особенно полезно при создании массива строк. При статическом определении под каждую строку отводится равное число символов (в примере выше каждая из строк - "First", "Second", "Third" - будет располагаться в 10-байтовом участке).

Код:
char **AcsFirst; //- массив строк
//- вариант: char **AAFirst; //- массив массивов символов - если так будет лучше для задачи

//- количество строк:
unsigned n = 3;
Вариант А:
Код:
//- поехали выделять память:
AcsFirst = new char*[n];
for ( unsigned i=0; i<n; i++ )
{
    AcsFirst[i] = new char[10]; //- снова одна и та же длина строк
    ::strcpy( AcsFirst[i], "\\\\\" );
}
Вариант Б (хитрый):
Код:
//- определяем вспомогательную функцию
inline char* strinitcpy( const char *tcsSrc )
{    return ( tcsSrc ? ::strcpy( new char[ strlen(tcsSrc) + 1 ], tcsSrc ) : (void*)(0uL) );  }

//- поехали выделять память:
AcsFirst = new char*[n];
AcsFirst[0] = strinitcpy( "First" );  //- длина равна 6
AcsFirst[1] = strinitcpy( "The Second String" );  //- длина равна 18
AcsFirst[2] = strinitcpy( "" );  //- длина равна 1
При работе с динамическим массивом память под него требуется удалять также вручную, как и выделять. Иначе, когда закончится время жизни объекта (== указателя на массив), доступ к выделенной памяти будет потерян.
Код:
for ( unsigned i=0; i<n; i++ )
    delete[] AcsFirst[i]; //- операции 'delete[]' не важен размер выделенной памяти
delete[] AcsFirst;
Ответить с цитированием
  (#8 (permalink)) Старый
Charlie Rat Charlie Rat вне форума
Member
 
Сообщений: 47
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.11.2007
По умолчанию 15.12.2007, 01:04

Спасибо!
Будем разбираться
Ответить с цитированием
  (#9 (permalink)) Старый
Charlie Rat Charlie Rat вне форума
Member
 
Сообщений: 47
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.11.2007
По умолчанию 15.12.2007, 01:37

Вопрос следующий. Нахождение нулевого елемента в заданной области.
Например, дан массив размерностью 5х5. Если разделить диагональю заданный массивом "квадрат", то нулевое значение необходимо найти в одной из областей, ограниченных диагональю.
Изменение управляющих переменных i и j ни к чему не приводит.
Код:
// перебираем отдельные строки (одномерные массивы в совокупности)
    for (int i=0; i<a; i++){

        // поиск нулевого элемента в текущей строке
        null_element=A[0][0];
        // изменение индекса столбца для текущей строки
        for (int j=0; j<b; j++)  
        {
            
            if (A[i][j]=0)
                null_element=A[i][j];
        }
В лучшем случае вывод первого столбца.
Ответить с цитированием
  (#10 (permalink)) Старый
Arachnelis Arachnelis вне форума
Member
 
Сообщений: 1,324
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.07.2007
Lightbulb 15.12.2007, 02:25

Два уточняющих вопроса:

1. Если размерность нечетная, то должны ли диагонали:
а) включаться во все треугольники,
б) включаться по заданному правилу, например "влево-вверх",
в) исключаться из рассмотрения.

2. Требуется написать универсальный алгоритм, чтобы по заказу искал в нужном треугольнике? Или четыре алгоритма? Или как?

Две ошибки:
1. Лимиты названы разными буквами - 'a' и 'b', хотя по идее должны быть равны, иначе диагонали не нащупать.
2. Опять поставил в if() присваивание! Запомни уже:
операция СРАВНЕНИЯ на равенство записывается ДВУМЯ знаками: "=="

А вообще изменять надо не "i и j", как ты сказал - они и так изменяются - это же параметры цикла,- а их лимитирующие значения.

Например, следующая пара циклов перебирает большой треугольник - верхнюю правую половину квадрата:
Код:
for ( int i = 0; i < N; i++ )
{
    for ( int j = i; j < N; j++ )
    {
        if ( A[i][j] == 0 )
            ...
    }
}
Параметр 'j' в каждой итерации внешнего цикла имеет разные диапазоны, т.к. его стартовым значением является не константа, а параметр внешнего цикла 'i'.
Ответить с цитированием
  (#11 (permalink)) Старый
Charlie Rat Charlie Rat вне форума
Member
 
Сообщений: 47
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.11.2007
По умолчанию 15.12.2007, 03:10

Вообще задач десять. Суть в следующем. Массив как бы разбивается двумя диагоналями.
Неоходимо находить нулевое значение в следующих областях:
1 и 2 - Диагональ с верхнего левого угла к нижнему правому - в области ниже диагонали и в области выше диагонали. Точки, лежащие на диагонали включаются в область поиска.
3 - 5 - если провести сразу две диагонали, то они разобъют область на четыре части. Ищем сначала в верхней, затем - в нижней, и наконец, в обоих сразу.
6 - 8 задачи - тоже что и 3-5, только берутся левый и правый треугольники.
9, 10 задачи - Диагональ с верхнего правого угла к нижнему левому - в области ниже диагонали и в области выше диагонали. Точки, лежащие на диагонали включаются в область поиска.
Ответить с цитированием
  (#12 (permalink)) Старый
Arachnelis Arachnelis вне форума
Member
 
Сообщений: 1,324
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.07.2007
Post 16.12.2007, 02:16

Дааааауж... Сам-то всё понял?
Цитата:
1 и 2 - Диагональ с верхнего левого угла к нижнему правому - в областИ ниже диагонали и в областИ выше диагонали. Точки, лежащие на диагонали включаются в областЬ поиска.
Ну и как это все сопоставить? Несколько областей выше (толи совпадают, толи расположены в параллельных вселенных), и несколько - ниже. А диагональ включить в областЬ. В любую наугад? Или это некая кашерная область, которая важна как манна небесная, и о ней даже вслух не говорят?

Цитата:
3 - 5 - если провести сразу две диагонали, то они разобъют область на четыре части.
Ищем сначала в верхней, затем - в нижней, и наконец, в обоих сразу.
Тоже неплохо... Ну ладно, тут хоть можно догадаться, что потом ищем в "верхней + нижней".
Но про диагонали так и не сказано!

Ладно, порешаю на днях хоть как-нибудь...
Ответить с цитированием
Ads
  (#13 (permalink)) Старый
Charlie Rat Charlie Rat вне форума
Member
 
Сообщений: 47
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 09.11.2007
По умолчанию 16.12.2007, 21:05

Хорошо. Представим задачу с точки зрения геометрии.
Имеется квадрат с вершинами ABCD (А - верхняя левая вершина). Из вершины А проведена диагональ к вершине С и из вершины В проведена диагональ к вершине D. Точкой пересечения диагоналей будет, например, точка О. Применительно к задаче необходимо найти мах в областях, ограниченных треугольниками: ABC, ACD, AOB, DOC, AOB и DOC одновременно, AOD и BOC одновременно, AOD, BOC, BAD, BCD. Надеюсь это будет более понятно. Достаточно просто начертить квадрат и провести диагонали.
Ответить с цитированием
  (#14 (permalink)) Старый
Arachnelis Arachnelis вне форума
Member
 
Сообщений: 1,324
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.07.2007
По умолчанию 21.12.2007, 16:47

Разобрался с условием, изложено было кривовато (а может, в тот день тормозил).

Пишу только циклы перебора, содержимое поставишь.
'nSize' - размер матрицы,
'nHalf' - полуразмер с включенной диагональю:
Код:
const unsigned nHalf = nSize / 2;
Итак, см.следующий пост. (надеюсь, нигде в решении не ошибся)

-

Кстати, насчет использования беззнаковых переменных.
При адресации массива в [] используется значение 'unsigned' (либо 'unsigned long long' на 64-разрядных платформах), поэтому, если счетчик цикла - int, то происходит приведение типа на каждой конструкции a[i]. В реальных проектах для индексирующих переменных и их экстремумов используют тип 'std::size_t', который определяется как раз так, т.е.:
Код:
size_t nSize = 10;
const size_t nHalf = nSize / 2;
for ( size_t i = 0; i < nSize; i++ )
{
    const size_t nTmp = (  i <= nHalf  ?  i  :  nSize - i );
    for ( size_t j = nTmp; j < nSize - nTmp; j++ )
    {
    }
}
Ответить с цитированием
  (#15 (permalink)) Старый
Arachnelis Arachnelis вне форума
Member
 
Сообщений: 1,324
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.07.2007
По умолчанию 21.12.2007, 16:47

Разобрался с условием, изложено было кривовато (а может, в тот день тормозил).

Пишу только циклы перебора, содержимое поставишь.
'nSize' - размер матрицы,
'nHalf' - полуразмер с включенной диагональю:
Код:
const unsigned nHalf = nSize / 2;
Итак, см.следующий пост. (надеюсь, нигде в решении не ошибся)

-

Кстати, насчет использования беззнаковых переменных.
При адресации массива в [] используется значение 'unsigned' (либо 'unsigned long long' на 64-разрядных платформах), поэтому, если счетчик цикла - int, то происходит приведение типа на каждой конструкции a[i]. В реальных проектах для индексирующих переменных и их экстремумов используют тип 'std::size_t', который определяется как раз так, т.е.:
Код:
size_t nSize = 10;
const size_t nHalf = nSize / 2;
for ( size_t i = 0; i < nSize; i++ )
{
    const size_t nTmp = (  i <= nHalf  ?  i  :  nSize - i );
    for ( size_t j = nTmp; j < nSize - nTmp; j++ )
    {
    }
}
Ответить с цитированием
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
подсчет количества элементов James007Bond Prolog 9 20.09.2012 20:07
Нахождение максимального элемента в двумерном массиве kaffetka1841 Assembler 0 12.12.2009 21:30
Значение cin.get() в двухмерном char массиве felixb Вопросы начинающих программистов 35 24.12.2007 15:15
Пары элементов в массиве Hardip Pascal 3 01.05.2007 18:12
Определение количества положительных элементов в С++ ThunderStorm Вопросы начинающих программистов 2 21.05.2006 17:42
Подсчет количества четных элементов массива в C++ miss melody Вопросы начинающих программистов 2 16.05.2006 13:55
Нахождение количества отрицательных или простых чисел в матрице прямоугольной lector C++ Builder 5 30.03.2006 23:19
Подсчет количества вхождений каждого символа во входном массиве Dian Visual C++ 5 25.12.2005 07:46
Нахождение количества диагоналей в квадратной матрице ZeroWolf Вопросы начинающих программистов 19 29.11.2005 18:20
Как посчитать количество элементов в массиве структур atomsk С/С++ 5 14.06.2005 04:35
Как в двухмерном массиве указателей определить номер строки и столбца элемента Anonymous Visual C++ 1 06.10.2003 11:34
Нахождение и вывод последовательных неодинаковых чисел в массиве Anonymous Вопросы начинающих программистов 2 23.03.2003 09:08



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов