Форум программистов, компьютерный форум, киберфорум
Pascal (Паскаль)
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.92/911: Рейтинг темы: голосов - 911, средняя оценка - 4.92
654 / 352 / 113
Регистрация: 11.12.2009
Сообщений: 508
1

Стандартные операции с массивами (матрицами)

29.05.2010, 11:10. Просмотров 176815. Ответов 36

-------------------------------------------------------------------------------------------
Содержание:
  1. "Переворот" массива
  2. Сдвиг массива на k элементов влево или вправо
  3. Сдвиг массива на k элементов влево или вправо за линейное время
  4. Поиск минимума/максимума и их индексов
  5. Поиск минимума/максимума и их индексов в двумерном массиве (матрице)
  6. Работа с элементами выше/ниже/на главной/побочной диагоналях
  7. Транспонирование матрицы относительно главной и побочной диагоналей
  8. Поворот двумерного массива на 90° по часовой стрелке
  9. Поворот на 90 градусов по часовой стрелке и против без использования дополнительного массива
  10. Удаление элемента в одномерном массиве
  11. Удаление строк и столбцов по условию
  12. Цифровая сортировка (DigidalSort)
  13. Удаление всех строк и столбцов, содержащих хотя бы 1 ноль
  14. Двоичный (бинарный) поиск
  15. Работа с матрицей одним циклом
  16. Заполнение массива случайными неповторяющимися значениями
  17. Заполнение массива змейкой из левого верхнего угла
  18. Заполнение массива змейкой снизу вверх построчно
  19. Удалить все элементы, которые встречаются больше 1 раза
  20. Удаление элементов в одномерном несортированном массиве по условию
  21. Заполнение массива по спирали
  22. Построение синусоиды на двумерном массиве(матрице) из точек(.)
  23. Вставка нового столбца в матрицу со сдвигом исходных элементов
  24. Вставка новой строки в матрицу со сдвигом исходных элементов
  25. Переворот матрицы на 90° по часовой стрелке
  26. Заполнение массива неповторяющимися значениями
-------------------------------------------------------------------------------------------





1) Очень часто на форуме просят "переворот" массива. Например, было
Код
1 2 3 4 5
Стало
Код
5 4 3 2 1
Осуществляется это так:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var
   a:array[1..100] of integer;
   i,r,n:integer;
begin
 readln(n); {читаем размер массива}
 for i:=1 to n do
  read(a[i]);
 for i:=1 to n div 2 do   {сам "переворот"}
  begin
   r:=a[i];
   a[i]:=a[n-i+1];
   a[n-i+1]:=r;
  end;
 for i:=1 to n do
  write(a[i],' ');
 readln
end.
2) Не менее возникает вопрос о сдвиге массива на k элементов влево или вправо.
Было
Код
1 2 3 4 5
Стало
Код
5 1 2 3 4
Сдвиг влево на k элементов:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var
   a:array[1..100] of integer;
   i,r,n,k,j:integer;
begin
 read(n,k);  {k обозначает величину сдвига}
 for i:=1 to n do
  read(a[i]);
 for i:=1 to k do
  begin
   for j:=1 to n do
    if (j=1) then r:=a[j] else a[j-1]:=a[j];
   a[n]:=r;
  end;
 for i:=1 to n do
  write(a[i],' ');
 readln
end.
Сдвиг на k элементов вправо:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var
   a:array[1..100] of integer;
   i,r,n,k,j:integer;
begin
 read(n,k);  {k обозначает величину сдвига}
 for i:=1 to n do
  read(a[i]);
 for i:=1 to k do
  begin
   for j:=n downto 1 do
    if (j=n) then r:=a[n] else a[j+1]:=a[j];
   a[1]:=r;
  end;
 for i:=1 to n do
  write(a[i],' ');
 readln
end.
38
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.05.2010, 11:10
Ответы с готовыми решениями:

Стандартные операции с матрицами
Очень прошу, помогите, кто чем сможет) буду очень благодарна... Написать программы и если можно,...

Стандартные операции с массивами
Можете помочь? Завтра сдавать : 1) Вести массив A(N). Найти среднее геометрическое значение...

Операции с массивами и матрицами, подсчет кол-ва столбцов содержащих отрицательные элементы.
Нужна помощь с таким заданием: Если в прямоугольной матрице меньше половины столбцов содержит...

Стандартные мат. операции с двумерными массивами
Возможно ли вычитание и другие стандартные мат. операции с двумерными массивами как с векторами?...

36
29 / 29 / 18
Регистрация: 13.02.2010
Сообщений: 145
29.07.2011, 14:16 21
Заполнение массива по спирали
Очень часто это задание попадается для разминки.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
uses crt;
var a: array [1..100,1..100] of integer;
    i,m,k,n: integer;
begin
writeln ('Vvesti chislo');
readln (n);
k:=0;
m:=0;
repeat
for i:= m+1 to n-m do
begin
inc (k);                      
a[i,m+1]:= k;
end;
for i:= m+2 to n-m do
begin                             
inc (k);
a[n-m,i]:= k;
end;
for i:= n-m-1 downto m+1 do
begin
inc (k);                                  
a[i,n-m]:= k;
end;
for i:= n-m-1 downto m+2 do
begin
inc (k);
a[m+1,i]:=k;
end;
inc (m);
until m+1=n div 2 + 2;
for i:= 1 to n do
begin
for k:= 1 to n do
write (a[i,k]:3,' ');
writeln;
end;
end.
6
16 / 9 / 4
Регистрация: 10.01.2012
Сообщений: 54
14.01.2012, 19:19 22
Построение синусоиды на двумерном массиве(матрице) из точек(.)

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
program project1;
uses crt;
const w=79;{Ширина массива} h=22; {Высота массива}
var i,j,k: integer;
    arr: array [1..h,1..w] of char; 
begin
    ClrScr; {Очищаем экран}
        {Заполняем массив точками '.'}
    for j:=1 to h do
        for i:=1 to w do
        begin
            arr[j,i]:='.';
        end;
        {Запоняем некоторые элементы массива,
            которые выявляются по формуле, звездочками '*'} 
    for j:=1 to w do
    begin
         k:=round((sin(3.0*j*PI/w)+1)/2*h);
         arr[k,j]:='*';
    end;
        {Выводем массив}
  for j:=1 to h do
  begin
    writeln;
        for i:=1 to w do
            write(arr[j,i]);
   end;
 
   readln;
end.
Примерно так:
Стандартные операции с массивами (матрицами)
2
любитель покушать
685 / 637 / 248
Регистрация: 25.09.2011
Сообщений: 1,313
15.03.2012, 12:33 23
Думаю кому-нибудь будет полезно: вставление нового столбца в матрицу со сдвигом исходных элементов, например: вставить столбец между 5 и 6 столбцом исходной матрицы.

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
uses crt;
var
a: array[1..10,1..12] of integer;
b: array[1..10] of integer;
i,k,n,j,q: integer;
 
begin
write('Введите размерность матрицы, не больше 10 и не меньше 6 : ');
repeat
read(n);
until (n>=6) and (n<11);
 
writeln('Введите элементы одномерного массива:');
for k:=1 to n do begin
read(b[k]);
end;
 
write('В какой столбец будут вставляться элементы: ');
repeat
read(q);
until (q>=1) and (q<=n);
 
writeln('Для вывода результата нажмите ENTER...');
readln;
clrscr;
 
write('Исходная матрица:');
writeln;
for i:=1 to n do begin
for j:=1 to n do begin
a[i,j]:=random(10);
write(a[i,j]:4);
end;
writeln;
end;
 
for j:=n+1 downto q do begin
for i:=1 to n do begin
a[i,j+1]:=a[i,j];
end;
end;
 
for i:=1 to n do begin
a[i,q]:=b[i];
end;
 
writeln;
writeln('Полученная матрица:');
for i:=1 to n do begin
for j:=1 to n+1 do begin
write(a[i,j]:4);
end;
writeln;
end;
end.
Добавлено через 9 минут
аналогично предыдущей программе, только вставление строки:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
uses crt;
var
a: array[1..12,1..10] of integer;
b: array[1..10] of integer;
i,k,n,j,q: integer;
 
