0 / 0 / 0
Регистрация: 11.07.2016
Сообщений: 1
1

В массиве удалить элементы, меньшие среднего арифметического элементов массива

11.07.2016, 14:17. Показов 1597. Ответов 13

Author24 — интернет-сервис помощи студентам
"В массиве удалить элементы, меньшие среднего арифметического элементов массива."
Надо написать самым простым способом
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.07.2016, 14:17
Ответы с готовыми решениями:

Расчет СА (среднего арифметического) отрицательных элементов массива. Заменить минимальный элемент в массиве на СА
СА- среднее арифметическое Помогите написать часть которая будет считать СА, находить...

Заменить все элементы, значение которых меньше среднего арифметического всех элементов массива на нулевые
Мое задание: Заменить все элементы, значение которых меньше среднего арифметического всех элементов...

Emu8086 элементы больше среднего арифметического удалить
data segment mas1 dw 2, 4, 6, 8, 10 mas2 dw 5 dup (?) n dw 0 s dw 0...

Заменить четные по значению элементы на значение среднего арифметического всех элементов массива
Задание такое: Заменить четные по значению элементы на значение среднего арифметического всех...

13
Прощай, Мир!
1672 / 830 / 253
Регистрация: 26.05.2012
Сообщений: 3,056
11.07.2016, 19:24 2
начни писать тогда и помощь будет..
0
Модератор
Эксперт по математике/физике
5272 / 4054 / 1389
Регистрация: 30.07.2012
Сообщений: 12,429
12.07.2016, 18:20 3
bodi_124
Читайте Правила форума, пункт 4.7. Как можно более полно описывайте суть проблемы или вопроса, что было сделано для ее решения и какие результаты получены.
0
183 / 121 / 26
Регистрация: 18.05.2015
Сообщений: 509
13.07.2016, 12:34 4
bodi_124, наверняка методичка есть?
0
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 914
16.07.2016, 18:35 5
Изучаю ассемблер. Решил попробовать решить данную задачу. Вот что получилось:
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
org 100h
 
  jmp start1
;======================================
length db 10
array db 22,7,12,18,5,13,8,23,2,14
 
m3:
  mov word[bx], 0
  dec cx
  jcxz exit      ; отдельное условие проверки CX на 0, т.к loop это делает не явно
  jmp m2
  
;=======================================
start1:
  mov dx, 0
  
  mov bx, array
  movzx cx, [length]
m1:
  mov ax, [bx]
  add dx, ax
  inc bx
  loop m1
  mov cl, [length]
  mov dh, 0
  mov ax, dx    
  div cl               ; в AX среднее арифметич.
  
m2:
  dec bx
  cmp [bx], al
  jl m3       ; Переход если ср. арифметич. больше элемента массива
  loop m2
  exit:
  mov ax, 4C00h
  int 21h
