Работа с массивами. Нужна помощь

Новичок в С++. Сейчас у меня задание: Создать массив из N рандомных вещественных чисел и:

  1. Найти максимальный по модулю элемент
  2. Найти сумму элементов, расположенных между первым и вторым положительными элементами
  3. Преобразовать массив так, чтобы все нулевые элементы располагались после всех остальных. Я уже 2 недели пытаюсь разобраться в массивах, пока что смог сделать только первый пункт, и то, максимальный не по модулю, а просто максимальный. Вот все что у меня есть:
#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
    srand(time(NULL));
    setlocale(LC_ALL, "");
    int n, step = 0;
    double max = -10000;
    double* mas = NULL;
    cout << "Введите размер массива: ";
    cin >> n;
    mas = new double[n];
    for (int i = 0; i < n; ++i)
    {
        mas[i] = (double)(rand() % 10001) / 100 - 50;
        cout << mas[i] << " ";
    }
    cout << endl;
    for (int i = 0; i < n; i++)
    {
        if (*(mas + i) > max)
        {
            max = *(mas + i);
        }
        step++;
    }
    cout << "Максимальный элемент массива: " << max;
    return 0;
}

Помогите пожалуйста исправить первый пункт чтоб находилось по модулю и решить остальные 2. Второй и третий пункты я мучал очень долго, но там даже ничего похожего на нужный результат не получается, мне даже как пример своего решения выкладывать нечего. У меня даже идей уже никаких нет и мыслей. По возможности, объясните ваше решение. Я очень хочу разобраться с массивами, но мне это очень трудно дается.


Ответы (1 шт):

Автор решения: Ilnarildarovuch

Исправление первого пункта:

Чтобы найти максимальный по модулю элемент, необходимо использовать функцию abs из заголовочного файла <cmath>. Вот исправленный код:

#include <cmath>

// ...

for (int i = 0; i < n; i++)
{
    if (abs(*(mas + i)) > abs(max))
    {
        max = *(mas + i);
    }
}

Решение второго пункта:

Чтобы найти сумму элементов между первым и вторым положительными элементами, необходимо сначала найти индексы этих элементов. Вот как это можно сделать:

int firstPositiveIndex = -1;
int secondPositiveIndex = -1;

for (int i = 0; i < n; i++)
{
    if (*(mas + i) > 0)
    {
        if (firstPositiveIndex == -1)
        {
            firstPositiveIndex = i;
        }
        else if (secondPositiveIndex == -1)
        {
            secondPositiveIndex = i;
        }
    }
}

Теперь, когда у нас есть индексы первого и второго положительных элементов, мы можем вычислить сумму элементов между ними:

double sum = 0;

if (firstPositiveIndex != -1 && secondPositiveIndex != -1)
{
    for (int i = firstPositiveIndex + 1; i < secondPositiveIndex; i++)
    {
        sum += *(mas + i);
    }
}

Решение третьего пункта:

Чтобы преобразовать массив так, чтобы все нулевые элементы располагались после всех остальных, можно использовать два указателя: один для чтения элементов, а другой для записи ненулевых элементов. Вот как это можно сделать:

int readIndex = 0;
int writeIndex = 0;

while (readIndex < n)
{
    if (*(mas + readIndex) != 0)
    {
        *(mas + writeIndex) = *(mas + readIndex);
        writeIndex++;
    }

    readIndex++;
}

// Заполнить оставшиеся элементы нулями
for (int i = writeIndex; i < n; i++)
{
    *(mas + i) = 0;
}

Объяснение:

  • Указатель readIndex считывает элементы массива слева направо.
  • Указатель writeIndex записывает ненулевые элементы слева направо.
  • Когда встречается ненулевой элемент, он записывается в текущую позицию writeIndex, и writeIndex увеличивается.
  • Когда встречается нулевой элемент, он пропускается, и readIndex увеличивается.
  • После того, как все ненулевые элементы записаны, оставшиеся элементы заполняются нулями.

Изменение 2 пункта без использования индексации, только с помощью указателей:

int* firstPositivePtr = nullptr;
int* secondPositivePtr = nullptr;

int* ptr = mas;
while (ptr < mas + n)
{
    if (*ptr > 0)
    {
        if (firstPositivePtr == nullptr)
        {
            firstPositivePtr = ptr;
        }
        else if (secondPositivePtr == nullptr)
        {
            secondPositivePtr = ptr;
        }
    }

    ptr++;
}

double sum = 0;

if (firstPositivePtr != nullptr && secondPositivePtr != nullptr)
{
    ptr = firstPositivePtr + 1;
    while (ptr < secondPositivePtr)
    {
        sum += *ptr;
        ptr++;
    }
}

Объяснение:

  • Указатель ptr используется для перебора элементов массива.
  • Указатели firstPositivePtr и secondPositivePtr используются для отслеживания первого и второго положительных элементов.
  • После того, как найдены первый и второй положительные элементы, указатель ptr устанавливается на элемент после первого положительного элемента.
  • Затем указатель ptr используется для перебора элементов между первым и вторым положительными элементами, и их сумма вычисляется.

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

→ Ссылка