Форум программистов, компьютерный форум CyberForum.ru

Сделать вставку асма - C++

Восстановить пароль Регистрация
 
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
13.06.2010, 21:23     Сделать вставку асма #1
Помогите пожалуйста!!!!нужно дописать вставку асма, вот задача:

Латинский квадрат. Латинским квадратом порядка n называется квадратная таблица размером nxn, каждая строка и каждый столбец которой содержат все числа от 1 до n. Проверить, является ли заданная целочисленная матрица латинским квадратом.

вот код:

C++
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
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
 
int main()
{
        int **masiv, n, i, j;
        std::cout<<"Enter number= ";
        std::cin>>n;
        masiv=new int*[n];
     for(i=0; i<n; i++)
       masiv[i]=new int[n];
        for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                        masiv[i][j]=(i+j)%n+1;
        for(i=0; i<n; i++)
        {
                for(j=0; j<n; j++)
                        std::cout<<masiv[i][j]<<" ";
                std::cout<<endl;
        }
        getch();
  return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vital792
1987 / 1259 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
13.06.2010, 21:29     Сделать вставку асма #2
Где то я это уже сегодня видел) а не указано какой набор инструкций можно использовать? (fpu mmx sse)?

Добавлено через 2 минуты
и опять что вставлять то? опять все переписать на ассемблер?
BoDRbIi
 Аватар для BoDRbIi
60 / 10 / 3
Регистрация: 21.07.2009
Сообщений: 250
13.06.2010, 22:27     Сделать вставку асма #3
Я так понял надо сделать вставку. точнее фун-цию на ассемблере которая бы проводила вычисления?
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
13.06.2010, 23:35  [ТС]     Сделать вставку асма #4
Совершенно верно, нужно сделать вставку, которая бы делала вычисления
vital792
1987 / 1259 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 08:39     Сделать вставку асма #5
я не вижу ничего лучше чем
1. Создать эталонный вектор [1..n] - для сравнения
2. В цикле сортировать строки матрицы и сравнивать с эталонным вектором
3. Транспонировать и повторить шаг2.
Это решение в лоб - очень громоздкое и медленное. Может кто подскажет способ оптимальнее?
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 10:40  [ТС]     Сделать вставку асма #6
Блин, по ходу, сеня я её не здамблин, зачетная прога.

Добавлено через 1 час 7 минут
Вопрос жизни и смертипросто необходима помощь
vital792
1987 / 1259 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 10:55     Сделать вставку асма #7
Вот половина решения:
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
bool IsLatin(int **matrix, int n)
{
    bool result;
    int *vector = new int[n];
    for(int i=0; i<n; i++)
        vector[i] = i+1;
    int *temp = new int[n];
    _asm
     {
         mov    ecx, n
         xor    ebx, ebx
_loop0:
         push   ecx
         push   ebx
         mov    eax, [matrix]
         mov    esi, [eax+ebx]
         mov    ecx, n
         mov    edi, [temp]
         rep    movsd
_loop1:
         mov    ecx, n
         mov    esi, [temp]
         xor    ebx, ebx
_loop2:
         lodsd
         cmp    eax, dword ptr [esi]
         jbe    no_swap
         xchg   eax, dword ptr [esi]
         mov    dword ptr [esi-4], eax
         inc    ebx
no_swap:
         loop   _loop2
         cmp    ebx, 0
         jne    _loop1
 
         mov    edi, [vector]
         mov    ecx, n
         repnz  cmpsd
         jz _noLatin
         pop    ebx
         add    ebx, 4
         pop    ecx
         loop   _loop0
         jmp    _Latin
_noLatin:
         pop    eax
         pop    eax
         xor    eax, eax
         mov    result, al
         jmp    _end
_Latin:
         mov    eax, 1
         mov    result, al
_end:
     }
    delete [] vector;
    delete [] temp;
    return result;
}
Осталось транспонировать матрицу и вызвать функцию IsLatin еще раз.
Вызов:
C++
1
2
if(IsLatin(masiv, n))
       cout<<"Matrix is Latin Square";
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 10:59  [ТС]     Сделать вставку асма #8
а как нить, еще подробней можно???если не сложно конечно
vital792
1987 / 1259 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 11:14     Сделать вставку асма #9
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
    _asm
     {
         mov    ecx, n // кол-во элементов
         xor    ebx, ebx //индекс
_loop0:
         push   ecx     // сохраняем счетчик
         push   ebx     // и индекс
         mov    eax, [matrix]   // получим указатель на матрицу
         mov    esi, [eax+ebx]  // разыменуем с масштабированием(т.е. получим в цикле указатели на строки матрицы)
         mov    ecx, n          // 
         mov    edi, [temp]     // указатель на временный вектор(в нем будем хранить сортированные строки матрицы)
         rep    movsd           // копируем строку
_loop1:                         // далее - обычная сортировка массива пузырьком
         mov    ecx, n
         mov    esi, [temp]
         xor    ebx, ebx
_loop2:
         lodsd
         cmp    eax, dword ptr [esi]
         jbe    no_swap
         xchg   eax, dword ptr [esi]
         mov    dword ptr [esi-4], eax
         inc    ebx
no_swap:
         loop   _loop2
         cmp    ebx, 0
         jne    _loop1
                                // до сюда
         mov    edi, [vector]   // а тут сравниваем сортированную строку с эталонным вектором
         mov    ecx, n
         repnz  cmpsd
         jz _noLatin            // не похожа
         pop    ebx             // восстанавливаем регистры
         add    ebx, 4          // индекс массива (+sizeof(int))
         pop    ecx
         loop   _loop0          // цикл по строкам матрицы
         jmp    _Latin          // прошли все строки удачно
_noLatin:
         pop    eax             // не удачно
         pop    eax             //  - выровняем стек
         xor    eax, eax        // result = false;
         mov    result, al
         jmp    _end
_Latin:
         mov    eax, 1          // result = true;
         mov    result, al
_end:
     }
