hardasm
Читатель
Offline
|
 |
« : 26-12-2011 22:18 » |
|
Моя идея: найти количество цифр числа, найти количество различных цифр числа. Если эти количества совпадают, то данное число не содержит повторяющихся цифр. Этим правилом пройти все числа от N до 100. На С++ написал - работает, на Ассемблере - не могу. Помогите, пожайлуста перевести на Асм для TASM! //Найти в интервале от 100 до n все целые числа, не содержащие повторяющихся цифр #include<iostream> #include<clocale> using namespace std; // кол-во цифр числа int numberOfDigits(int m) { int i=0; for(; m!=0; i++) m/=10; return i; } // кол-во различных цифр числа int numberOfDifferDigits(int m) { const unsigned peak=20;//максимальное кол-во цифр N-числа, с к-рым компилер может работать bool L[peak]; for(int i=0; i<peak; i++) L[i]=0; do { L[m%10]=1; m/=10; } while(m!=0); unsigned uniq=0;//счётчик различных цифр числа: for(int i=0; i<peak; i++) uniq+=L[i]; return uniq; } int main() { setlocale(LC_ALL,"russian"); cout<<"Введи число больше ста: "; int n; cin>>n; cout<<"Количество цифр числа: "<<numberOfDigits(n)<<'\n'; cout<<"Количество различных цифр числа: "<<numberOfDifferDigits(n)<<'\n'; while(n!=100) { if(numberOfDigits(n)==numberOfDifferDigits(n)) //если кол-во цифр числа равно кол-ву различных цифр числа, то это число не содержит повторяющихся цифр cout<<n<<' '; n--; } return 0; }
|
|
|
|
|
Записан
|
|
|
|
|
Oldy
|
 |
« Ответ #1 : 27-12-2011 04:33 » |
|
У С-компиляторов есть инструкция компиляции через (в) ассемблер. Попробуйте использовать ее. (У Borland C++ "-S")
|
|
|
|
« Последнее редактирование: 27-12-2011 06:35 от Oldy »
|
Записан
|
С уважением, Oldy.
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
 |
« Ответ #2 : 27-12-2011 06:36 » |
|
Так, заметки в сторону const unsigned peak=20;//максимальное кол-во цифр N-числа, с к-рым компилер может работать bool L[peak]; for(int i=0; i<peak; i++) L[i]=0; В десятичной системе, обшее количество комбинаций чисел всего десять. Так что L[10] и далее просто бесмысленно. Да и еше больше можно убыстрить и упростить алгоритм. Деление довольно сложная и тяжеллая операция. Процессор выполняет ее в десятки раз дольше чем даже умножение.
|
|
|
|
« Последнее редактирование: 27-12-2011 06:38 от Finch »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
|
Вад
|
 |
« Ответ #3 : 27-12-2011 08:07 » |
|
Кроме того, организовывать полный перебор с проверкой... нерационально как-то. Количество итоговых комбинаций будет сильно ниже, чем полное количество цифр в интервале. И все эти дорогостоящие проверки... Не проще ли сразу подсчитывать количество возможных перестановок? То есть, алгоритмически, будет немного посложнее, конечно, но оно того стоит, я думаю.
|
|
|
|
|
Записан
|
|
|
|
hardasm
Читатель
Offline
|
 |
« Ответ #4 : 29-12-2011 23:04 » |
|
В десятичной системе, обшее количество комбинаций чисел всего десять. Так что L[10] и далее просто бесмысленно. Да и еше больше можно убыстрить и упростить алгоритм. Деление довольно сложная и тяжеллая операция. Процессор выполняет ее в десятки раз дольше чем даже умножение.
Согласен, протупил Добавлено через 48 секунд:У С-компиляторов есть инструкция компиляции через (в) ассемблер. Попробуйте использовать ее. (У Borland C++ "-S")
А для Visual studio не подскажете?
|
|
|
|
« Последнее редактирование: 29-12-2011 23:05 от hardasm »
|
Записан
|
|
|
|
|
Вад
|
 |
« Ответ #5 : 30-12-2011 11:06 » |
|
У С-компиляторов есть инструкция компиляции через (в) ассемблер. Попробуйте использовать ее. (У Borland C++ "-S")
А для Visual studio не подскажете? В зависимости от версии студии, возможны отличия, но в 2008й в настройках проекта есть "C/C++"->"Output files"->"Assembler Output", где нужно выбрать желаемое среди вариантов (ключ /FA с вариациями)
|
|
|
|
|
Записан
|
|
|
|
hardasm
Читатель
Offline
|
 |
