Форум программистов, компьютерный форум, киберфорум
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 11.12.2017
Сообщений: 6
1

Все элементы массива, не равные нулю, переписать, сохраняя их порядок, в начало массива, а нулевые значения - в конец

02.04.2018, 08:07. Показов 3011. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Создать одномерный массив A[0..N-1]. Все его элементы, не равные нулю, переписать, сохраняя их порядок, в начало массива, а нулевые значения- в конец массива. Новый массив не заводить и сортировку не применять.
Как организовать сия программу?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.04.2018, 08:07
Ответы с готовыми решениями:

Все элементы, не равные нулю, переписать (сохраняя их порядок) в начало, а нулевые элементы – в конец массива
Задан одномерный массив. Все его элементы, не равные нулю, переписать (сохраняя их порядок) в...

одномерный массив. Все его элементы, не равные нулю, переписать, сохраняя их порядок в начало массива, а нулевые элементы в конец массива in c++
одномерный массив. Все его элементы, не равные нулю, переписать, сохраняя их порядок в начало...

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

Все элементы массива, не равные нулю, переписать (сохраняя их порядок) в начало массива
Дан одномерный массив. Все его элементы, не равные нулю, переписать (сохраняя их порядок) в начало...

5
Прощай, Мир!
1672 / 830 / 253
Регистрация: 26.05.2012
Сообщений: 3,056
02.04.2018, 12:29 2
переписывай нулевые значения в конец массива, т.к. в общем случае нулевое значение - одно единственное, а не равные нулю - множество значений.. ищи нулевое значение в массиве, сдвигай оставшуюся часть массива на один элемент ближе к началу и помещай нулевое значение в самый конец.. и так в цикле пока не пройдут все элементы массива..
0
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
03.04.2018, 07:54 3
Не нужно ничего сдвигать.
Нужны два указателя, на первый "ноль" и на первый "не ноль" и обменивать содержимое по этим указателям с поиском следующего.
На Pascal
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
program test;
 
var
  A: array [0..9] of integer;
  Indx0, Indx1: integer;
  i: integer;
  temp: integer;
begin
  {заполнение массива}
  randomize;
  for i := low(A) to high(A) do
    if random(10) > 4 then
      A[i] := random(20) - 10
    else
      A[i] := 0;
  for i := low(A) to high(A) do
    Write(A[i]: 4);
  writeln;
  {поиск первого нулевого элемента}
  Indx0 := low(A);
  while (Indx0 <= high(A)) do
  begin
    if A[Indx0] = 0 then
      break;
    Inc(Indx0);
  end;
  {поиск следующего за нулевым элементом ненулевого}
  Indx1 := Indx0 + 1;
  while (Indx1 <= high(A)) do
  begin
    if A[Indx1] <> 0 then
    begin
    {перестановка первого нулевого и
    следующего за ним ненулевого элементов}
      A[Indx0] := A[Indx1];
      A[Indx1] := 0;
      Inc(Indx0);
      while (Indx0 <= high(A)) do
      begin
        if A[Indx0] = 0 then
          break;
        Inc(Indx0);
      end;
      Indx1 := Indx0;
    end;
    Inc(Indx1);
  end;
  {вывод результатов}
  for i := low(A) to high(A) do
    Write(A[i]: 4);
  writeln;
end.
Можно увидеть, что часть кода повторяется (поиск первого нулевого элемента). Поэтому, хотя в Pascal это было бы предосудительно, но в Assembler можно сделать переход внутрь цикла и внутрь условия if.

Добавлено через 7 минут
Или же не сокращать код за счёт перехода внутрь if, но тогда удалить строку 44, чтобы поиск следующего ненулевого элемента не возвращался "назад", а продолжил дальше.
0
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
07.04.2018, 18:36 4
Без ввода массива.
Да и алгоритм упростил, чтобы легче реализовать на цепочечных командах
Assembler
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
LOCALS
 
.model small
 
.stack 100h
 
.data
        CrLf            db      0Dh, 0Ah, '$'
        msgInstance     db      'Instance:', 0Dh, 0Ah, '$'
        msgResult       db      'Result:', 0Dh, 0Ah, '$'
        msgPressAnyKey  db      'Press any key to exit...', '$'
        N               dw      10
        Array           dw      48, -60, 0, 109, 111, 0, 0, 107, -128, 93
.code
 
;Вывод массива слов (word)
;cx - количество выводимых элементов
;ds:dx - адрес массива слов
ShowArray       proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
 
        jcxz    @@Exit          ;если массив пустой - завершить
 
        mov     si,     1       ;индекс элемента массива
        mov     di,     dx      ;адрес текущего элемента массива
        @@ForI:
                mov     ax,     [di]
                call    Show_AX
                mov     ah,     02h
                mov     dl,     ' '
                int     21h
                ;переход к следующему элементу
                inc     si
                add     di,     2
        loop    @@ForI
@@Exit:
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
ShowArray       endp
 
