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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Массив из диапозона чисел 
V
    Опции темы
JAYBE
Дата 11.1.2013, 10:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Добрый день!
Помогите, пожалуйста, с задачей:  Задан числовой массив А[1:m, 1:n]. Составить программу поиска элемента массива, который является наибольшим из отрицательных чисел расположенных в строках.
Мой код:
Код

#include <iostream>
#include <stdlib.h>
using namespace std;

int main()
{
    int m, n, start_random, end_random, min, rnd;
    cout << "Enter length of array: ";
    cin >> m;
    cout << "Enter height of array: ";
    cin >> n;
    int array[m][n];
    srand(time(0));
    cout << "Enter start of random:";
    cin >> start_random;
    start_random+=1;
    cout << "Enter start of random:";
    cin >> end_random;
    end_random-=start_random;
    cout << "Sgenerirovanniy massiv:\n";
    for (int i=0; i<m; i++) {
        for (int y=0; y<n; y++) {
            cout << (array[i][y] = rand()%11-5) << ' ';
            //cout << rand()%10-5 << ' ';
        }
        cout << endl;
    }
    min = array[0][0];
    for (int i=0; i<m; i++) {
        for (int y=0; y<n; y++) {
            if (min>array[i][y]) {
                min = array[i][y];
            }
        }
    }
    cout << "Minimalnoe chilslo: " << min << endl;
    return 0;
}


Возникает 2 вопроса.
1) Как сделать рандомный массив из дапозона, причем 
Код

array[i][y] = rand()%start_random-end_random/start_random
 работает некорректно... Скажем если необходим диапозон от -10 до 15.
2) У меня циклы 2 раза "пробегают". 1 раз при создании массив и 2-ой раз при поиске минимального элемента. Как-то можно их оптимизировать с точки зрения алгоритма в один?
PM   Вверх
bsa
Дата 11.1.2013, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(JAYBE @  11.1.2013,  11:16 Найти цитируемый пост)
Как сделать рандомный массив из дапозона

легко: x ∈ [-10;15] -> y ∈ [0;25], где x = (y - 10) -> y = random * 25 / RAND_MAX, где random ∈ [0;RAND_MAX]:
y = (int)(25 * (rand()/(double)RAND_MAX) + 0.5);
x = y - 10;
PM   Вверх
feodorv
Дата 11.1.2013, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(JAYBE @  11.1.2013,  11:16 Найти цитируемый пост)
Как-то можно их оптимизировать с точки зрения алгоритма в один? 

Можно, но смысла особого не имеет. Это две разные подзадачи:
  • инициализация элементов массива
  • поиск особого элемента в матрице
которые могут быть реализованы как отдельные подпрограммы. К тому же задание - ученическое, такая оптимизация здесь не требуется.

Тем не менее, задача стоит как
Цитата(JAYBE @  11.1.2013,  11:16 Найти цитируемый пост)
поиск элемента массива, который является наибольшим из отрицательных чисел расположенных в строках.

В связи с чем возникает несколько вопросов:
  • "наибольшее из отрицательных чисел" - имеется в виду по модулю (-10 > -2) или по значению (-10 < -2)
  • почему подчёркивается "расположенных в строках"? Не следует ли для каждой строки выполнить поиск такого наибольшего значения и вывести его вместе с координатами в массиве?
  • что делать, если отрицательных значений в матрице (строке) нет? Не следует ли так и сообщить пользователю: "В матрице отсутствуют элементы с отрицательными значениями"...
  • нужно ли вывести на экран всю матрицу целиком, чтобы потом понять, правильно ли осуществлён поиск?



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
bsa
Дата 11.1.2013, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(JAYBE @  11.1.2013,  11:16 Найти цитируемый пост)
У меня циклы 2 раза "пробегают". 1 раз при создании массив и 2-ой раз при поиске минимального элемента. Как-то можно их оптимизировать с точки зрения алгоритма в один? 

конечно можно. посмотри на циклы - они имеют много общего.  smile 
PM   Вверх
JAYBE
Дата 11.1.2013, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



А как сделать переход к следующему шагу в цикле, есть какой-либо аналог continue в js.
Тоесть так можно было бы:
Код