« Ответ #6 : 30-12-2011 18:36 » |
|
В зависимости от версии студии, возможны отличия, но в 2008й в настройках проекта есть "C/C++"->"Output files"->"Assembler Output", где нужно выбрать желаемое среди вариантов (ключ /FA с вариациями)
Спасибо, буду знать. (правда для меня это не выход: асм-файл весит аш 69кб, содержит 2тыщи строк, ладно буду думать. Если у кого-то что-то похожее найдётся, будьте людьми... спасибо)
|
|
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
 |
« Ответ #7 : 30-12-2011 18:51 » |
|
hardasm, так он тебе, чтобы "подсмотреть как", а не для того, чтобы его взять и сдать.  Халявы не будет.
|
|
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
|
Вад
|
 |
« Ответ #8 : 30-12-2011 19:15 » |
|
hardasm, ты лучше ответь на вопрос: Не проще ли сразу подсчитывать количество возможных перестановок? Просто пост начинался с твоей идеи, которая выглядит в корне неверной - в смысле, неэффективной. Или комбинаторику не проходили?
|
|
|
|
|
Записан
|
|
|
|
hardasm
Читатель
Offline
|
 |
« Ответ #9 : 31-12-2011 17:30 » |
|
hardasm, ты лучше ответь на вопрос: Не проще ли сразу подсчитывать количество возможных перестановок? Просто пост начинался с твоей идеи, которая выглядит в корне неверной - в смысле, неэффективной. Или комбинаторику не проходили? проходили, в школе) С Новым Годом!
|
|
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
 |
« Ответ #10 : 31-12-2011 17:43 » |
|
В школе проходят комбинаторику?
|
|
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
 |
« Ответ #11 : 01-01-2012 08:22 » |
|
Finch, в некоторых школах - да.
|
|
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
hardasm
Читатель
Offline
|
 |
« Ответ #12 : 06-01-2012 12:22 » |
|
Ну вот, на плюсах упростил (идея та же): //Найти в интервале от 100 до n все целые числа, не содержащие повторяющихся цифр #include<iostream> #include<clocale> using namespace std;
int main() { setlocale(LC_ALL,"russian"); cout<<"Введи число больше ста: "; int n; cin>>n; bool L[10]; // каждый "бит" этого массива отвечает за присутствие цифры в текущем числе for(int i=100;i<=n;i++) { for(int j=0; j<10; j++) L[j]=0; int tmp=i; while(tmp!=0) // есть ли в числе разные цифры? { if(L[tmp%10]!=0) break; L[tmp%10]=1; tmp/=10; if(tmp==0) cout<<i<<' '; } } cout<<endl; return 0; } Пытаюсь стряпать аналог на ассемблере: .model small .stack .data n dw ? LM dw ? ; как-бы аналог массива bool L[10] ten dw 10 ms db "Vvedi n>100:$" .code extrn writer:near extrn read:near .startup ; Выводим просьбу ввести n mov ah,9 lea dx,ms int 21h call read mov n,ax; запоминаем n
mov cx,100 next: ; как-бы аналог цикла for(int i=100;i<=n;i++) lea bx,LM add bx,20 nuler: ; заполним массив нулями mov [bx],0 dec bx dec bx jnz nuler mov [bx],0 inc cx mov ax,cx; сохраним cх proverka_chisla: ; есть ли в текущем числе разные цифры? ;cwd div ten; остаток от деления на 10 попадёт в dx ;lea bx,LM add dx,dx add bx,dx mov si,[bx] sub bx,dx cmp si,0 jne next; если si не=0, значит в текущем числе уже есть цифра равная dx mov [bx],1 cmp ax,0 jne proverka_chisla mov ax,cx call writer cmp ax,n jne next
mov ah,1 int 21h .exit end Ошибка: Divide overflow Понимаю, что идея далеко не самая эффективная, но мне сейчас главное "шоб работало" - на творчество нет времени  . Помогите подправить  , пожалуйста.
|
|
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
 |
« Ответ #13 : 06-01-2012 12:59 » |
|
lea bx,LM add bx,20 nuler: ; заполним массив нулями mov [bx],0 dec bx dec bx jnz nuler mov [bx],0 Вот тут переполнение налицо. Причем n тоже будет обнулен. Кстати для таких случаев есть замечательные команды. Работа с массивом байт. rep movsw
|
|
|
|
« Последнее редактирование: 06-01-2012 13:06 от Finch »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
hardasm
Читатель
Offline
|
 |
« Ответ #14 : 06-01-2012 13:24 » |
|
lea bx,LM add bx,20 nuler: ; заполним массив нулями mov [bx],0 dec bx dec bx jnz nuler mov [bx],0 Вот тут переполнение налицо. Причем n тоже будет обнулен. а как обнулится n, не пойму?
|
|
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
 |
« Ответ #15 : 06-01-2012 16:36 » |
|
Посмотри команду movsw. Ну или если хочеш вручную, заведи в любом регистре счетчик и считай до 20. Вернее от 20 до 0.
|
|
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
|