Все что меньше среднего арифметического записываю 0. Возможно лучший вариант был бы сдвигать, если кто нибудь подскажет как это сделать - буду благодарен. Так же есть небольшая проблема в моем решении: не знаю как еще и остаток проверять. Т.к среди элементов есть число 12, а ср. арифметическое 12 и остаток 4, а по моему условию он четко считает что эту 12 обнулять не нужно. Спасибо за ответы! P.S свое решение не очень нравится, т.к мне кажется что слишком много меток и условий для данной задачи
0
197 / 89 / 15
Регистрация: 10.07.2016
Сообщений: 146
16.07.2016, 22:03 6
Твоё решение более менее близко к оптимальному для данной задачи. Однако пройдёмся по пунктам:
1. строка 16 - обычно для этого используют XOR
2. строка 18 - указатель на массив лучше поместить в SI, открыв таким образом доступ к LODSW и заменив им строки 21,23
3. Массив объявлен как байтовый, однако в первом цикле идёт чтение двух байт (строка 21), а указатель изменяется на 1 байт (строка 23)
4. Чуть не забыл - строка 19 movzx зачем? И неплохо бы после загрузки размера массива обнулить AH (если массив байтовый) и тогда сложение слов в строке 27 имеет смысл
5. Строка 26 - эта строка приведёт к ошибке в расчётах, если сумма массива выйдет за пределы 255. Опасаться переполнения при делении в данном случае не стоит, т.к. даже если будут максимальные числа - 255 все 10 раз, получится 255*10 и если это разделить на 10 выход за пределы 255 не произойдет. В общем случае использования операции деления легко понять когда возможно переполнение - если старшая половина делимого равна или больше делителя.
6. Строка 28 - коммент не верен, т.к. целый ответ в AL, остаток AH и в строке 32 сравнение идёт правильно с AL, т.е. опять же массив байтовый, однако в строке 9 затирка слова. И кстати строка 33 переход знаковый, т.е. массив байтовый со знаком в старшем бите? Тогда нужны команды сложения и деления знаковые.
7. Строки 8-12 было бы лучше убрать и сделать
Assembler
1
2
3
4
5
m2: dec bx
cmp [bx],al
jnc m3
mov [bx],ah (который до цикла обнулён);
m3: loop m2
8. Проверку остатка от деления нужно делать 1 раз и до второго цикла: or ah,ah; je qwerty; inc al; qwerty: xor ah,ah (для затирки), т.е. если есть хоть какой-то остаток увеличиваем целый результат деления на 1 (округляем в большую сторону).
9. Ради интереса попробуй составить алгоритм без изменения указателя в массиве - строки 23,31, или с помощью mmx команд.
1
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 914
16.07.2016, 22:47 7
Круто. Спасибо за детальное объяснение. Попробую ответить на ваши некоторые пункты. Насчет пункта 1) эту штуку знал, только подзабыл про нее. Я так понимаю что здесь разница в байтах?

Добавлено через 17 минут
по пункту 2) читал что для массива используют индексные регистры SI, DI, но так как тот ресурс по которому я читаю более про них не говорил, поэтому у меня сложилось впечатление что их используют, когда не хватает регистров общего назначения. А про LODSW не слышал, надо почитать.
0
Эксперт Hardware
Эксперт Hardware
6151 / 2391 / 396
Регистрация: 29.07.2014
Сообщений: 3,135
Записей в блоге: 4
17.07.2016, 07:14 8
Senarist, совсем необязательно прибавлять к среднему 1. Можно просто уточнить условие проверки, типа меньше/равно(JBE) и всё. И почитай про строковые команды, которые удобны тем, что не нужно постоянно двигать указатели. Эти команды сами их сдвигают. Вот тебе краткое описание:
Код
   STOSB  - запись символа из AL в ES:DI;
   LODSB  - чтение символа в AL из DS:SI;
   MOVSB  - копирование из DS:SI в ES:DI;
   CMPSB  - сравнивает байт DI, с байтом SI (сравнивает строки);
   SCASB  - сравнивает байт AL, с байтом DI (поиск символа в строке).
Для организации циклов применяется префикс "REP". Как и в случае с командой LOOP, счётчиком служит регистр CX, который при каждом цикле уменьшается на 1. Ниже приведены модификации префикса "REP" для этих целей. Часто REP применяется для STOSB/LODSB/MOVSB, а REPE применяется для CMPSB/SCASB:
Код
REP         -   продолжать, пока CX > 0;
REPE/REPZ   -   прекратить, при не совпадении (сравнение строк);
REPNE/REPNZ -   прекратить, при совпадении (поиск символа в строке).
Вот тебе пример, в котором массив читается через LODSB, а перезаписывается новыми значениями через STOSB. В конце массива нужно вставить маркер конца - нуль:
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
;fasm code...
org 100h
jmp  start
 
array  db   22,7,12,18,5,13,8,23,2,14
len    =    $ - array         ; длина массива = текущий адрес, минус адрес начала массива
 
start: mov   si,array         ; SI для LODSB
       mov   cx,len           ;
       xor   bx,bx            ;