begin
write('Введите размерность матрицы, не больше 10 и не меньше 6 : ');
repeat
read(n);
until (n>=6) and (n<11);
 
writeln('Введите элементы одномерного массива:');
for k:=1 to n do begin
read(b[k]);
end;
 
write('В какую строку будут вставляться элементы: ');
repeat
read(q);
until (q>=1) and (q<=n);
 
writeln('Для вывода результата нажмите ENTER...');
readln;
clrscr;
 
write('Исходная матрица:');
writeln;
for i:=1 to n do begin
for j:=1 to n do begin
a[i,j]:=random(10);
write(a[i,j]:4);
end;
writeln;
end;
 
for i:=n+1 downto q do begin
for j:=1 to n do begin
a[i+1,j]:=a[i,j];
end;
end;
 
for i:=1 to n do begin
a[q,i]:=b[i];
end;
 
writeln;
writeln('Полученная матрица:');
for i:=1 to n+1 do begin
for j:=1 to n do begin
write(a[i,j]:4);
end;
writeln;
end;
end.
1
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
09.04.2012, 19:54 24
А вот моя разработка переворота на 90о по часовой стрелке!
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var
  a: array[1..50, 1..50] of longint;
  i, j, n, m: integer;
 
begin
  readln(n, m); 
  if (n >= 1) and (m >= 1) and (n <= 50) and (m <= 50) then
  begin
    for i := 1 to n do
      for j := 1 to m do
        read(a[i, j]);
    writeln(m,' ',n);
    for i:=1 to m do
    begin
      for j := n downto 1 do
        if (j>1) then write(a[j,i], ' ') else write(a[j,i]);
      if (i<m) then writeln;
    end;
  end;
end.
1
130 / 54 / 27
Регистрация: 13.03.2013
Сообщений: 162
25.04.2013, 00:08 25
Заполнение массива неповторяющимися значениями:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
program Myprogram;
type Tarr = array of integer;
 
procedure FillArray(var a:Tarr; n, r1, r2: integer);{a - массив;
                                                     n - длина массива;
                                                     r1, r2 - диапазоны рандома}
var i, j: integer;
    p: boolean;
begin
randomize;
setlength(a,n);
if r2-r1<n then begin
for i:=1 to n-1 do a[i]:=random(r2-r1+1)+r1;
end else begin
a[0]:=random(r2-r1+1)+r1;
p:=false;
for i:=1 to n-1 do begin
    repeat
    a[i]:=random(r2-r1+1)+r1;
    p:=false;
    for j:=0 to i-1 do begin
    if a[j]=a[i] then p:=true;
    end;
    until p=false;
end;
end;
end;
 
procedure WriteArray(a: Tarr);
var i: integer;
begin
for i:=0 to length(a)-1 do begin
write(a[i]:4);
end;
writeln;
end;
 
var MyArray: Tarr;
begin
FillArray(MyArray, 10, 0, 10);
WriteArray(MyArray);
readln;
end.
0
1642 / 1071 / 1081
Регистрация: 03.07.2013
Сообщений: 4,507
23.10.2014, 15:48 26
16)
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Const n=5;
Var
  m   : array[1..n,1..n] of Integer;
  i,j : Byte;
Begin
  For i:=1 to n do
   For j:=1 to n do m[i,Ord(not Odd(i))*(n+1-j)+Ord(Odd(i))*j]:=(i-1)*n+j;
  
  For i:=1 to n do
  Begin
    For j:=1 to n do Write(m[i,j]:4);
    Writeln;
  end;
end.
0
Модератор
62540 / 46714 / 32197
Регистрация: 18.05.2008
Сообщений: 113,060
23.10.2014, 15:57 27
В простом АВС это не рулит, а количество циклов нужно сократить.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Const n=5;
Var
  m   : array[1..n,1..n] of Integer;
  i,j : Byte;
Begin
For i:=1 to n do
 begin
  For j:=1 to n do
   begin
    m[i,Ord(not Odd(i))*(n+1-j)+Ord(Odd(i))*j]:=(i-1)*n+j;
    Write(m[i,j]:4);
   end;
  Writeln;
 end;
end.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
30770 / 20101 / 7853
Регистрация: 22.10.2011
Сообщений: 34,920
Записей в блоге: 6
23.10.2014, 16:04 28
Цитата Сообщение от Puporev Посмотреть сообщение
количество циклов нужно сократить
Только не в ущерб правильности ответа. Приведенный в посте №27 код работает некорректно:
Код
   1   2   3   4   5
   0   0   8   7   6
  11  12  13  14  15
   0   0  18  17  16
  21  22  23  24  25
0
Модератор
62540 / 46714 / 32197
Регистрация: 18.05.2008
Сообщений: 113,060
23.10.2014, 16:07 29
Согласен, лажанулся...
0
0 / 0 / 0
Регистрация: 08.10.2014
Сообщений: 44
06.12.2014, 22:31 30
Цитата Сообщение от Unrealler Посмотреть сообщение
if (j=n) then r:=a[n] else a[j+1]:=a[j];
можно ли написать без if'а , а как-нибудь по другому?
0
CAPITAL OF ROCK!
1280 / 707 / 982
Регистрация: 03.03.2010
Сообщений: 2,286
07.12.2014, 04:56 31
roma070201, как вы себе это представляете? тут же совершенно разные переменные.
0
13058 / 5844 / 1705
Регистрация: 19.09.2009
Сообщений: 8,807
07.12.2014, 12:28 32
Цитата Сообщение от roma070201 Посмотреть сообщение
можно ли написать без if'а , а как-нибудь по другому?
С учётом окружающего кода - можно. Имеем:
Pascal
1
2
3
4
5
6
for i:=1 to k do
begin
  for j:=n downto 1 do
    if (j=n) then r:=a[n] else a[j+1]:=a[j];
  a[1]:=r;
end;
Тогда без IF будет так:
Pascal
1
2
3
4
5
6
7
for i:=1 to k do
begin
  r := a[n]; 
  for j:= n - 1 downto 1 do
    a[j+1]:=a[j];
  a[1]:=r;
end;
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
5666 / 3386 / 2424
Регистрация: 22.11.2013
Сообщений: 9,513
Записей в блоге: 1
15.01.2017, 15:31 33
Лучший ответ Сообщение было отмечено ZX Spectrum-128 как решение

Решение

Сдвиг массива на k элементов за линейное время
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{ сдвиг массива a на n элементов (вправо для n>0, влево для n<0 }
procedure rotate(var a: array of Integer; n: Integer);
  procedure rev(b, e: Integer);
  var t: Integer;
  begin
    while b<e do begin
      t:=a[b]; a[b]:=a[e]; a[e]:=t;
      Inc(b); Dec(e);
    end;
  end;
begin
  n:=n mod (High(a)+1); if n=0 then Exit;
  if n<0 then Inc(n,High(a)+1);
  rev(Low(a),High(a)); rev(0,n-1); rev(n,High(a));
end;
3
Модератор
Эксперт Pascal/DelphiЭксперт NIX
5666 / 3386 / 2424
Регистрация: 22.11.2013
Сообщений: 9,513
Записей в блоге: 1
24.10.2017, 19:46 34
Лучший ответ Сообщение было отмечено ildwine как решение

Решение

А вот еще более эффективный сдвиг (за один проход):
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure vRotate(var a: array of Integer; shift: Integer); {+ влево, - вправо}
var b, c, t, size: Integer;
begin
  size:=High(a)+1;
  shift:=shift mod size; if shift<0 then Inc(shift,size);
  if shift=0 then Exit;
  b:=0;
  while (b<>shift) and (shift<>size) do begin
    c:=shift;
    while (b<>shift) and (c<>size) do begin
      t:=a[b]; a[b]:=a[c]; a[c]:=t;
      Inc(b); Inc(c);
    end;
    if b=shift then shift:=c;
  end;
end;
0
Модератор
Эксперт Pascal/DelphiЭксперт NIX
5666 / 3386 / 2424
Регистрация: 22.11.2013
Сообщений: 9,513
Записей в блоге: 1
08.02.2018, 16:00 35
И еще циклический сдвиг за один проход фрагмента массива [fst,lst) так, что mid становится на место fst:
Pascal
1
2
3
4
5
6
7
8
9
10
11
procedure vRotate(var a: array of Integer; fst, mid, lst: Integer);
var nxt: Integer; t: Integer;
begin
  nxt:=mid;
  while fst<>nxt do begin
    t:=a[fst]; a[fst]:=a[nxt]; a[fst]:=t;
    Inc(fst); Inc(nxt);
    if      nxt=lst then nxt:=mid
    else if fst=mid then mid:=nxt;
  end;
end;
то же самое на указателях (предполагается, что эти указатели образованы из элементов одного массива!!!):
Pascal
1
2
3
4
5
6
7
8
9
10
11
procedure vRotate(fst, mid, lst: PInteger);
var nxt: PInteger; t: Integer;
begin
  nxt:=mid;
  while fst<>nxt do begin
    t:=fst^; fst^:=nxt^; fst^:=t;
    Inc(fst); Inc(nxt);
    if      nxt=lst then nxt:=mid
    else if fst=mid then mid:=nxt;
  end;
end;
2
Модератор
Эксперт Pascal/DelphiЭксперт NIX
5666 / 3386 / 2424
Регистрация: 22.11.2013
Сообщений: 9,513
Записей в блоге: 1
07.04.2018, 12:37 36
И еще один однопроходный вариант вращения [fst,fst+cnt) на shift элементов (<0 -- влево, >0 -- вправо).
по мотивам https://www.cyberforum.ru/post4788988.html
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure vRotate(var a: array of Integer; fst, cnt, shift: Integer);
var t: Integer;
begin
  if cnt < 2 then Exit;
  shift:=shift mod cnt; if shift = 0 then Exit;
  if       shift > cnt shr 1 then Dec(shift,cnt)
  else if -shift > cnt shr 1 then Inc(shift,cnt);
  if shift > 0 then
    for fst:=fst-shift+cnt-1 downto fst do begin
      t:=a[fst+shift]; a[fst+shift]:=a[fst]; a[fst]:=t;
    end
  else
    for fst:=fst-shift to fst+cnt-1 do begin
      t:=a[fst+shift]; a[fst+shift]:=a[fst]; a[fst]:=t;
    end;
end;
1
^
419 / 48 / 16
Регистрация: 23.07.2014
Сообщений: 278
14.09.2018, 15:48 37
Преобразование двумерного массива (матрицы) в одномерный.
Задача простая, но её решение часто спрашивается. Публикую только "решающую часть", то есть, саму обработку. Объявление переменных, инициализацию, ввод данных и их вывод я опустил.
Pascal
1
2
3
4
5
6
7
8
9
10
11
{Предположим, что двумерный массив с его размерность уже задана}
 
arrayElementsNumber:=0;
for i:=1 to rowsNumber do begin
    for j:=1 to columnsNumber do begin
        inc(arrayElementsNumber);
        a[arrayElementsNumber]:=matrix[i, j];
    end;
end;
 
{На выходе имеем одномерный массив, хранящийся в переменной a. Размерность этого массива равна arrayElementsNumber}
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.09.2018, 15:48

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Класс: Разработать класс для работы с матрицами(операции над матрицами)...
Добрый вечер, хочу попросить о помощи с отловом проблемы. Сама задача: разработать класс для...

Стандартные алгоритмы работы с одномерными массивами
1. Ввод массива целых чисел. 2. Вывод массива в строку. 3. Найти минимальный элемент. Найти...

Работа с массивами и матрицами
1.Реализуйте проект «Массив». Кнопка «Заполнить» формирует массив из десяти случайных целых чисел в...

Как работать с массивами и матрицами?
Как работать с массивами и матрицами?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.