Эта функция проверяет только строки. Чтобы проверить столбцы транспонируй матрицу( в двойном цикле замени i-й на j-й) и вызови функцию для транспонированной матрицы
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 11:22  [ТС]     Сделать вставку асма #10
Я наверное не правильно понял, но вот что у мя получилось, исправьте если не правильно:
C++
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
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
 
int main()
{       
        setlocale(LC_ALL, "Russian");
        int **masiv, n, i, j;
        std::cout<<"Введите кол-во элементов= ";
        std::cin>>n;
        masiv=new int*[n];
     for(i=0; i<n; i++)
       masiv[i]=new int[n];
        for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                        masiv[i][j]=(i+j)%n+1;
        for(i=0; i<n; i++)
        {
                for(j=0; j<n; j++)
                        std::cout<<masiv[i][j]<<" ";
                std::cout<<endl;
        }
        if(IsLatin(masiv, n))
       cout<<"Matrix is Latin Square";
        bool IsLatin(int **matrix, int n)
{
        bool result;
        int *vector = new int[n];
        for(int i=0; i<n; i++)
                vector[i] = i+1;
        int *temp = new int[n];
        _asm
         {
                 mov    ecx, n // кол-во элементов
                 xor    ebx, ebx //индекс
_loop0:
                 push   ecx             // сохраняем счетчик
                 push   ebx             // и индекс
                 mov    eax, [matrix]   // получим указатель на матрицу
                 mov    esi, [eax+ebx]  // разыменуем с масштабированием(т.е. получим в цикле указатели на строки матрицы)
                 mov    ecx, n                  // 
                 mov    edi, [temp]             // указатель на временный вектор(в нем будем хранить сортированные строки матрицы)
                 rep    movsd                   // копируем строку
_loop1:                                                 // далее - обычная сортировка массива пузырьком
                 mov    ecx, n
                 mov    esi, [temp]
                 xor    ebx, ebx
_loop2:
                 lodsd
                 cmp    eax, dword ptr [esi]
                 jbe    no_swap
                 xchg   eax, dword ptr [esi]
                 mov    dword ptr [esi-4], eax
                 inc    ebx
no_swap:
                 loop   _loop2
                 cmp    ebx, 0
                 jne    _loop1
                                                                // до сюда
                 mov    edi, [vector]   // а тут сравниваем сортированную строку с эталонным вектором
                 mov    ecx, n
                 repnz  cmpsd
                 jz     _noLatin                        // не похожа
                 pop    ebx                             // восстанавливаем регистры
                 add    ebx, 4                  // индекс массива (+sizeof(int))
                 pop    ecx
                 loop   _loop0                  // цикл по строкам матрицы
                 jmp    _Latin                  // прошли все строки удачно
_noLatin:
                 pop    eax                             // не удачно
                 pop    eax                             //  - выровняем стек
                 xor    eax, eax                // result = false;
                 mov    result, al
                 jmp    _end
_Latin:
                 mov    eax, 1                  // result = true;
                 mov    result, al
_end:
         } 
        }
        delete [] vector;
        delete [] temp;
        getch();
        return result;
        
  
}
vital792
1987 / 1259 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 11:35     Сделать вставку асма #11
C++
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
bool IsLatin(int **matrix, int n);
 
