C++: Среднее арифметическое + нахождение минимального и максимального элементов (индексов) + сортировка

Хорошие задачки стали давать в универах. Составные =)

Вычислить среднее арифметическое элементов массива X=(x1,x2,…,xn),
расположенных между его минимальным и максимальным значениями.
Если минимальный элемент размещается в массиве раньше
максимального, то упорядочить массив на данном промежутке по
возрастанию его элементов, и наоборот, если минимальный элемент
размещается после максимального, то упорядочить по убыванию.

PS: Нельзя использовать динамическую память :(
Задача на самом деле не задача, а состоящая из трех подзадач:

  1. Найти минимальный и максимальный элементы и их индексы
  2. Вычислить среднее арифметическое для этого промежутка
  3. Отсортировать промежуток по возростанию или убыванию в зависимости от того, как расположены минимальный и максимальный элементы.

Не хочу читать! Хочу исходный код!

Нахождение минимального и максимального элементов массива.


Я это делал тут (и наверное тут), но можно лучше, поэтому решил переписать код по-правильному что ли.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
        imin = 0;
    imax = 0;
    for (int i = 0; i < n; i++)
    {
        if (arr[i] <= arr[imin])
        {
            imin = i;
        } 
        if (arr[i] > arr[imax])
        {
            imax = i;
        }
    }
        imin = 0;
	imax = 0;
	for (int i = 0; i < n; i++)
	{
		if (arr[i] <= arr[imin])
		{
			imin = i;
		} 
		if (arr[i] > arr[imax])
		{
			imax = i;
		}
	}

Если разобрать его построчно, то будет так:

  • Сначала присваиваем переменным, в которых будут индексы минимального и максимального элементов 0. Считаем, что все находится в 0-ой ячейке.
  • Пробегаем по всему массиву, благо он маленький, и смотрим, если текущий элемент массива стал меньше чем элемент с индексом imin (для этого обращаемся по индексу к элементу), то переприсваиваем индекс. Тоже самое и с максимальным, только знак другой.

Примечание: int n — длина массива; int imin, imax — индексы минимального и максимального элементов соответственно. arr[] — массив

Вычислить среднее арифметическое для этого промежутка


Для второго шага будет круто использовать функцию. Так как нам нужно найти среднее значение между минимальным и максимальным элементам, то в функцию следует передать: ссылку на массив (массив), индекс минимального и индекс максимального элементов.

Дальше нужно пройтись по этим элементам и просчитать. Но фишка в том, что максимальный элемент может идти до минимального, и цикл выполняться не будет. Понадобится условие и 2 разных цикла.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
double getAverage (int * arr, int imin, int imax)
{
    int sum = 0, 
        _count = 0;
    if (imin < imax)
    {
        for (int i = imin; i <= imax; i++)
        {
            sum += arr[i];
            _count++;
        }
    }
    else
    {
        for (int i = imax; i <= imin; i++)
        {
            sum += arr[i];
            _count++;
        }
    }
    return sum / _count * 1.0;
 
}
double getAverage (int * arr, int imin, int imax)
{
	int sum = 0, 
		_count = 0;
	if (imin < imax)
	{
		for (int i = imin; i <= imax; i++)
		{
			sum += arr[i];
			_count++;
		}
	}
	else
	{
		for (int i = imax; i <= imin; i++)
		{
			sum += arr[i];
			_count++;
		}
	}
	return sum / _count * 1.0;

}

Мне кажется, что весьма очевидно, что делает эта функция.

Отсортировать промежуток по возростанию или убыванию в зависимости от того, как расположены минимальный и максимальный элементы.


Последнее, что нужно сделать — выполнить сортировку. Алгоритм не указан. Взял первый попавшийся и слегка его модифицировал. Сделал из него функцию (по-хорошеу конечно процедуру, но да ладно):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void sort(int * arr, int f, int t, bool order) {
  for (int i=f; i<t-1; i++) 
  {
    int min=i;
    for (int j=i+1; j<t; j++) 
    {
      if (order ^ arr[min] > arr[j]) 
      {
       min=j;
      }
    }
        int temp = arr[min]; 
        arr[min] = arr[i]; 
        arr[i] = temp;
  }
}
void sort(int * arr, int f, int t, bool order) {
  for (int i=f; i<t-1; i++) 
  {
    int min=i;
    for (int j=i+1; j<t; j++) 
	{
      if (order ^ arr[min] > arr[j]) 
	  {
       min=j;
      }
    }
		int temp = arr[min]; 
        arr[min] = arr[i]; 
        arr[i] = temp;
  }
}

на вход подается массив (так же как и в функцию вычисления среднего арифметического) число f (first) — с какого индекса начинать сортировку и t (to) до какого индекса производить сортировку. Последний параметр order определяет порядок сортировки (по возрастанию или по убыванию).

На самом деле он самый интересный в этой функции. Порядок сортировки зависит от знака в условии. > или <. Order — логическая переменная и второе выражение тоже логическое выражение. Если применить к нему операцию XOR (логическое отрицание, значек ^, то знак развернется)

Собрав все воедино можно получить такой код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "stdafx.h"
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <locale>
 
#define SIZE 200
 
using namespace std;
 
double getAverage (int * arr, int imin, int imax)
{
    int sum = 0, 
        _count = 0;
    if (imin < imax)
    {
        for (int i = imin; i <= imax; i++)
        {
            sum += arr[i];
            _count++;
        }
    }
    else
    {
        for (int i = imax; i <= imin; i++)
        {
            sum += arr[i];
            _count++;
        }
    }
    return sum / _count * 1.0;
 
}
void sort(int * arr, int f, int t, bool order) {
  for (int i=f; i<t-1; i++) 
  {
    int min=i;
    for (int j=i+1; j<t; j++) 
    {
      if (order ^ arr[min] > arr[j]) 
      {
       min=j;
      }
    }
        int temp = arr[min]; 
        arr[min] = arr[i]; 
        arr[i] = temp;
  }
}
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "Russian");
    int arr [SIZE],
        n = 0,
        imax =0,
        imin =0;
    srand(time(NULL));
    cout << "Введите n:";
    cin >> n;
    if (n > SIZE)
    {
        cout << "n ну очень большой!";
        system("pause");
        return -1;
    }
    // Заполнение и вывод
    for (int i = 0; i < n; i++)
    {
        arr[i] = rand() % 10; 
        cout << arr[i] << " ";
    }
    // Нахождение минимального и максимального элементов массива
    imin = 0;
    imax = 0;
    for (int i = 0; i < n; i++)
    {
        if (arr[i] <= arr[imin])
        {
            imin = i;
        } 
        if (arr[i] > arr[imax])
        {
            imax = i;
        }
    }
    cout << endl;
    cout.precision(4);
    cout << "Среднее арифметическое = " << getAverage(arr, imin,imax) << endl;
    cout << "Индекс минимального = " << imin  << "\nИндекс максимального = " << imax << endl;
    if (imin < imax)
    {
        sort(arr, imin, imax, false);
    }
    else
    {
        sort(arr, imax, imin, true);
    }
    cout << "Массив после сортировки = " << endl;
    for (int i = 0; i < n; i++)
    {
        cout << arr[i] << " ";
    }
    system("Pause");
    return 0;
}
#include "stdafx.h"
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <locale>

