Консультация № 198323
21.04.2020, 17:14
0.00 руб.
21.04.2020, 17:38
0 1 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:

Даны целые M и N и вектор действительных чисел X[1..N]. Найти целое число i (1<=i<=N-M), для которого сумма x[i]+...+x[i+M] ближе всего к нулю, где i- номер элемента из X. При решении использовать сортировку Хоара
Написать на плюсах требуется. Я написал, не могу понять, в чем причина того, что программа не работает.

Вот код:
Код:
#include <iostream>						
#include <vector>
#include <time.h>
#include <cmath>
using namespace std;
void qSort(int* a, int l, int r)
{
int i=l, j=r, m=a[(l+r)/2];
do
{
for(; a[i]<m; i++);
for(; a[j]>m; j--);
if( i<=j) swap(a[i++],a[j--]);
}while(i<=j);
if(l<j) qSort(a,l,j);
if(i<r) qSort(a,i,r);
}

int main()
{
srand(time(NULL));

setlocale(LC_CTYPE, "Russian");//ввод кирилицы

vector <double> X;//
int N,
M,
I = 1;

cout <<" \nВведите размер вектора:\t";//ввод размера вектора
cin >> N;

for(;;){ //ввод целого
cout << "\nВведите целое число:\t";
cin >> M;
if((M > N) || (M < 0)) cout << "\nНеверный ввод.\nПопробуйте еще раз.\n";//предупреждение о неверном вводе
else break;
}

//Заполнение вектора случайными значениями
for(int i = 0; i < N ; i++){
X.push_back(rand()%11-5);
}

//Печать вектора с использованием итераторов
vector<double>::const_iterator Start= X.begin(); //Указатель на начало вектора
vector<double>::const_iterator End = X.end(); //Указатель на конец вектора
vector<double>::const_iterator It; //Указатель на текущий элемент

for (It = Start;It < End; It++){ //печать
cout << *It << '\t';
}
int e=0;
int*arr=new int[N-M];
for(int i = 0;i < N - M ; i++){
while(e < N - M)
{for(int j=e;j<e+M;j++)
{ arr[i] += X[j];

};
arr[i]=abs(arr[i]);
e=e+1;

};

};
int*arr1=new int[N-M];
for(int i = 0;i <N - M ; i++)
{
arr1[i]=arr[i];
};
qSort(arr,0,N-M);
for(int i=0;i<N-M;i++)
{
if(arr[0]==arr1[i])
cout<<"i="<<i+1;
}

}

Обсуждение

давно
Студент
403303
19
24.04.2020, 00:31
общий
это ответ
Здравствуйте, josiph_tito!
Есть несколько недочетов, например вектор действительных чисел, а инициируете фактически целыми числами. И вызов алгоритма сортировки происходит с выходом за пределы массива, захватывается мусор в памяти и чревато исключением времени исполнения. Вместо qSort(arr,0,N-M); следует использовать qSort(arr,0,N-M-1); Выделенную память лучше освобождать штатно.
Постарался не сильно изменять исходный текст, только с целью лучшей читаемости.
P.-S. Надо учесть, что сравнение действительных чисел (if(arr[0]==arr1[i])) является небезопасным, но это уже отдельная тема.

Код:

#include <iostream>
#include <vector>
#include <time.h>
#include <cmath>

using namespace std;

void qSort(double* a, int l, int r)
{
int i=l, j=r;
double m=a[(l+r)/2];
do
{
for(; a[i]<m; i++);
for(; a[j]>m; j--);
if( i<=j) swap(a[i++],a[j--]);
}while(i<=j);
if(l<j) qSort(a,l,j);
if(i<r) qSort(a,i,r);
}

int main()
{
int i, e;

srand(unsigned(time(nullptr)));

setlocale(LC_CTYPE, "Russian");//ввод кирилицы

vector <double> X;
int N,M;

cout<<"Укажите размер вектора N, 1 или больше: ";
cin >> N;
if(N<1)
{
cout<<"Неверное число.";
return 0;
}

cout<<"Задайте количество нерассматриваемых элементов в конце массива, от 0 до "<<N-1<<": ";
cin>>M;
if(M<0 || M>N-1)
{
cout<<"Неверное число.";
return 0;
}

//Заполнение вектора случайными значениями
for(i = 0; i < N ; i++)
{
X.push_back(double(rand())/RAND_MAX*10-5);
}

//Печать вектора с использованием итераторов
vector<double>::const_iterator Start= X.begin(); //Указатель на начало вектора
vector<double>::const_iterator End = X.end(); //Указатель на конец вектора
vector<double>::const_iterator It; //Указатель на текущий элемент

for (It = Start;It < End; It++){ //печать
cout << *It << endl;
}
cout<<endl;

double *arr=new double[N-M];

for(i = 0; i < N - M ; i++)
{
arr[i]=0.0;
for(e=i;e<N-M;e++)
arr[i]+=X[e];
arr[i]=abs(arr[i]);
}

double *arr1=new double[N-M];

for(i = 0;i <N - M ; i++)
arr1[i]=arr[i];

qSort(arr,0,N-M-1);

for(i=0;i<N-M;i++)
if(arr[0]==arr1[i])
cout<<endl<<"i="<<i+1;

delete[] arr;
delete[] arr1;

return 0;
}
Форма ответа