min = array[0][0] = array[i][y] = rand()%11-5;
    for (int i=0; i<m; i++) {
        for (int y=0; y<n; y++) {
 if ( i==0 && y==0 ) continue
            cout << (array[i][y] = rand()%11-5) << ' ';
            if (min>array[i][y]) {
                min = array[i][y];
            } ';
        }
        cout << endl;
    }
cout << min << endl;

PM   Вверх
IValdemar
Дата 11.1.2013, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



JAYBE
continue в C и C++ есть  smile 
Код

if ( i==0 && y==0 ) continue;


Добавлено через 6 минут и 6 секунд
Цитата(JAYBE @  11.1.2013,  22:40 Найти цитируемый пост)
cout << (array[i][y] = rand()%11-5) << ' ';

вот так он выведет 1, или что-то вроде этого, если надо вывести array[i][y] тогда так:
Код

array[i][y]  = rand()%11-5;
cout<< array[i][y] <<' ';

PM MAIL Skype   Вверх
volatile
Дата 12.1.2013, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

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



Цитата(IValdemar @  11.1.2013,  23:11 Найти цитируемый пост)
cout << (array[i][y] = rand()%11-5) << ' ';
вот так он выведет 1, или что-то вроде этого, если надо вывести array[i][y] тогда так


Нормально выведет. Код идентичен.

PM MAIL   Вверх
feodorv
Дата 12.1.2013, 00:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(JAYBE @  11.1.2013,  23:40 Найти цитируемый пост)
min = array[0][0] = array[i][y] = rand()%11-5;

А зачем здесь array[i][y]? i и y инициализированы корректно?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
IValdemar
Дата 13.1.2013, 00:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



volatile, хм действительно правильно выводит. Не знал, что так можно. 

Это потому что результатом операции 
Код

(array[i][y] = rand()%11-5)

является элемент array[i][y]? 
PM MAIL Skype   Вверх
volatile
Дата 13.1.2013, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

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



IValdemar, в данном случае мы имеем оператор присваивания.
Стандартная сигнатура этого оператора:

Код

type & operator = (const type &);

как видите он возвращает ссылку на объект, которому присваиваецца значение.

Код

cout << (array[i][y] = rand()%11-5)

здесь произодицца присваивание array[i][y] случайного значения, и затем возвращаецца ссылка на array[i][y], значение которой и выводицца в стандартный вывод.

---
Очевидно, что вы перепутали с оператором сравнения:

Код

bool operator == (const type &);

Вот он, как раз возвращает булеву переменную, как вы и описали.
Цитата(IValdemar @  11.1.2013,  23:11 Найти цитируемый пост)
вот так он выведет 1, или что-то вроде этого,


В языке С/С++ оператор=, и оператор==, это два разных оператора.
Не нужно их путать.

PM MAIL   Вверх
JAYBE
Дата 14.1.2013, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Спасибо. Так и не понял bsa про объяснение рандомных чисел - сделал сам. Оставил двойной проход по массиву, по учебной задаче наврное не стоит заморачиваться так с опимизацией выполнения кода.
В итоге оставил так:
Код

#include <iostream>
#include <stdlib.h>
using namespace std;

int main()
{
    int m, n, start_random, end_random, min, rnd;
    cout << "Enter length of array: ";
    cin >> m;
    cout << "Enter height of array: ";
    cin >> n;
    int array[m][n];
    srand(time(0));
    cout << "Enter start of random:";
    cin >> start_random;
    start_random;
    cout << "Enter end of random:";
    cin >> end_random;
    end_random+=1;
    cout << "Sgenerirovanniy massiv:\n";
    for (int i=0; i<m; i++) {
        for (int y=0; y<n; y++) {
            if (start_random>=0) {
                rnd = start_random + rand()%(end_random-abs(start_random));
            } else {
                rnd = start_random+rand()%(end_random+abs(start_random));
            }
            cout << (array[i][y] = rnd) << ' ';
        }
        cout << endl;
    }
    min = array[0][0];
    for (int i=0; i<m; i++) {
        for (int y=0; y<n; y++) {
            if (min>array[i][y]) {
                min = array[i][y];
            }
        }
    }
    cout << "Minimalnoe chilslo: " << min << endl;
    return 0;
}

PM   Вверх
bsa
Дата 14.1.2013, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



JAYBE, а что там непонятного? rand() возвращает значения от 0 для RAND_MAX включительно. Тебе же нужно от -10 до 15. Можно вынести -10 за скобку и получить от 0 до 25 включительно. Теперь нужно как-то RAND_MAX превратить в 25. Как это сделать? да очень просто - раздели результат rand() на double(RAND_MAX) (double необходим, чтобы деление было нецелочисленным) и получишь значения в диапазоне от 0 до 1 включительно. Теперь умножаешь на 25 и получаешь от 0 до 25. Осталось только вспомнить о -10. Правда, есть одна особенность, связанная с преобразованиями из double в int - при этом число округляется к ближайшему меньшему целому. Т.е. число 24.999999999999 округлится к 24. Чтобы этого избежать нужно добавить 0.5. Вот итоговая формула:
Код
r = int(25 * (rand() / double(RAND_MAX)) + 0.5) - 10;

PM   Вверх
volatile
Дата 14.1.2013, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

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



Цитата(bsa @  14.1.2013,  15:35 Найти цитируемый пост)
Т.е. число 24.999999999999 округлится к 24. Чтобы этого избежать нужно добавить 0.5. 

bsa, в данном случае лучше не прибавлять 0,5
иначе вероятность выпадения числа 0 и 25 будет в 2 раза меньше чем остальных (1...24)

Если нужен диапазон от 0 до 25 включительно, лучше умножать на 26, и ничего не прибавлять.

Добавлено через 8 минут и 32 секунды
r = rand() % 26 - 10;
PM MAIL   Вверх
bsa
Дата 14.1.2013, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(volatile @  14.1.2013,  17:55 Найти цитируемый пост)
r = rand() % 26 - 10;

в этом случае распределение неравномерно, так как RAND_MAX не делится на 26



Цитата(volatile @  14.1.2013,  17:55 Найти цитируемый пост)
bsa, в данном случае лучше не прибавлять 0,5
иначе вероятность выпадения числа 0 и 25 будет в 2 раза меньше чем остальных (1...24)

Если нужен диапазон от 0 до 25 включительно, лучше умножать на 26, и ничего не прибавлять.
а что будет в случае если rand вернет RAND_MAX? Ты уверен, что будет 24.9999999999, а не 25.00000000001? Я нет.

Я вспомнил правильную формулу.
Код
r = int(rand() / (RAND_MAX + 1.0) * N); //r будет в диапазоне [0;N)
Я для ТС она будет выглядеть так:
Код
r = int(rand() / (RAND_MAX + 1.0) * 26) - 10;

PM   Вверх
volatile
Дата 14.1.2013, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

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



Цитата(bsa @  14.1.2013,  20:02 Найти цитируемый пост)
 этом случае распределение неравномерно, так как RAND_MAX не делится на 26

Согласен, строго говоря, там будет незначительная неравномерность.
Но этой неравномерностью, в большинстве случаев можно спокойно пренебречь.

Цитата(bsa @  14.1.2013,  20:02 Найти цитируемый пост)
Я вспомнил правильную формулу.
r = int(rand() / (RAND_MAX + 1.0) * N); //r будет в диапазоне [0;N)

Эта формула, лишь длиннее, но ничем не лучше.
Неравномерность там будет точно такая-же. smile
Могу показать, если пожелаете. Но думаю вы сами поймете, если задумаетесь.
кстати, именно потому, что 
Цитата(bsa @  14.1.2013,  20:02 Найти цитируемый пост)
RAND_MAX не делится на 26

 smile 


Если уж нужна абсолютная равномерность, то надо делать так:
Код

// Получение равномерного числа в диапазоне [0..n)
int uniform_rnd (int n)
{
   int bound = RAND_MAX - RAND_MAX % n;
   int r;
   while ((r = rand ()) >= bound)
      ;
   return r % n;
}


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

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

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

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

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


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

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


 




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


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

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