#define SIZE 200

using namespace std;

double getAverage (int * arr, int imin, int imax)
{
	int sum = 0, 
		_count = 0;
	if (imin < imax)
	{
		for (int i = imin; i <= imax; i++)
		{
			sum += arr[i];
			_count++;
		}
	}
	else
	{
		for (int i = imax; i <= imin; i++)
		{
			sum += arr[i];
			_count++;
		}
	}
	return sum / _count * 1.0;

}
void sort(int * arr, int f, int t, bool order) {
  for (int i=f; i<t-1; i++) 
  {
    int min=i;
    for (int j=i+1; j<t; j++) 
	{
      if (order ^ arr[min] > arr[j]) 
	  {
       min=j;
      }
    }
		int temp = arr[min]; 
        arr[min] = arr[i]; 
        arr[i] = temp;
  }
}
int _tmain(int argc, _TCHAR* argv[])
{
	setlocale(LC_ALL, "Russian");
	int arr [SIZE],
		n = 0,
		imax =0,
		imin =0;
	srand(time(NULL));
	cout << "Введите n:";
	cin >> n;
	if (n > SIZE)
	{
		cout << "n ну очень большой!";
		system("pause");
		return -1;
	}
	// Заполнение и вывод
	for (int i = 0; i < n; i++)
	{
		arr[i] = rand() % 10; 
		cout << arr[i] << " ";
	}
	// Нахождение минимального и максимального элементов массива
	imin = 0;
	imax = 0;
	for (int i = 0; i < n; i++)
	{
		if (arr[i] <= arr[imin])
		{
			imin = i;
		} 
		if (arr[i] > arr[imax])
		{
			imax = i;
		}
	}
	cout << endl;
	cout.precision(4);
	cout << "Среднее арифметическое = " << getAverage(arr, imin,imax) << endl;
	cout << "Индекс минимального = " << imin  << "\nИндекс максимального = " << imax << endl;
	if (imin < imax)
	{
		sort(arr, imin, imax, false);
	}
	else
	{
		sort(arr, imax, imin, true);
	}
	cout << "Массив после сортировки = " << endl;
	for (int i = 0; i < n; i++)
	{
		cout << arr[i] << " ";
	}
	system("Pause");
	return 0;
}