int main(int argc, char* argv[])
{
     int **masiv, n, i, j;
     std::cout<<"Enter number= ";
     std::cin>>n;
     masiv=new int*[n];
     for(i=0; i<n; i++)
         masiv[i]=new int[n];
     for(i=0; i<n; i++)
         for(j=0; j<n; j++)
             masiv[i][j]=(i+j)%n+1;
     for(i=0; i<n; i++)
     {
         for(j=0; j<n; j++)
             std::cout<<masiv[i][j]<<" ";
         std::cout<<endl;
     }
     getch();
 
     if(IsLatin(masiv, n))
                { // транспонирование и повторная проверка
         std::cout<<"Matrix is Latin Square";
}
 
     return 0;
}
 
bool IsLatin(int **matrix, int n)
{
    bool result;
    int *vector = new int[n];
    for(int i=0; i<n; i++)
        vector[i] = i+1;
    int *temp = new int[n];
    _asm
     {
         mov    ecx, n // кол-во элементов
         xor    ebx, ebx //индекс
_loop0:
         push   ecx     // сохраняем счетчик
         push   ebx     // и индекс
         mov    eax, [matrix]   // получим указатель на матрицу
         mov    esi, [eax+ebx]  // разыменуем с масштабированием(т.е. получим в цикле указатели на строки матрицы)
         mov    ecx, n          // 
         mov    edi, [temp]     // указатель на временный вектор(в нем будем хранить сортированные строки матрицы)
         rep    movsd           // копируем строку
_loop1:                         // далее - обычная сортировка массива пузырьком
         mov    ecx, n
         mov    esi, [temp]
         xor    ebx, ebx
_loop2:
         lodsd
         cmp    eax, dword ptr [esi]
         jbe    no_swap
         xchg   eax, dword ptr [esi]
         mov    dword ptr [esi-4], eax
         inc    ebx
no_swap:
         loop   _loop2
         cmp    ebx, 0
         jne    _loop1
                                // до сюда
         mov    edi, [vector]   // а тут сравниваем сортированную строку с эталонным вектором
         mov    ecx, n
         repnz  cmpsd
         jz _noLatin            // не похожа
         pop    ebx             // восстанавливаем регистры
         add    ebx, 4          // индекс массива (+sizeof(int))
         pop    ecx
         loop   _loop0          // цикл по строкам матрицы
         jmp    _Latin          // прошли все строки удачно
_noLatin:
         pop    eax             // не удачно
         pop    eax             //  - выровняем стек
         xor    eax, eax        // result = false;
         mov    result, al
         jmp    _end
_Latin:
         mov    eax, 1          // result = true;
         mov    result, al
_end:
     }
    delete [] vector;       // освободим память
    delete [] temp;
    return result;
}
Добавлено через 8 минут
Цитата Сообщение от Vasal Посмотреть сообщение
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
std::cout<<masiv[i][j]<<" ";
std::cout<<endl;
}
в этом цикле ты получаешь свой латинский квадрат так что результатбудет всегда положительный.
Добавь еще цикл для ввода произвольной матрицы чтобы проверить результат