; выводит знаковое 16-разрядное число из регистра AX на экран
; с выравниванием на 8 позиций по правому краю
; входные данные:
; ax - число для отображения
Show_AX proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
 
        mov     cx,     10      ;основание системы счисления
        xor     di,     di      ; di - кол. цифр в числе
        xor     si,     si      ; si - признак отрицательного числа
        ; если число в ax отрицательное, то
        ;1) напечатать (запомнить в стеке) символ '-'
        ;2) сделать ax положительным
        or      ax,     ax
        jns     @@Conv
        mov     si,     1
 
        neg     ax
 
@@Conv:
        xor     dx,     dx
        div     cx              ; dl = num mod 10
        add     dl,     '0'     ; перевод в символьный формат
        inc     di
        push    dx              ; складываем в стек
        or      ax,     ax
        jnz     @@Conv
        ;если число отрицательное - помещаем символ "-" в строку
        or      si,     si
        jz      @@Positive
        mov     dx,     '-'
        push    dx
        inc     di
@@Positive:
        ; выводим из стека на экран
        ; - сначала пробелы для выравнивания по правому краю
        mov     cx,     6
        sub     cx,     di
        mov     ah,     02h
        mov     dl,     ' '
@@LeftPad:
        int     21h
        loop    @@LeftPad
        ;сохранённые символы цифр
@@Show:
        pop     dx              ; dl = очередной выводимый символ
        mov     ah,     2       ; ah - функция вывода символа на экран
        int     21h
        dec     di              ; повторяем пока di<>0
        jnz     @@Show
 
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
Show_AX endp
 
main    proc
        ;инициализация сегментного регистра ds адресом сегмента данных
        mov     ax,     @data
        mov     ds,     ax
 
        ;вывод исходного массива
        mov     ah,     09h
        lea     dx,     [msgInstance]
        int     21h
        lea     dx,     [Array]
        mov     cx,     [N]
        call    ShowArray
        mov     ah,     09h
        lea     dx,     [CrLf]
        int     21h
 
        ;обработка массива
        mov     ax,     ds
        mov     es,     ax
        cld
        @@while:
                ; - поиск первого нулевого элемента
                lea     di,     [Array]
                mov     cx,     [N]
                mov     ax,     0
                repne   scasw
                jnz     @@StopProcess
                mov     bx,     di      ;Indx0
                sub     bx,     2
                ; - поиск следующего за нулевым элементом ненулевого
                jcxz    @@StopProcess
                repe    scasw
                je      @@StopProcess
                        mov     dx,     [di-2]
                        mov     [bx],   dx
                        mov     [di-2], ax
                jmp     @@while
@@StopProcess:
        ;вывод результата
        mov     ah,     09h
        lea     dx,     [msgResult]
        int     21h
        lea     dx,     [Array]
        mov     cx,     [N]
        call    ShowArray
        mov     ah,     09h
        lea     dx,     [CrLf]
        int     21h
        ;ожидание нажатия любой клавиши
        mov     ah,     09h
        lea     dx,     [msgPressAnyKey]
        int     21h
 
        mov     ah,     00h
        int     16h
 
        mov     ax,     4C00h
        int     21h
main    endp
 
end     main
0
3406 / 1825 / 489
Регистрация: 28.02.2015
Сообщений: 3,696
10.04.2018, 13:59 5
Вариант предложенный proc3nt, и проще и покрасивей будет
Assembler
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
model   small
.stack
.data
Array   dw  1, 2, 0, 4, 5, 0, 0, 8, 9, 10
szArray equ ($-Array)/2
.code
begin:  mov ax,@data
    mov ds,ax
    mov es,ax
    lea di,array
    xor ax,ax
    mov cx,szArray
;начало
@@01:   repne   scasw
    jcxz    @@02
    mov si,di
    sub di,2
    push    di
    push    cx
    rep movsw
    mov [di],ax
    pop cx
    pop di
    jmp @@01
;конец
@@02:   xor ax,ax
    int 16h
    mov ax,4c00h
    int 21h
    end begin
1
Модератор
Эксперт по электронике
8476 / 4335 / 1642
Регистрация: 01.02.2015
Сообщений: 13,461
Записей в блоге: 8
10.04.2018, 17:42 6
Constantin Cat, согласен с оговорками.
На ассемблере код короче, но не эффективнее.
На Pascal реализация за 1 проход. Но на асме я запутался и сделал, как сделал, о чём честно и написал.
0
10.04.2018, 17:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.04.2018, 17:42
Помогаю со студенческими работами здесь

Все элементы массива, не равные нулю, переписать (сохраняя их порядок) в начало массива
Задан одномерный массив. Все его элементы, не равные нулю, переписать (сохраняя их порядок) в...

В каждой строке все элементы, не равные нулю, переписать в начало строки, а нулевые элементы – в конец массива
Дан двумерный массив. В каждой строке все его элементы, не равные нулю, переписать (сохраняя...

Все элементы массива, не равные нулю, перепишите, сохраняя их порядок, в начало массива
Дан одномерный массив. Все его элементы, не равные нулю, перепишите (сохраняя их порядок) в начало...

Переписать элементы массива, не равные нулю, в начало массива, а нулевые элементы - в конец массива
Дан одномерный массив. Все его элементы, не равные нулю, перепишите (сохраняя их порядок) в начало...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru