Произведение последних элементов в массиве

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

Ответить
dissable1
Сообщения: 4
Зарегистрирован: 22 дек 2014, 15:04

Задание такое:
Задав одномерный массив целочисленных данных А в одном из заданных форматов, реализовать обработку массива, как указа-но в варианте. Длина статического массива N<=20. Значение N ввести с клавиатуры с проверкой на допустимые значения. Предусмотреть возможность ввода значений элементов массива пользователем и с помощью датчика случайных чисел.

Найти произведение последних L элементов в массиве A={a}.
Я всё сделал ,до произведения.Дальше тупик..

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

#include <iostream>
#include <windows.h>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
    SetConsoleOutputCP(1251);
    const short N = 20;
    short n, mas[N],L,proizv;
    while (true)
    {
        cout << "Введите n-->";
        cin >> n;
        if (n > 0 && n <= N) break;
        cout << "Неправильное значение,повторите попытку" << endl;
    }
    int choise;
    do
    {
        cout << "1 - заполнение массива вручную" <<endl
            << "2 - заполнение случайными числами" <<endl;
        cin >> choise;
        switch (choise)
        {
        case 1:
            cout << "понял,заполняйте сами!" << endl;
            for (int i = 0; i < n; ++i)
            cin >> mas[i];
            break;
            case 2:
            srand((unsigned)time(NULL));
            for (int i = 0; i < n; ++i)
                mas[i] = rand();
            break;
        default:cout << "Неправильное значение!" <<endl;
        }
    } while ((choise < 1 || choise > 2));
    cout << "Массив-->";
    for (int i = 0; i < n; ++i)
        cout << mas[i] << ' ' << endl;
    cout << "введите L-->";
    cin >> L;
Мне сказали что нужно дальше запускать цикл
for (int i = n-1; i => L; --i) и умножать всё
Но мозг не варит,помогите пожалуйста дописать
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Фактически, тебе нужно перемножить элементы массива mas начиная с последнего (с индексом n-1) и заканчивая L-ым с конца (следовательно у него индекс n - 1 - (L - 1), раскрывая скобки получаем n-L).
proizv = mas[n-1] * ... * mas[n-L]
Теперь как это из формулы превратить в код программы. Очевидно нужен цикл по индексам, причём границы цикла уже вычислены.

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

for (int i = n-1; i >= n-L; --i)
В переменной proizv мы будем накапливать произведение, на каждой следующей итерации домножая proizv на очередной эдемент массива и помещая результат снова в proizv:

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

proizv = proizv*mas[i];
Осталась последняя мелочь. Чем инициализировать proizv перед циклом, чтобы накопление отработало корректно. Нулём? Ноль бы подошёл, если бы суммировали элементы. В случае же умножения в качестве инициализрующего значения ноль не подходит, так как перемножение в цикле нуля на любое число снова даст ноль и никакого накопления не получится. Правильный ответ 1.

В результате имеем следующий код:

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

proizv = 1;
for (int i = n-1; i >= n-L; --i)
   proizv = proizv*mas[i];
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
dissable1
Сообщения: 4
Зарегистрирован: 22 дек 2014, 15:04

Спасибо большое,помогите пожалуйста ещё с проверкой.Мне нужно чтобы тип результата был short,и чтобы числа ,которые ввожу в массив,были не больше SHRT_MAX и меньше SHRT_MIN.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Считать значение больше SHRT_MAX или меньше SHRT_MIN в переменную типа short ты не сможешь по определению, так как произойдёт переполнение, старший бит пропадёт и число всё равно останется в указанном диапазоне. То есть сравнивать с граничными числами после того, как число было считано в переменную бессмысленно.

В качестве альтернативы предлагаю считать в переменную типа long, проверить границы, а затем, если всё в порядке, переприсвоить значение переменной типа short.

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

Да,это я знаю,я просто не знаю как проверять число,которое ввожу в массив.Если была бы переменная,то спокойно написал,вроде
if (a>SHRT_MIN && a<SHRT_MAX) break;
а что тут писать вместо "а"?
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

А mas нельзя написать вместо а? Я думал, что эта часть понятна сама собой.

Всё, что я писал, куда важнее, так как простая замена a на mas не решит проблемы. Причины выше указаны. Так что нужно, как минимум, объявить переменную типа большего, чем short (к примеру, int или long), считать число в неё, потом сделать проверку и лишь потом, если всё в порядке, записать значение в mas.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
dissable1
Сообщения: 4
Зарегистрирован: 22 дек 2014, 15:04

а как написать функции ввода и вывода массива?Я думал просто скопировать,но так не работает

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

int func1()
{
	s = 0;
	for (; s < n; ++s)
	{
		while (true)
		{
			cin >> mas[s];
			if (mas[s]>SHRT_MIN && mas[s] < SHRT_MAX)
				break;
			cout << "Выход за диапазон,повторите попытку" << endl;
		}
	}
}
int func2()
{
	srand((unsigned)time(NULL));
	for (int i = 0; i < n; ++i)
		mas[i] = rand();
	break;
}
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Дело в том, что mas является локальной переменной. Внутри функци func1 и func2 эта переменная не будет видна, так как область её виимости ограничена функцией main. То же самое касается переменной n.

Выхода два:

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