Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке? Тип приложения - не Qt, Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.
|
Массивы
Задача 5.9. Удалить из массива все отрицательные элементы, расположенные между максимальным и минимальным элементами массива X[n].
Решение этой задачи можно разделить на следующие этапы:
- Ввод массива.
- Поиск номеров максимального (nmax) и минимального (nmin) элементов массива.
- Определение меньшего (a) и большего (b) из чисел nmax и nmin.
- Далее, необходимо перебрать все элементы массива, расположенные между числами с номерами a и b. Если число окажется отрицательным, то его необходимо удалить. Однако на этом этапе нужно учитывать тонкий момент. Если просто организовать цикл от a+1 до b-1, то при удалении элемента изменяется количество элементов, расположенных между a и b, и номер последнего удаляемого элемента. Это может привести к тому, что не всегда корректно будут удаляться отрицательные элементы, расположенные между a и b. Поэтому этот цикл для удаления организован несколько иначе.
Текст программы:
#include <iostream> #include <math.h> using namespace std; int main ( int argc, char **argv ) { int i, j, k, n, nmax, nmin, *x, a, b; cout<<" n = "; cin>>n; //Ввод количества элементов в массиве. x=new int [ n ]; //Выделяем память для динамического массива x. cout<<"Введите элементы массива X \n "; //Ввод элементов массива. for ( i =0; i<n; i++) cin>>x [ i ]; //Поиск номеров максимального и минимального элементов в массиве. for (nmax=nmin= i =0; i<n; i++) { if ( x [ i ]<x [ nmin ] ) nmin= i; if ( x [ i ]>x [ nmax ] ) nmax= i; } //Проверяем, что раньше расположено, минимум или максимум if ( nmin<nmax ) { a=nmin; b=nmax; } else { a=nmax; b=nmin; } //Перебираем все элементы, расположенные между максимумом и минимумом for ( i=a+1,k=1;k<=b-a-1;k++) if ( x [ i ] <0) //Проверяем, является ли очередной элемент массива отрицательным. {//Если текущий элемент массива является отрицательным числом, удаляем его for ( j= i; j<n-1; j++) x [ j ]=x [ j + 1 ]; n--; } else i ++; //Если x[i]>=0, переходим к следующему элементу. cout<<"Преобразованный массив X\n "; for ( i =0; i<n; i++) cout<<x [ i ]<<" \t "; cout<<endl; return 0; }
В качестве тестового можно использовать следующий массив: 34, 4, -7, -8, -10, 7, -100, -200, -300, 1. Здесь приведённая выше программа работает корректно, а вариант
for ( i=a+1; i<b; ) if ( x [ i ] <0) { for ( j= i; j<n-1; j++) x [ j ]=x [ j + 1 ]; n--; } else i ++;
приводит к неправильным результатам. Рекомендуем читателю самостоятельно разобраться в особенностях подобных алгоритмов удаления.
Задача 5.10. В массиве X[n] найти группу наибольшей длины, которая состоит из знакочередующихся чисел.
Если будут вычислены следующие значения:
- nach — номер первого элемента в группе;
- kon — номер последнего элемента в группе;
- k — количество элементов в группе.
то, зная любые два из них, можно однозначно определить группу внутри массива.
Вначале количество элементов в знакочередующейся группе равно 1. Дело в том, что если мы встретим первую пару знакочередующихся элементов, то количество их в группе сразу станет равным 2. Однако все последующие пары элементов будут увеличивать k на 1. И чтобы не решать проблему построения последовательности значений k 0,2,3,4,5,..., первоначальное значение k примем равным 1. Когда будем встречать очередную пару подряд идущих соседних элементов, то k необходимо будет увеличить на 1.
Алгоритм поиска очередной группы состоит в следующем: попарно () перебираем все элементы массива (параметр цикла изменяется от 0 до n - 2).
Если произведение соседних элементов отрицательно (), то это означает, что они имеют разные знаки и являются элементами группы. В этом случае количество () элементов в группе увеличиваем на 1 (k++). Если же произведение соседних элементов положительно (), то эти элементы не являются членами группы. В этом случае возможны два варианта:
- Если , то только что закончилась группа, в этом случае kon=i -номер последнего элемента в группе, — количество элементов в только что закончившейся группе.
- Если , то это просто очередная пара незнакочередующихся элементов.
После того, как закончилась очередная группа знакочередующихся элементов, необходимо количество групп (kgr) увеличить на 1 (kgr++). Если это первая группа (kgr=1) знакочередующихся элементов, то в переменную max записываем длину этой группы (max=k)3В переменной, а в переменную kon_max номер последнего элемента группы (kon_max=i). Если это не первая группа (kgr=1), то сравниваем max и длину текущей группы (k). Если k>max, то в переменную max записываем длину этой группы (max=k), а в переменную kon_max номер последнего элемента группы (kon_max=i).
После этого в переменную k опять записываем 1 для формирования новой группы элементов.
По окончанию цикла значение k может быть больше 1. Это означает, что в самом конце массива встретилась ещё одна группа. Для неё надо будет провести все те же действия, что и для любой другой группы. Далее приведён текст программы.
#include <iostream> using namespace std; int main ( int argc, char **argv ) { float *x; int i, k, n, max, kgr, kon_max; cout<<" n = "; cin>>n; //Ввод размера массива. x=new float [ n ]; //Выделение памяти для массива. cout<<"Введите массив x\n "; //Ввод элементов массива. for ( i =0; i<n; i++) cin>>x [ i ]; //Попарно перебираем элементы массива. Количество знакочередующихся //групп в массиве kgr=0, количество элементов в текущей группе — 1. for ( kgr= i =0,k=1; i<n-1; i++) //Если соседние элементы имеют разные знаки, то количество (k) //элементов в группе увеличиваем на 1. if ( x [ i ] * x [ i +1]<0) k++; else if ( k>1) //Если k>1, то только что закончилась группа, i — номер последнего элемента {//в группе, k — количество элементов в группе. Увеличиваем kgr на 1. kgr++; if ( kgr==1) //Если это первая группа (kgr=1) знакочередующихся элементов, { max=k; //то max — длина группы (max=k), kon_max= i; //kon_max — номер последнего элемента группы. } else //это не первая группа (kgr 6= 1), сравниваем max и длину текущей группы. if ( k>max) //Если k>max, { max=k; //max — длина группы, kon_max= i; //kon_max — номер последнего элемента группы. } k=1; //В переменную k записываем 1 для формирования новой группы элементов. } if ( k>1) //Если в конце массива была группа. { kgr++; //Количество групп увеличиваем на 1. if ( kgr==1) //Если это первая группа, { max=k; //то max — длина группы, kon_max=n-1; //группа закончилась на последнем элементе массива. } else if ( k>max) //Если длина очередной группы больше max. { max=k; //то в max записываем длину последней группы, kon_max=n-1; //группа закончилась на последнем элементе массива. } } if ( kgr >0) //Если знакочередующиеся группы были, { //то выводим информацию о группе наибольшей длины, cout<<"В массиве "<<kgr<<" групп знакочередующихся элементов\n "; cout<<"Группа максимальной длины начинается с элемента Номер "<<kon_max-max+1<<", её длина "<<max<<",номер последнего элемента группы " <<kon_max<<endl; for ( i=kon_max-max+1; i<=kon_max; i++) //а также саму группу. cout<<x [ i ]<<" "; cout<<endl; } else //Если знакочередующихся групп не было, то выводим сообщение об этом. cout<<"В массиве нет групп знакочередующихся элементов\n "; return 0; }