Добавлено через 1 минуту
Цитата Сообщение от Vasal Посмотреть сообщение
for(i=0; i<n; i++)
for(j=0; j<n; j++)
masiv[i][j]=(i+j)%n+1;
не то скопировал)) - в этом цикле
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 11:35  [ТС]     Сделать вставку асма #12
он у мя чето не отпечатывает того что нужно,нада чтоб он отпечатал 2 ответа, т.е 2 латинских квадрата, один чтоб был языка си, а другой вставки асма,я чет щас пытался этого добится, но почему то не получилось
vital792
1987 / 1259 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 11:39     Сделать вставку асма #13
так я не понял надо всего лишь получить этот квадрат? А как же
Цитата Сообщение от Vasal Посмотреть сообщение
Проверить, является ли заданная целочисленная матрица латинским квадратом.
? Данная функция как раз проверяет является ли введенная матрица этим квадратом. Я че зря старался? этого не надо? как раз получить его никаких проблем - проверить куда сложнее
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 11:45  [ТС]     Сделать вставку асма #14
нет, это нада, я имелл в виду, то что, их нужно отпечатать, сначала в С а потом сразу после него должен следовать асм.ну и потом типа конец программы, все в одной, я вот хотел этого добится но чет не получилось
Orwomoi
63 / 62 / 2
Регистрация: 16.11.2009
Сообщений: 156
14.06.2010, 12:36     Сделать вставку асма #15
хмм... Если латинский квадрат содержит последовательность чисел 1..n Этим можно воспользоваться при сортировке.
1. Выделяем память под строку длины n
2. заполняем нулями.
3. Хватаем первый элемент из квадрата,
4. проверяем нe больше ли он числа n,
5. и ставим его во временную строку на место равное его порядковому числу.
5.5 еще можно проверить на 0 место, куда ставим элемент из квадрата. Если там не 0, значит туда уже копировали элемент из этой строки квадрата, а значит в строке 2 одинаковых числа, чего не может быть в латинском квадрате.
6. По завершении работы со строкой из квадрата сканируем временную строку (scas) на 0. Если в строке остался ноль, значит в строке квадрата отсутвсует один из элементов последовательности 1..n
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 13:13  [ТС]     Сделать вставку асма #16
ваще запутался, так как будит правильно, то что уже есть, или заново нада писать.
vital792
1987 / 1259 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 13:37     Сделать вставку асма #17
Цитата Сообщение от Orwomoi Посмотреть сообщение
1. Выделяем память под строку длины n
2. заполняем нулями.
3. Хватаем первый элемент из квадрата,
4. проверяем нe больше ли он числа n,
5. и ставим его во временную строку на место равное его порядковому числу.
5.5 еще можно проверить на 0 место, куда ставим элемент из квадрата. Если там не 0, значит туда уже копировали элемент из этой строки квадрата, а значит в строке 2 одинаковых числа, чего не может быть в латинском квадрате.
6. По завершении работы со строкой из квадрата сканируем временную строку (scas) на 0. Если в строке остался ноль, значит в строке квадрата отсутвсует один из элементов последовательности 1..n
да - это намного лучше
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 14:00  [ТС]     Сделать вставку асма #18
мдя, блин с ума сойти. мне че переделовать? чтоб по лучше выглядело?
Orwomoi
63 / 62 / 2
Регистрация: 16.11.2009
Сообщений: 156
14.06.2010, 14:02     Сделать вставку асма #19
Цитата Сообщение от Vasal Посмотреть сообщение
ваще запутался, так как будит правильно, то что уже есть, или заново нада писать.
Как было - тоже правильно, но мой вариант быстрее.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.06.2010, 09:49     Сделать вставку асма
Еще ссылки по теме:

C++ Trie дерево, реализовать вставку
C++ Сделать из assembler кода ассемблерную вставку в C++
C++ Нужно переделать С++ функцию на ассемблерную вставку

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

Или воспользуйтесь поиском по форуму:
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
15.06.2010, 09:49  [ТС]     Сделать вставку асма #20
а как сдесь сделать так, чтоб он отпечатовал 2 ответа????то есть, с начала С, а потом асм

Добавлено через 11 часов 40 минут
что то у мя ваще эта программа отказывается работать
вот другой код, может с ним что нить получится:

C++
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
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
 
 
typedef int  T_elem_type;
class T_dvumern_arr
{    
    typedef std::vector<T_elem_type>  T_row;
    typedef std::vector<T_row>        T_matrix;
    typedef std::set<T_elem_type>     T_stand_elems;
 
    T_elem_type                       n_;
    T_matrix                          matrix_;    
    T_stand_elems                     stand_elems_;
public:
    T_dvumern_arr(T_elem_type  n) : n_(n), matrix_(n_, T_row(n_))
    {}
    //-----------------------------------------------------------
    void  input()
    {
        std::cout << "Введите элементы матрицы "
                  << n_
                  <<" x "
                  << n_
                  << ": "
                  << std::endl;
        for(int i = 0; i < n_; ++i)
        {
            stand_elems_.insert(i + 1);
            for(int j = 0; j < n_; ++j)
            {
                std::cout << "A("    
                          << i + 1
                          << ", "
                          << j + 1
                          << ") = ";
                std::cin >> matrix_[i][j];
            }
            std::cout << std::endl;
        }//for(int i = 0; i < n_; ++i)    
    }//void  input()
    //-----------------------------------------------------------
    bool are_latin_rows(T_matrix  matrix)
    {
        for(int i = 0; i < n_; ++i)
        {
            T_row  cur_row = matrix[i];
            if(T_stand_elems(cur_row.begin(), cur_row.end()) != stand_elems_)
            {
                return false;
            }
        }
        return true;
    }
    //-----------------------------------------------------------
    T_matrix  get_transp_matrix()
    {        
        T_dvumern_arr  temp_dvumern_arr(n_);        
        for(int i = 0; i < n_; ++i)
        {
            for(int j = 0; j < n_; ++j)
            {                
                temp_dvumern_arr.matrix_[i][j] = matrix_[j][i];
            }
        }        
        return  temp_dvumern_arr.matrix_;
    }
    //-----------------------------------------------------------
    bool is_latin_kvadrat()
    {
        return are_latin_rows(matrix_)
               && are_latin_rows(get_transp_matrix());
    }
};
 
int main()
{
    std::locale::global(std::locale(""));
 
    std::cout << "Введите размерность латинского квадрата: ";
    T_elem_type  n = 0;
    std::cin >> n;
    if(n < 1) return 0;
    T_dvumern_arr  dvumern_arr(n);
    dvumern_arr.input();
    std::cout << "Заданная матрица "
              << (dvumern_arr.is_latin_kvadrat() ? "является " : "не является ")
              << "латинским квадратом."
              << std::endl;
    system("pause");
    return 0;
}
Добавлено через 15 минут
исправьте сдесь если не правильно, просто программа должна выдавать 2 ответа, а выходит один

Добавлено через 1 минуту
C++
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
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
 
typedef int  T_elem_type;
class T_dvumern_arr
{    
    typedef std::vector<T_elem_type>  T_row;
    typedef std::vector<T_row>        T_matrix;
    typedef std::set<T_elem_type>     T_stand_elems;
 
    T_elem_type                       n_;
    T_matrix                          matrix_;    
    T_stand_elems                     stand_elems_;
public:
    T_dvumern_arr(T_elem_type  n) : n_(n), matrix_(n_, T_row(n_))
    {}
    //-----------------------------------------------------------
    void  input()
    {
        std::cout << "Введите элементы матрицы "
                  << n_
                  <<" x "
                  << n_
                  << ": "
                  << std::endl;
        for(int i = 0; i < n_; ++i)
        {
            stand_elems_.insert(i + 1);
            for(int j = 0; j < n_; ++j)
            {
                std::cout << "A("    
                          << i + 1
                          << ", "
                          << j + 1
                          << ") = ";
                std::cin >> matrix_[i][j];
            }
            std::cout << std::endl;
        }//for(int i = 0; i < n_; ++i)    
    }//void  input()
    //-----------------------------------------------------------
    bool are_latin_rows(T_matrix  matrix)
    {
        for(int i = 0; i < n_; ++i)
        {
            T_row  cur_row = matrix[i];
            if(T_stand_elems(cur_row.begin(), cur_row.end()) != stand_elems_)
            {
                return false;
            }
        }
        return true;
    }
    //-----------------------------------------------------------
    T_matrix  get_transp_matrix()
    {        
        T_dvumern_arr  temp_dvumern_arr(n_);        
        for(int i = 0; i < n_; ++i)
        {
            for(int j = 0; j < n_; ++j)
            {                
                temp_dvumern_arr.matrix_[i][j] = matrix_[j][i];
            }
        }        
        return  temp_dvumern_arr.matrix_;
    }
    //-----------------------------------------------------------
    bool is_latin_kvadrat()
    {
        return are_latin_rows(matrix_)
               && are_latin_rows(get_transp_matrix());
    }
};
 