summ:  lodsb                  ;
       add   bx,ax            ; ВХ = сумма
       loop  summ             ;
 
       xchg  ax,bx            ;
       mov   bx,len           ;
       xor   dx,dx            ;
       div   bx               ;
       xchg  ax,dx            ; DX = среднее
 
       mov   cx,bx            ;
       sub   si,cx            ;
       mov   di,si            ; SI/DI = адрес массива
newAr: lodsb                  ;
       cmp   al,dl            ;
       jbe   fuck             ; пропустить, если AL меньше/равно среднего
       stosb                  ; иначе: перезапись массива значением из AL
fuck:  loop  newAr            ;
 
       xor   al,al            ; вставляем маркер конца массива
       stosb                  ;
 
       xor  ax,ax             ;
       int  16h               ;
       ret                    ;
1
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
17.07.2016, 16:34 9
Эта задача вообще из области параноидальной шизофрении.
Во-1, для вычисления среднего необходимо задействовать FPU. (Если сами данные в массиве не FP, то можно и не задействовать, а смтреть по остатку)
Во-2, как задан массив? По указателю? Тогда как вычисляется его размер/окончание? Какой тип данных массива?
И в-3, что такое "удалить элементы массива"? Шилом пробить ячейки на кристалле ОЗУ?
0
Эксперт Hardware
Эксперт Hardware
6151 / 2391 / 396
Регистрация: 29.07.2014
Сообщений: 3,135
Записей в блоге: 4
17.07.2016, 19:45 10
Цитата Сообщение от Kukuxumushu Посмотреть сообщение
задача из области параноидальной шизофрении
Ну правильно.. Щас доверили книжки писать всяким Чикатило, которые их пишут нито под-кайфом, нито спросони. Это уже вошло в привычку: всё что не оговорено, можно подгонять под свои мысли, и добавлять отсебятину.
Короче, полная анархия
0
197 / 89 / 15
Регистрация: 10.07.2016
Сообщений: 146
18.07.2016, 21:03 11
Senarist, XOR используют из-за размера, но не всегда, т.к. он изменяет флаги.
Для работы с массивами можно использовать любые регистры, однако для определённых реализаций алгоритма удобнее ESI/EDI, для других реализаций лучше будут конструкции типа [EDX+ECX*4] и тп. На языках высокого уровня работа с массивами идёт в жестко заданных рамках, на асме полная свобода и даже само понятие массива носит исключительно абстрактный характер.
0
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 914
18.07.2016, 22:49 12
Цитата Сообщение от Ol44 Посмотреть сообщение
на асме полная свобода и даже само понятие массива носит исключительно абстрактный характер.
Да, зная основы С++ я это понял, попробовав писать данную программу)
0
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 914
21.07.2016, 17:38 13
А есть ли команда наподобие lodsb, только чтобы ни как для моего примера указатель "шел" с начала до конца, а наоборот с конца. (Занести в si адрес последнего элемента массива и идти к началу) ?
0
Эксперт Hardware
Эксперт Hardware
6151 / 2391 / 396
Регистрация: 29.07.2014
Сообщений: 3,135
Записей в блоге: 4
21.07.2016, 17:55 14
..установи флаг DF, командой STD
1
21.07.2016, 17:55
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.07.2016, 17:55
Помогаю со студенческими работами здесь

В массиве определить количество элементов меньших среднего арифметического значения
В массиве Х определить количество элментов меньших среднего арифметического значения.

Подсчитать количество элементов, которые больше среднего арифметического массива
Задание такое: нужно написать программу, которая формирует массив из 3-х столбцов и 5-ти строк....

Числа, большие среднего арифметического, заменить на первое значение в массиве
может быть я немножко не туда, но вот в чем дело, у меня дана задача на паскале, нужно сделать...

Подсчет среднего арифметического массива
Компилирую программу: tasm.exe prog1.asm - все нормально. tlink.exe prog1.obj - Выдает ошибку...


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

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

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