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

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

29.05.2010, 11:10. Просмотров 147119. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.05.2010, 11:10
Ответы с готовыми решениями:

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

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

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

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

Основные операции с матрицами
Определить значение матричного многочлена f(x)=A*A*A+2*A*A-3*A-5*E; -2 0 3 A= 9 ...

36
Даня98
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
Sagittarius
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
Севак
любитель покушать
682 / 634 / 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
SeryZone
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
Erea
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
APALoff
1638 / 1067 / 1080
Регистрация: 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
Puporev
Модератор
55065 / 42330 / 29232
Регистрация: 18.05.2008
Сообщений: 100,027
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
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26351 / 17679 / 7001
Регистрация: 22.10.2011
Сообщений: 31,114
Записей в блоге: 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
Puporev
Модератор
55065 / 42330 / 29232
Регистрация: 18.05.2008
Сообщений: 100,027
23.10.2014, 16:07 29
Согласен, лажанулся...
0
roma070201
0 / 0 / 0
Регистрация: 08.10.2014
Сообщений: 41
06.12.2014, 22:31 30
Цитата Сообщение от Unrealler Посмотреть сообщение
if (j=n) then r:=a[n] else a[j+1]:=a[j];
можно ли написать без if'а , а как-нибудь по другому?
0
JokeR.BY
CAPITAL OF ROCK!
1278 / 705 / 982
Регистрация: 03.03.2010
Сообщений: 2,284
Завершенные тесты: 2
07.12.2014, 04:56 31
roma070201, как вы себе это представляете? тут же совершенно разные переменные.
0
Mawrat
12830 / 5738 / 1700
Регистрация: 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
bormant
Модератор
Эксперт Pascal/DelphiЭксперт NIX
4058 / 2671 / 2140
Регистрация: 22.11.2013
Сообщений: 7,484
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
bormant
Модератор
Эксперт Pascal/DelphiЭксперт NIX
4058 / 2671 / 2140
Регистрация: 22.11.2013
Сообщений: 7,484
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
bormant
Модератор
Эксперт Pascal/DelphiЭксперт NIX
4058 / 2671 / 2140
Регистрация: 22.11.2013
Сообщений: 7,484
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
bormant
Модератор
Эксперт Pascal/DelphiЭксперт NIX
4058 / 2671 / 2140
Регистрация: 22.11.2013
Сообщений: 7,484
07.04.2018, 12:37 36
И еще один однопроходный вариант вращения [fst,fst+cnt) на shift элементов (<0 -- влево, >0 -- вправо).
по мотивам http://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
Вадим Мошев
^
378 / 43 / 16
Регистрация: 23.07.2014
Сообщений: 211
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
14.09.2018, 15:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.09.2018, 15:48

Операции с матрицами в Pascal
Здравствуйте!Помогите пожалуйста с написанием программы для следующей задачи: Дана матрица размера...

Выполнить операции с квадратными матрицами
2. Выполнить операции (здесь A, B, C, D — квадратные матрицы порядка n) (B^T)*(C^T)*(D^T)

Арифметические операции над матрицами
Выполнив действия над матрицами A(n,n) и B(n,n) вычислить матрицу C(n,n) по формуле...


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

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

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