Скачать в виде архива

Пример работы программы:

5 Responses

  1. Oksana 03.01.2014 / 19:22

    Помогите пожайлуста.Что делать когда нужно подсчитать количество цифер между первим максимальним и последним минимальним (и наоборот-между первим мін і последним макс) если значения в масиве могут повторяться

    • Pyatnitsev 03.01.2014 / 21:57

      Привет!
      Первый максимальный — точное сравнение. A[i] > max
      Последний минимальный это не точное сравнение a[i] <= min Ну а внутри считать. Или мне код накидать ?

      • Oksana 04.01.2014 / 02:58

        Спасибо что откликнулся) Задание стоит следующее -Найти макс и мин значения в массиве, посчитать сколько цифр находится в промежутке между ними. Но возник вопрос так как массив задается рандомно, то что будет, если макс и мин значение будет повторятся несколько раз. Как указать что нужное нам именно первое макс и последнее мин значения.(Например випадают цифри 79,79,6,7,8,9,45,4,-8,-8 и нам нужно первое 79 и последнее — 8)У меня получился такой код.Что нужно добавить еще
        #include
        #include
        using namespace std;
        void main()
        {
        srand(time(0));
        const int size=10;
        int mas[size];
        for(int i=0; i<size;i++)
        {
        mas[i]=rand()%201-100;
        cout<<mas[i]<<endl;
        }
        int max=mas[0];
        int min=mas[0];
        for(int i=0;i<size;i++)
        {
        if(maxmas[i])min=mas[i];
        }
        int imax=0;
        int imin=0;
        for(int i=0;imas[imax]) imax=i;
        if(mas[i]<=mas[imin])imin=i;
        }
        int count=0;
        if(imin<imax)
        {
        for(int i=imin; i<imax;i++)count++;
        }
        else
        {
        for(int i=imax;i<imin;i++)count++;
        }
        cout<<endl<<"max "<<max<<endl;
        cout<<"index max "<<imax<<endl;
        cout<<endl<<"min "<<min<<endl;
        cout<<"index min "<<imin<<endl;
        cout<<endl<<"count mig min i max "<<count<<endl;

        • Pyatnitsev 04.01.2014 / 16:59

          Такая идея:
          // ConsoleApplication1.cpp: определяет точку входа для консольного приложения.
          //

          #include «stdafx.h»
          #include
          #include
          #include

          int _tmain(int argc, _TCHAR* argv[])
          {
          int a[250];
          int n = 0, min=32768, max=-32767, maxi, mini;
          printf_s(«Enter size of array (1..250):»);
          scanf_s(«%d», &n);
          srand(time(NULL));
          for (int i = 0; i < n; i++) { a[i] = rand() % 10; printf_s("%d ", a[i]); if (a[i] <= min) // последний минимум { min = a[i]; mini = i; } if (a[i] > max) // первый максимум
          {
          max = a[i];
          maxi = i;
          }
          }
          printf_s(«\nlast min = %d in postion %d\nfirst max = %d in position %d\ndigits between %d\n»,min, mini,max, maxi, abs(maxi-mini));
          system(«pause»);
          return 0;
          }

          Пример запуска

          http://pyatnitsev.ru/wp-content/uploads/2014/01/ConsoleApplication1.zip — вот

  2. Vlados471 07.05.2014 / 01:34

    как осуществить нахождение минимальных и максимальных элементов индекса при помощи ввода массива с клавиатуры, а не с помощью случайного набора?

Добавить комментарий