Персональная страничка
Диканева Тараса
Викторовича

Главная \ Преподавательское \ Программирование для начинающих

10. Массивы

Предыдущий раздел:

Следующий раздел:

Задание 10: Массивы

1. Заполнение массивов.

Опишите три массива с одинаковым количеством элементов, заданным константой. Значения элементов первого массива должны вводиться с клавиатуры, второго быть равными номерам элементов, третьего быть случайными целыми числами в диапазоне от 0 до 10. После заполнения выведите элементы каждого из массивов.

При решении следующих задач можно использовать любой из способов заполнения.

2. Пусть описана константа и два типа-массива:

  const
    m = 3;
  type
    TMas1 = array [1..2*m+1] of real;
    TMas2 = array [-m..m] of real;

Создайте программу, которая значения, записанные в элементах массива 1-го типа, переносит в массив 2-го типа.

3. Создайте программу, проверяющую есть ли в целочисленном массиве хотя бы один нечетный элемент.

4. В массиве, элементами которого являются целые числа произвести следующие действия:

    1) Если элементы меньше заданного числа, замените их этим числом.

    2) Замените все элементы с индексами в диапазоне [a, b] нулями.

    3) Поменяйте местами первый и последний элементы массива.

    4) Совершите циклическую перестановку элементов массива (сдвиньте все элементы вправо, а последний поставьте на первое место).

    5) Расположите элементы массива в обратном порядке.

    6) Поменяйте местами элементы с четными и нечетными индексами.

    7) Сожмите массив, выбросив из него каждое второе значение. Оставшуюся половину массива заполните нулями.

    8) Вставьте дополнительный элемент в массив в заданное место. Чтобы освободить это место, все элементы, начиная с него, сдвиньте вправо. Последний элемент будет некуда девать – и черт с ним.

    9) Определите индекс указанного пользователем элемента массива. Если такого элемента нет, сообщите об этом пользователю.

5. Пусть имеется массив, заполненный целыми числами. Получите на его основе новый массив следующими способами:

    1) Получите массив из разностей соседних элементов исходного массива.

    2) Получите массив из скользящих сумм n соседних элементов. То есть каждый i-й элемент нового массива это сумма n элементов старого, начиная с i-го. Новый массив, очевидно, будет содержать на n-1 элементов меньше. Пусть массивы заданы с одинаковой длиной, просто не выводите элементы нового массива, которые невозможно вычислить.

6. Получите сумму и среднее арифметическое всех элементов массива.

7. Получите корень из суммы квадратов всех элементов массива (модуль вектора).

8. Для двух массивов получите сумму попарных произведений их членов (скалярное произведение).

9. Для двух массивов получите Евклидово расстояние между ними.

10. Найдите максимальный и минимальный элементы массива.

11. Отсортируйте элементы массива методом выбора.

Следующий раздел:

Предыдущий раздел:

