C/C++

Помогите написать код с масивом

Дан массив размера N. Найти номера двух ближайших элементов из этого массива (т.е. элементов с наименьшим модулем разницы) и вывести эти номера в порядке возрастания.
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <vector>
#include <chrono>
#include <random>
#include <array>
#include <span>
using namespace std;
pair<int, int> find(const span<int> box) {
vector<int> tmp{ box.begin(), box.end() };
sort(tmp.begin(), tmp.end());
auto min = abs(tmp[0] - tmp[1]);
pair<int, int> fox{ tmp[0], tmp[1] };
for (auto i = 2U; i < tmp.size(); ++i) {
auto x = abs(tmp[i - 1] - tmp[i]);
if (x < min) {
min = x;
fox = { tmp[i - 1], tmp[i] };
}
}
auto itr_a = find(box.begin(), box.end(), fox.first);
auto itr_b = find(box.begin(), box.end(), fox.second);
auto pos_a = distance(box.begin(), itr_a) + 1;
auto pos_b = distance(box.begin(), itr_b) + 1;
return { pos_a, pos_b };
}
void mix(const span<int> box) {
const auto seed = static_cast<unsigned>(chrono::system_clock::now().time_since_epoch().count());
shuffle(box.begin(), box.end(), default_random_engine(seed));
}
void show(const span<int> box) {
for (auto x : box) cout << setw(4) << x;
puts("");
}
void show(const pair<int, int>& box) {
auto& [a, b] = box;
cout << setw(4) << a << setw(4) << b << '\n';
}
void test(const span<int> box) {
mix(box);
show(box);
auto res = find(box);
show(res);
}
int main() {
const auto n = 10U;
array<int, n> box{ 24, 17, -32, 95, -46, 29, 39, 55, -11, 62 };
for (auto i = 0; i < 10; ++i) test(box);
system("pause > nul");
}
Дмитрий Костыря
Дмитрий Костыря
90 157
Лучший ответ
#include <stdio.h>
#include <math.h>

int main()
{
const int N = 10;
int A[N];
for(int x = 0; x < N; x++) scanf("%d", &A[x]);
int delta_min = fabs(A[0] - A[1]), i1, i2;
for(int x = 0; x < N; x++)
{
for(int y = 0; y < N; y++)
{
if(x != y) /* чтобы не сравнивать элемент сам с собой */
if( fabs(A[x] - A[y]) < delta_min)
{
delta_min = fabs(A[x] - A[y]);
i1 = x;
i2 = y;
}
}
}

if(i1 < i2)
printf("%d\t%d\n", i1 + 1, i2 + 1);
else /* +1 потому что индексы начинаются с нуля, а не с единицы */
printf("%d\t%d\n", i2 + 1, i1 + 1);

return 0;
}
Лёшка Задорин чтобы не сравнивать сам с собой и не делать лишних итераций, достаточно ограничить диапазон;
x от 0 до предпоследнего индекса
y от x+1 до последнего индекса
Лёшка Задорин допустим массив из трех элементов ABC;
вы должны сравнить A c B, A c C, B с С (всего три итерации и три сравнения).
ваш код будет делать девять итераций и шесть сравнений.
int a;
cin >> a;
int* arr = new int[a];
for (int i = 0; i < a; i++)
arr[i] = rand() % 1000;
int res = fabs(arr[0]-arr[1]), i1=0, i2=1;

for (int i = 0; i < a; i++)
cout << arr[i] << "\t";
cout << endl;

for (int i=0; i<a-1; i++)
for (int j=i+1; j<a; j++)
if (fabs(arr[i] - arr[j]) < res)
{
res = fabs(arr[i] - arr[j]);
i1 = i;
i2 = j;
}
i1 < i2? cout << i1 << "\t" << i2 : cout << i2 << "\t" << i1;
Maks Yandala
Maks Yandala
51 411
Примечание:
Функция fabs() мне показалась неуместной, потому что во время компиляции мне выдало предупреждение, связанное с потерей данных:
дело в том, что fabs() работает только с дробными числам, размер которых может быть больше других. Из-за неявного преобразования дробного числа в тип данных, размер которых поменьше, может произойти та самая потеря данных. Поправьте, если неправ.

Предположим, что дан массив типа int с длиной N.

#include

using std::cout;
using std::endl;

int main()
{

int array[N];
int length=N;

int minDifference;

//Позже этим элементам будут присвоены значения нужных нам элементов
int firstElement, secondElement;

for (int count = 0; count < 1; ++count)
{
int min=array[count];
int max=array[count+1];

if (array[max] > array[min])
minDifference = array[max] - array[min];
else
minDifference = array[min] - array[max];

for (int count1 = 0; count1 < length; ++count1)
{
int currentDifferense;

if (array[count1 + 1] > array[count1])
currentDifferense = array[count1 + 1] - array[count1];
else
currentDifferense = array[count1] - array[count1 + 1];

if (minDifference > currentDifferense)
{
minDifference = currentDifferense;

firstElement = count1;
secondElement = count1 + 1;
}

}
}

int minElement = (array[firstElement] > array[secondElement]) ? secondElement : firstElement;
int maxElement = (array[firstElement] > array[secondElement]) ? firstElement : secondElement;

//Находим разницу между двумя рядом стоящими элементами и на этой основе создаем динамический массив.
//Также в нижнем стейтменте добавлена единица чтобы избежать ошибки неучтенной единицы.
int betweenDifferense = array[maxElement] - array[minElement]+1;

int* fromFirst_to_Second = new int[betweenDifferense];
for (int count = 0; count < betweenDifferense; ++count)
{
fromFirst_to_Second[count] = array[minElement] + count;
}

for (int count = 0; count < betweenDifferense; ++count)
{
cout << fromFirst_to_Second[count] << " ";
}

return 0;
}
Alexei Revencu
Alexei Revencu
902
Maks Yandala Предупреждение - возможно код будет работать не так, как вами задумано.
Предупреждение double -- int возможна потеря данных в нашем случае роли не играет и может игнорироваться. У нас массив int с мантиссой 4 байта, а fabs работает с double с мантиссой 6 байт. Значит потери значащих цифр не будет.
Alexei Revencu Спасибо за ответ.
Вы наверное правы. Прошу прощения за свое невежество, если неправ.

Но когда fabs() неявно преобразует число double(6 байт) в int(4 байта), эти два байта как раз должны потеряться при неявном преобразовании, разве нет?
Maks Yandala В коде ошибки.
1)цикл for (int count = 0; count < 1; ++count) равнозначен его отсутствию с count = 0;

2) если length = N, а count1 < N то array[count1 + 1] выйдет за границы массива с ошибкой.
Maks Yandala Допустим мы помещаем 4-х значное число в шестизначный контейнер. 5555 -> 005555. Обратная операция даст 5555, потому мы теряем только два незначащие нули.