int main()
{
    std::locale::global(std::locale(""));
 
    std::cout << "Введите размерность латинского квадрата: ";
    T_elem_type  n = 0;
    std::cin >> n;
    if(n < 1) return 0;
    T_dvumern_arr  dvumern_arr(n);
    dvumern_arr.input();
    std::cout << "Заданная матрица "
              << (dvumern_arr.is_latin_kvadrat() ? "является " : "не является ")
              << "латинским квадратом."
              << std::endl;
    std::cout << "Начало асма" ;
    system("pause");
};
    bool is_latin_kvadrat(int **matrix, int n)
{
        bool result;
        int *vector = new int[n];
        for(int i=0; i<n; i++)
                vector[i] = i+1;
        int *temp = new int[n];
      [ASM]
_asm
         {
                 mov    ecx, n // кол-во элементов
                 xor    ebx, ebx //индекс
_loop0:
                 push   ecx             // сохраняем счетчик
                 push   ebx             // и индекс
                 mov    eax, [matrix]   // получим указатель на матрицу
                 mov    esi, [eax+ebx]  // разыменуем с масштабированием(т.е. получим в цикле указатели на строки матрицы)
                 mov    ecx, n                  // 
                 mov    edi, [temp]             // указатель на временный вектор(в нем будем хранить сортированные строки матрицы)
                 rep    movsd                   // копируем строку
_loop1:                                                 // далее - обычная сортировка массива пузырьком
                 mov    ecx, n
                 mov    esi, [temp]
                 xor    ebx, ebx
_loop2:
                 lodsd
                 cmp    eax, dword ptr [esi]
                 jbe    no_swap
                 xchg   eax, dword ptr [esi]
                 mov    dword ptr [esi-4], eax
                 inc    ebx
no_swap:
                 loop   _loop2
                 cmp    ebx, 0
                 jne    _loop1
                                                                // до сюда
                 mov    edi, [vector]   // а тут сравниваем сортированную строку с эталонным вектором
                 mov    ecx, n
                 repnz  cmpsd
                 jz     _noLatin                        // не похожа
                 pop    ebx                             // восстанавливаем регистры
                 add    ebx, 4                  // индекс массива (+sizeof(int))
                 pop    ecx
                 loop   _loop0                  // цикл по строкам матрицы
                 jmp    _Latin                  // прошли все строки удачно
_noLatin:
                 pop    eax                             // не удачно
                 pop    eax                             //  - выровняем стек
                 xor    eax, eax                // result = false;
                 mov    result, al
                 jmp    _end
_Latin:
                 mov    eax, 1                  // result = true;
                 mov    result, al
_end:
         }
[/ASM]  
 
        
        delete [] vector;               // освободим память
        delete [] temp;
        return result;
}
Добавлено через 53 секунды
C++
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
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
 
typedef int  T_elem_type;
class T_dvumern_arr
{    
    typedef std::vector<T_elem_type>  T_row;
    typedef std::vector<T_row>        T_matrix;
    typedef std::set<T_elem_type>     T_stand_elems;
 