64 комментария

  1. Игорёк

    program zd48;
    const
    n=3;
    type
    TMassive1=array [0..n-1] of real;
    TMassive2=array [0..n-1] of integer;
    TMassive3=array [0..n-1] of integer;
    var
    y:TMassive1;
    z:TMassive2;
    x:TMassive3;
    i:integer;
    begin
    writeln(‘Ââåäèòå y[1]’);
    readln(y[1]);
    writeln(‘Ââåäèòå y[2]’);
    readln(y[2]);
    writeln(‘Ââåäèòå y[3]’);
    readln(y[2]);

    for i:=0 to n-1 do
    x[i]:=random(10);
    z[i]:=i;
    for i:=0 to n-1 do
    writeln(‘x[‘,i,’] ‘,x[i]);
    for i:=0 to n-1 do
    writeln(‘z[‘,i,’] ‘,z[i]);

    end.

    1-я задача. Почему z=0 2 раза ? Что не так ? Сначало 0 потом когда индекс 1 тоже 0, а потом 2 становится, как и должно быть.

  2. Игорёк

    ошибку, нашёл устранил. Извиняюсь. что написал, не посомтрев более подробно.

  3. Игорёк

    сократить 2-ю задачу можно ли ?

    program zd49;
    const
     m = 3;
     type
        TMas1 = array [1..2*m+1] of real;
        TMas2 = array [-m..m] of real;
        var
        x:TMas1;
        y:TMas2 ;
        i,k,l:integer;
        begin
       for i:=1 to 2*m+1 do
       begin
       x[i]:=random(10);
       writeln(i,' ','x[',i,']','=',x[i]);
       end;
       for k:=-m to m do
       begin
       y[k]:=random(15);
        writeln(k,' ','y[',k,']','=',y[k]);
        end;
         writeln(' ');
         for l:=1 to 7 do
         begin
          for k:=-m to m do
          begin
          for i:=1 to 2*m+1 do
          begin
         if i=k+4 then
           begin
         x[i]:=x[i]+y[k];
         y[k]:=x[i]-y[k];
         x[i]:=x[i]-y[k];
         
    
        writeln(k,' ','y[',k,']','=',y[k]);
        writeln(i,' ','x[',i,']','=',x[i]);
           end;
          end;
         end;
        end;
       end.
    
  4. Taras

    Ты меняешь местами содержимое массивов. А в задаче требуется всего лишь скопировать содержимое x в y. Кроме того, не понятно зачем тебе внутренний цикл, если ты все равно что-то делаешь лишь на одном из его шагов (все таки цикл это способ сделать что-то много раз). Зачем тебе внешний цикл, кстати, тоже не понятно.

    Ну, и до кучи, чтобы вывести пустую строку достаточно написать writeln; без всяких скобок — сокращение аж на 5 символов!

  5. Игорёк

    ну да, это я заметил. Уже после того как сюда написал) просто решил не забивать) И редактировать нельзя) Хм, а разве не одно и тоже ? Т.е Сначло нахожу чему равны жлементы x а потом y. А потом меняю местами. А если копировать, то надо, тоже самое, только просто чтобы в х осталось всё прежнее а в y стало как в х?

  6. Taras

    >> А если копировать, то надо, тоже самое, только просто чтобы в х осталось всё прежнее а в y стало как в х?

    Да, именно так.

  7. Игорёк

    Сделал, спасибо)

  8. kmrt

    3 задание срочно

  9. Денис

    В 4 номере :
    Пункт 4 = пункту 6
    Пункт 7 — как можно выбросить элементы из массива, если их количество константа ?

  10. Taras

    В пункте 4 имеется в виду, что, например, из массива

    1 2 3 4

    получится

    4 1 2 3

    А в пункте 6 из него должен получиться

    2 1 4 3

    В 7-м пункте предлагается выбрасывать значения, то есть должно получиться

    1 3 0 0

  11. Дмитрий

    Скажите, господа, а как задать количество элементов массива не константой? Т.е. мне нужно задать количество элементов с клавиатуры. Напишите пожалуйста, как в таком случае объявить массив.

  12. оксана

    проверьте, пожалуйста, задание 4/4:
    const
    n=10;
    type
    TMas= array[0..n-1] of integer;
    var
    x: TMas;
    i,k,z,m: integer;
    begin
    for i:=0 to n-1 do
    x[i]:= random(30);
    k:=x[n-1];
    x[m]:=x[0];
    for i:=1 to n-1 do
    begin
    z:=x[i];
    x[i]:=x[m];
    x[m]:=z;
    end;
    x[0]:=k;
    for i:=0 to n-1 do
    write(x[i],’ ‘);
    end.

  13. оксана

    и заодно 4/5:
    const
    n=10;
    type
    TMas= array[0..n-1] of integer;
    var
    x: TMas;
    i,k,z,m: integer;
    begin
    for i:=0 to n-1 do
    begin
    x[i]:= random(30);
    write(x[i],’ ‘);
    end;
    writeln;
    m:=n-1;
    k:=n div 2;
    for i:=0 to m do
    begin
    if i< k then
    begin
    z:=x[i];
    x[i]:=x[m];
    x[m]:=z;
    m:=m-1;
    end;
    end;
    for i:=0 to n-1 do
    write(x[i],' ');
    end.

  14. оксана

    не совсем понимаю задание 4/7, как это выбросить элемент?

  15. Taras

    >> проверьте, пожалуйста, задание 4/4:

    Работает правильно. Но:
    1) Переменной m не присвоено никакое значение. Поскольку это так называемая глобальная переменная, то по умолчанию m = 0. Но полагаться на это — плохой стиль. Всегда надо явно присваивать значения.
    2) Суть твоего алгоритма — каждый элемент меняем местами с нулевым. Это приводит к нужному результату, но не эффективно. Подумай, как то же самое совершив примерно 3 раза меньше операций.
    3) Запоминание последнего и потом запись его в нулевой элемент при твоем подходе лишние. Там и так уже нужное значение.

    >> и заодно 4/5:

    Работает правильно, но:
    1) Менять конечное значение значение счетчика цикла for (m) в теле самого цикла это очень (очень!) плохой стиль. Формально допустимо, но так делать не надо. Это запутывает логику программы и служит источником труднообнаруживаемых ошибок.

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

    2) Конструкция

    for i:=0 to m do
    begin
      if i< k then
      begin
        ...
      end;
    end;

    напрашивается на очевидное упрощение.

    >> не совсем понимаю задание 4/7, как это выбросить элемент?

    Например было: 1, 2, 3, 4, 5, 6
    Должно стать: 1, 3, 5, 0, 0, 0

  16. оксана

    тогда 4/5 так будет?:


    Был текст программы.

    Что значит глобальная переменная? 4/4 чего-то никакие варианты больше в голову не приходят — попробую попозже

  17. Taras

    4/5 — да, так гораздо лучше. Можно еще не вводить m и менять местами i-й и (n-i-1)-й элементы. Но так тоже хорошо.

    Пока что у нас все переменные глобальные. Локальные появятся, когда речь пойдет о процедурах и функциях.

  18. оксана

    а можете написать свой вариант решения 4/4, ведь это будет не совсем подсказкой, поскольку одним способом я все-таки ее решила.Пожалуйста)) А потом сотрете из комментариев.

  19. Taras

    Это было бы не педагогично.

    Представь, есть у тебя ряд из ящичков (элементов массива). В каждом ящике лежит камень (значение). Нужно сдвинуть камни циклическим образом. За раз можно перемещать только один камень. Два камня в один ящик класть нельзя. Для временного хранения можно использовать дополнительные ящики (вспомогательные переменные). Неужели для циклической перестановки ты начнешь менять содержимое каждого ящика с содержимым первого? Это же совершенно не логично.

  20. оксана

    разложила на столе «ящики» — фантики и «камни» — пробки с номерами. Перекладывала, перекладывала и по сути у меня получилось почти то же самое, просто вместо нулевого ящика появился второй дополнительный:
    const
    n=10;
    type
    TMas= array[0..n-1] of integer;
    var
    x: TMas;
    i,z1,z2: integer;
    begin
    for i:=0 to n-1 do
    begin
    x[i]:= random(30);
    write(x[i],’ ‘);
    end;
    writeln;
    z1:=0;
    z2:=x[0];
    for i:=1 to n-1 do
    begin
    z1:=x[i];
    x[i]:=z2;
    z2:=z1;
    end;
    x[0]:=z2;
    for i:=0 to n-1 do
    write(x[i],’ ‘);
    end.

  21. Taras

    Представь, что каждый камень весит 50кг ))

    Вот, ты перетаскиваешь 0-й в ящик z2. // Тяжело
    1-й в ящик z1. // Уфф
    Бывший нулевой из z2 в 1-й. // А женское ли это дело?
    Бывший первый из z1 в z2. // «Я птица большая, я птица сильная…»

    // Перекур

    Сидишь и думаешь: «Нафига же я таскала нулевой сначала в z2, а только потом в 1-й. Что нельзя было сначала 1-й освободить, а потом нулевой туда сразу кинуть?»

  22. оксана

    )))))))))))))
    Я устала. болею. туплю. и не в состоянии сообразить — предыдущее замечание высмеивает только излишнее старание к перетаскиванию нулевого камня или весь цикл перетаскивания камней?))

  23. Taras

    Это касается всего цикла. Просто присутствие лишних действий становится очевидным уже на первом шаге. Второй камень, вообще, придется таскать по три раза: x[1] -> z1 -> z2 -> x[2]. Хотя, если сначала освободить x[2], то можно сразу переложить его в нужное место. И т.д.

    Выздоравливай!

  24. оксана

    я понимаю, что можно сделать цикл короче, но не могу оформить в программе, потому что из дополнительных двух ящиков назад придется брать камни то из одного, то из другого. Цикл будет все-таки for или другой?

  25. Taras

    Цикл for. Я, вообще, говорил не об уменьшении числа шагов цикла, а об уменьшении числа перекладываний. Например, можно на каждом шаге делать не 3 перекладывания, а меньше.

  26. оксана

    у меня получается так для i от 1 до 5: z1=x[2]; x[2]=x[1]; z2=x[3]; x[3]=z1; z1=x[4]; x[4]=z2; z2=x[5]; x[5]=z1. Получается два перекладывания, но не понимаю как оформить в программу((

  27. Taras

    В идеале нужно обойтись одним перекладыванием. Для x[1] это у тебя получилось. Но можно этого добиться и для остальных.

  28. оксана


    Был текст программы.

    Нда, оказывается все очень просто))) Я долго смеялась))) Столько времени потратить на такую в принципе простую задачу. Я уже боюсь браться за 4/7? Там много перекладываний? Или тоже все в принципе довольно просто?

  29. Taras

    Ура! )))

    В 4/7 — тоже просто.

  30. оксана

    готово! 4/7:


    Был текст программы.

  31. Taras

    Годится.

    В качестве усовершенствований напрашивается

    (n+1) div 2

    вместо выражения со сложно вычисляемым h.

    Ну, и, как вариант, вместо i+b можно написать 2*i-1.

  32. оксана

    ага, хорошо. Не знаю нужен ли в 5/1 abs:


    Был текст программы.

  33. Taras

    abs не планировался. Ну, да ладно.

  34. оксана

    если я правильно поняла задание 5/2 то наверное так:
    const
    n=10;
    type
    TMas= array[1..n] of integer;
    var
    x,y: TMas;
    i,s: integer;
    begin
    for i:=1 to n do
    begin
    x[i]:= random(30);
    write(x[i],’ ‘);
    end;
    writeln;
    s:=0;
    for i:=2 to n do
    begin
    y[i]:=s+x[i-1];
    s:=y[i];
    end;
    for i:=2 to n do
    write(y[i],’ ‘);
    end.
    а в восьмом задании надо так?: s:=0; for i:=1 to n do s =s+ x[i]*y[i]

  35. Taras

    5/2 — не совсем так. n в задании — это не количество элементов. Если например было:
    1, 2, 3, 4, 5
    то при n = 2 должно стать
    3, 5, 7, 9

    В 8-м все так.

  36. оксана

    5/2:
    const
    N=10;
    type
    TMas= array[1..N] of integer;
    var
    x,y: TMas;
    i,s,m,b: integer;
    begin
    for i:=1 to N do
    begin
    x[i]:= random(30);
    write(x[i],’ ‘);
    end;
    writeln;
    readln(m);
    b:=m-1;
    s:=0;
    for i:=1 to m do
    s:=x[i]+s;
    y[1]:=s;
    for i:=2 to N-b do
    begin
    y[i]:=s-x[i-1]+x[m+1];
    m:=m+1;
    s:=y[i];
    end;
    for i:=1 to N-b do
    write(y[i],’ ‘);
    end.

  37. Taras

    Правильно и даже эффективно. Небольшие замечания:

    1) Переменная s — явно лишняя. Никто не мешает использовать нужный элемент массива непосредственно.

    2) Не очень хорошо, что m это и количество элементов суммы и счетчик для вычисления номера очередного элемента. Для таких разных сущностей лучше предусмотреть разные переменные.

    3) А вот b явно лишняя. Лучше писать «N-m+1». Тут все элементы выражения понятны (общее число элементов, число элементов суммы), соответственно, и логика прозрачна. А вот введение дополнительной переменной «на 1 меньше, чем число элементов суммы» все только затуманивает.

  38. оксана

    задание 10:
    const
    N=10;
    type
    TMas= array[1..N] of integer;
    var
    x: TMas;
    i,min,max: integer;
    begin
    for i:=1 to N do
    begin
    x[i]:= random(30);
    write(x[i],’ ‘);
    end;
    writeln;
    max:=1;
    min:=1;
    for i:=2 to N do
    begin
    if x[i]>x[max] then
    max:=i;
    if x[i]<x[min] then
    min:=i;
    end;
    writeln('max= ',x[max],' index ',max);
    writeln('min= ',x[min],' index ',min);
    end.
    Но если встречаются два одинаковых элемента, то выводится только один из них.

  39. Taras

    Все правильно. Я, в общем, и имел в виду нахождение только одного элемента. Если хочешь все, можно или использовать дополнительный массив или еще раз пробежать по массиву и найти все элементы совпадающие с минимальным.

  40. оксана

    задание 11:
    const
    N=10;
    type
    TMas= array[1..N] of integer;
    var
    x: TMas;
    i,b,z: integer;
    begin
    for i:=1 to N do
    begin
    x[i]:= random(30);
    write(x[i],’ ‘);
    end;
    writeln;
    for i:=1 to n do
    begin
    for b:=1 to N do
    begin
    if x[i]<x[b] then
    begin
    z:=x[b];
    x[b]:=x[i];
    x[i]:=z;
    end;
    end;
    end;
    for i:=1 to N do
    write(x[i],' ');
    end.
    опять намудрила?

  41. Taras

    Оксан, этот алгоритм прекрасен! При всей внешней простоте я, наверное, не меньше часа потратил на то, чтобы понять почему он все-таки работает ))

    Итак,
    i = 1 — если элемент больше первого, меняем его с первым местами. В результате на первом месте будет самый большой элемент. Сразу ясно, что легко не будет )

    i = 2 — первым делом ставим самый большой элемент на второе место. Дальше ничего не происходит. Вообще стоит заметить, что при b = i-1 самый большой элемент сдвигается на одну позицию вправо, а при b >= i уже никаких изменений с массивом не происходит.

    i = 3 — если 1-й элемент больше третьего, то третий встанет на место первого, а бывший первый на место второго. Второй (тот, который заодно максимальный элемент) в любом случае переедет на третье место. Заметим, что первые три элемента после этого упорядочены по возрастанию.

    i > 3 — пока x[b] < x[i] ничего не происходит. Как только это условие нарушается, происходит твоя знаменитая неэффективная циклическая перестановка (все элементы сдвигаются вправо, а на освободившееся место ставится i-й). Главное, что при этом элементы с 1-го по i-й по прежнему упорядочены по возрастанию. И так цепочка упорядоченных элементов протягивается до конца массива. Круто! ))) PS. Метод выбора это найти наименьший элемент, поставить его на первое место. Затем найти наименьший, начиная со второго - поставить на второе место. И так далее, в неотсортированной части массива ищется наименьший элемент и ставится в ее начало.

  42. оксана

    ))))))
    честно говоря, я сама не понимаю как он работает, потому что по моей задумке условие должно было проверяться как
    if x[i]>x[b] then
    но тогда сортировка почему то происходила по убыванию, а по возрастанию, тогда я просто поменяла > на <. ))))
    А в методе выбора есть вложенные циклы?

  43. Taras

    Вложенные циклы — есть.

  44. оксана

    все равно прихожу к такому же алгоритму, может условие как то по другому надо ставить?

  45. Taras

    Откровенно говоря, не понимаю, как можно вообще прийти к такому алгоритму.

  46. оксана

    задание 11 еще раз))):
    const
    N=10;
    type
    TMas= array[1..N] of integer;
    var
    x: TMas;
    i,k,z,min: integer;
    begin
    for i:=1 to N do
    begin
    x[i]:= random(30);
    write(x[i],’ ‘);
    end;
    writeln;
    for i:=1 to N do
    begin
    z:=x[i];
    min:=i;
    k:=i+1;
    while k<=N do
    begin
    if x[k]<x[min] then
    min:=k;
    k:=k+1;
    end;
    x[i]:=x[min];
    x[min]:=z;
    end;
    for i:=1 to N do
    write(x[i],' ');
    end.

  47. Taras

    О, вот это — сортировка методом выбора )

    while немножко не по делу. Никто не мешает начать for с i+1.
    И еще внешний цикл делает один лишний шаг. Когда i = N, ничего не происходит.

  48. оксана

    Ура!!! До свидания, массивы! Здравствуйте, процедуры и функции!

  49. АленА

    Больше всего писали о задании 4.7 и 11, мои варианты:
    Program Zadanie_10_4_7;
    const
    m = 10;
    type
    TMas1 = array [1..m] of integer;
    var
    i, n, k: integer;
    x: TMas1;
    begin
    n:=0;
    write(‘x = ‘);
    for i:= 1 to m do
    begin
    n:=random(10);
    x[i]:=n;
    write(n, ‘ ‘);
    end;
    writeln;

    if (m mod 2) = 0 then
    begin
    write(‘x = ‘);
    k:=0;
    for i:= 1 to (m div 2) do
    begin
    x[i]:=x[i+k];
    k:=k+1;
    write(x[i], ‘ ‘);
    end;
    for k:= (m div 2+1) to m do
    begin
    x[k]:=0;
    write(x[k], ‘ ‘);
    end;
    end;

    if (m mod 2) 0 then
    begin
    write(‘x = ‘);
    k:=0;
    for i:= 1 to (m div 2+1) do
    begin
    x[i]:=x[i+k];
    k:=k+1;
    write(x[i], ‘ ‘);
    end;
    for k:= (m div 2+2) to m do
    begin
    x[k]:=0;
    write(x[k], ‘ ‘);
    end;
    end;
    end.

    Program Zadanie_10_11;
    const
    m = 10;
    type
    TMas1 = array [1..m] of integer;
    var
    n, k, i, c, d, r: integer;
    x: TMas1;
    begin
    n:=0;
    write(‘x = ‘);
    for i:= 1 to m do
    begin
    n:=random(100);
    x[i]:=n;
    write(n, ‘ ‘);
    end;
    writeln;

    write(‘x = ‘);
    for c:=1 to m do
    begin
    d:=x[c];
    r:=0;
    for k:=c+1 to m do
    begin
    r:=x[k]-d;
    if r<0 then
    begin
    x[c]:=x[k];
    x[k]:=d;
    d:=x[c];
    end;
    end;
    write(x[c], ' ');
    end;
    end.

  50. АленА

    В программе 4.7 пропустило знак больше перед 0 в сточке if (m mod 2)

  51. Darkhan

    program N10_11;{упорядочение методом выбора}
    const
    m=20;
    type
    TMas = array[0..m-1] of integer;
    var
    x:TMas;
    i, k, c, Kmin:integer;
    begin
    for i:=0 to m-1 do {присвоение значений}
    x[i]:=trunc(random(50));
    for i:=0 to m-1 do {вывод результата}
    write( x[i], ‘ ‘);
    writeln;
    for k:=0 to m-2 do {внешний цикл}
    begin
    Kmin:=k;
    for i:=k+1 to m-1 do {внутренний цикл}
    begin
    if x[i] < x[Kmin] then
    begin
    c:=x[i];
    x[i]:=x[Kmin];
    x[Kmin]:=c;
    end;
    end;
    end;
    for i:=0 to m-1 do {вывод результата}
    write( x[i], ' ');
    end.

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