#c #arrays #data-structures
#c #массивы #структуры данных
Вопрос:
у меня есть задача, в которой я должен написать программу, чтобы найти пиковый элемент в массиве. Я его закодировал, но когда я показал его своей учительнице, она сказала мне, что это неточно, хотя он отлично работал на Dev C .Она сказала мне изменить его. Может кто-нибудь сказать мне, что не так с кодом и как мне его изменить.
int main(){
int arr[50];
cout<<"Enter size:";
int n;
cin>>n;
cout<<"Elements:";
for(int i=0;i<n;i ){
cin>>arr[i];
}
for(int i=0;i<n;i ){
if(arr[i]>arr[i 1] amp;amp; arr[i]>arr[i-1]){
cout<<"PEAK: "<<arr[i]<<endl;
}
}
return 0;
}
Комментарии:
1. Первое, что нужно исправить: Если
i
есть0
, чтоarr[i-1]
вам дает?2. Он не показал никаких error..so я думал, что это может принять мусорное значение..
Ответ №1:
Проблема заключается во втором for
теле цикла. Как указал NathanOliver в комментариях, arr[i] > arr[i-1]
должен попытаться получить доступ к памяти с недопустимым смещением, когда i
равно 0. То же самое касается другого условия — arr[i] > arr[i 1]
приведет к доступу за пределы — ну, ваш arr
может содержать максимум 50 элементов, поэтому, если n
меньше 50, вы должны обращаться только к неинициализированной памяти. Условие нахождения пика может быть переписано как:
for (unsigned i = 0u; i < n; i ){
bool isPeak = true;
if (i > 0 amp;amp; arr[i] < arr[i - 1]){
isPeak = false;
}
if (i < n - 1 amp;amp; arr[i] < arr[i 1]){
isPeak = false;
}
if (isPeak){
std::cout << "PEAK: " << arr[i] << 'n';
}
}
Это использует короткое замыкание логических операторов — выражения вычисляются слева направо, поэтому — если мы вернемся к i > 0 amp;amp; arr[i] < arr[i - 1]
условию — потенциально опасная проверка (которая может привести к недопустимому доступу) не будет выполнена, если первое условие ( i > 0
) равно false.
Что касается самого кода, теперь он проверяет каждую сторону текущего элемента отдельно.
Еще лучше (хотя, вероятно, это не связано с тем, что имеет в виду ваш учитель) было бы использовать std::vector
. Тогда код мог бы обрабатывать более 50 элементов.
Комментарии:
1. Большое спасибо… что означает i= 0u в коде ur?
2. Это второстепенная вещь, вы могли бы с таким же успехом написать
int i = 0
илиint i = 0u
.u
в конце числового литерала означает, что этот литерал (в данном случае 0) имеет типunsigned
. Если бы вы использовали0
, он был бы типаint
по умолчанию. Для получения дополнительной информации смотрите: en.cppreference.com/w/cpp/language/integer_literal Для ваших первых упражнений по кодированию это действительно не имеет значения. Это может иметь значение, если вы полагаетесь на автоматический вывод типа.auto foo = 0;
определяетfoo
какint
, тогда какauto foo = 0u;
дал бы вамunsigned foo
.3. спасибо, даже несмотря на то, что я студент 4-го семестра, изучающий компьютерные системы, я чувствую, что я ни хрена не смыслю в программировании,, Вы можете сказать мне, как улучшить мое кодирование?
4. Это выходит за рамки данного вопроса, но я обнаружил, что сайты с проблемами программирования, такие как HackerRank или Codewars (которые я широко использовал, хотя иногда они довольно медленные), являются неплохим способом улучшения. Возможно, вы также захотите попробовать другие языки программирования, если чувствуете, что у вас проблемы с C (особенно с учетом того, что его могут с трудом преподавать в университете). Это действительно зависит от того, что вам нравится делать — в целом просто продолжайте практиковаться. Запуск вашего собственного проекта — это также хороший способ столкнуться с новыми проблемами и повеселиться. Удачи!
5. отлично, сделаем это,