    T_elem_type                       n_;
    T_matrix                          matrix_;    
    T_stand_elems                     stand_elems_;
public:
    T_dvumern_arr(T_elem_type  n) : n_(n), matrix_(n_, T_row(n_))
    {}
    //-----------------------------------------------------------
    void  input()
    {
        std::cout << "Введите элементы матрицы "
                  << n_
                  <<" x "
                  << n_
                  << ": "
                  << std::endl;
        for(int i = 0; i < n_; ++i)
        {
            stand_elems_.insert(i + 1);
            for(int j = 0; j < n_; ++j)
            {
                std::cout << "A("    
                          << i + 1
                          << ", "
                          << j + 1
                          << ") = ";
                std::cin >> matrix_[i][j];
            }
            std::cout << std::endl;
        }//for(int i = 0; i < n_; ++i)    
    }//void  input()
    //-----------------------------------------------------------
    bool are_latin_rows(T_matrix  matrix)
    {
        for(int i = 0; i < n_; ++i)
        {
            T_row  cur_row = matrix[i];
            if(T_stand_elems(cur_row.begin(), cur_row.end()) != stand_elems_)
            {
                return false;
            }
        }
        return true;
    }
    //-----------------------------------------------------------
    T_matrix  get_transp_matrix()
    {        
        T_dvumern_arr  temp_dvumern_arr(n_);        
        for(int i = 0; i < n_; ++i)
        {
            for(int j = 0; j < n_; ++j)
            {                
                temp_dvumern_arr.matrix_[i][j] = matrix_[j][i];
            }
        }        
        return  temp_dvumern_arr.matrix_;
    }
    //-----------------------------------------------------------
    bool is_latin_kvadrat()
    {
        return are_latin_rows(matrix_)
               && are_latin_rows(get_transp_matrix());
    }
};
 
int main()
{
    std::locale::global(std::locale(""));
 
    std::cout << "Введите размерность латинского квадрата: ";
    T_elem_type  n = 0;
    std::cin >> n;
    if(n < 1) return 0;
    T_dvumern_arr  dvumern_arr(n);
    dvumern_arr.input();
    std::cout << "Заданная матрица "
              << (dvumern_arr.is_latin_kvadrat() ? "является " : "не является ")
              << "латинским квадратом."
              << std::endl;
    std::cout << "Начало асма" ;
    system("pause");
};
    bool is_latin_kvadrat(int **matrix, int n)
{
        bool result;
        int *vector = new int[n];
        for(int i=0; i<n; i++)
                vector[i] = i+1;
        int *temp = new int[n];
        _asm
         {
                 mov    ecx, n // кол-во элементов
                 xor    ebx, ebx //индекс
_loop0:
                 push   ecx             // сохраняем счетчик
                 push   ebx             // и индекс
                 mov    eax, [matrix]   // получим указатель на матрицу
                 mov    esi, [eax+ebx]  // разыменуем с масштабированием(т.е. получим в цикле указатели на строки матрицы)
                 mov    ecx, n                  // 
                 mov    edi, [temp]             // указатель на временный вектор(в нем будем хранить сортированные строки матрицы)
                 rep    movsd                   // копируем строку
_loop1:                                                 // далее - обычная сортировка массива пузырьком
                 mov    ecx, n
                 mov    esi, [temp]
                 xor    ebx, ebx
_loop2:
                 lodsd
                 cmp    eax, dword ptr [esi]
                 jbe    no_swap
                 xchg   eax, dword ptr [esi]
                 mov    dword ptr [esi-4], eax
                 inc    ebx
no_swap:
                 loop   _loop2
                 cmp    ebx, 0
                 jne    _loop1
                                                                // до сюда
                 mov    edi, [vector]   // а тут сравниваем сортированную строку с эталонным вектором
                 mov    ecx, n
                 repnz  cmpsd
                 jz     _noLatin                        // не похожа
                 pop    ebx                             // восстанавливаем регистры
                 add    ebx, 4                  // индекс массива (+sizeof(int))
                 pop    ecx
                 loop   _loop0                  // цикл по строкам матрицы
                 jmp    _Latin                  // прошли все строки удачно
_noLatin:
                 pop    eax                             // не удачно
                 pop    eax                             //  - выровняем стек
                 xor    eax, eax                // result = false;
                 mov    result, al
                 jmp    _end
_Latin:
                 mov    eax, 1                  // result = true;
                 mov    result, al
_end:
         }
 
        
        delete [] vector;               // освободим память
        delete [] temp;
        return result;
}
Yandex
Объявления
15.06.2010, 09:49     Сделать вставку асма
Ответ Создать тему
Опции темы

Текущее время: 17:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru