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

Преобразование массива - C++

Восстановить пароль Регистрация
 
KoMaTo3Huk
5 / 5 / 1
Регистрация: 01.05.2012
Сообщений: 48
19.03.2013, 00:59     Преобразование массива #1
Прошу помочь в решении данной задачи:
преобразовать данный 1-мерный массив в 2-хмерный так, чтобы в I столбце 2-хмерного массива располагались эл-ты одномерного (без повторов), во II столбце - кол-во их повторов, в III - точки входа (позиция, на которой впервые встречается данный элемент)

пример прилагается
Миниатюры
Преобразование массива  
Изображения
 
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.03.2013, 00:59     Преобразование массива
Посмотрите здесь:

C++ Преобразование массива по условию
преобразование массива C++
Преобразование элемента массива C++
Преобразование массива C++
Преобразование массива C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4924 / 2667 / 243
Регистрация: 29.11.2010
Сообщений: 7,421
19.03.2013, 02:09     Преобразование массива #2
Если порядок следования в первом столбце неважен, то
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
#include <iostream>
#include <algorithm>
#include <iterator>
#include <random>
#include <vector>
#include <unordered_map>
#include <cstddef>
 
int main()
{
    const std::size_t N = 10;
    std::mt19937 gen { std::random_device()() };
    std::uniform_int_distribution<int> uid(0, 99);
    std::vector<int> v(N);
    std::unordered_map<int, std::size_t> m;
    m.reserve(N);
 
    std::generate(v.begin(), v.begin() + N, [&uid, &gen] { return uid(gen); } );
    for (auto &x : v)
    {
        std::cout << x << " ";
        ++m[x];
    }
    std::cout << std::endl << std::endl;
 
    const std::size_t M = m.size();
    int *arr[3];
    for (int i=0; i < 3; i++)
        arr[i] = new int[M];
    auto it = m.cbegin();
    for (std::size_t i=0; i < M; i++)
    {
        arr[0][i] = it->first;
        arr[1][i] = it->second;
        arr[2][i] = std::distance(v.cbegin(), std::find(v.cbegin(), v.cend(), it->first));
        std::cout << arr[0][i] << " " << arr[1][i] << " " << arr[2][i] << std::endl;
        ++it;
    }
 
    for (int i=0; i < 3; i++)
        delete []arr[i];
}
http://liveworkspace.org/code/2LfsX5
Иначе провести небольшие изменения и превратить std::unordered_map в в std::vector<std:air<int, std::size_t>>;

Не по теме:

Зараза, int arr[3][M]; VLA обзывает

xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
19.03.2013, 02:24     Преобразование массива #3
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
#include <iostream>
#include <algorithm>
#include <map>
 
const int base[] = { 1, 0, 7, 1, 1, 0, 7, 3, 2, 4, 1, 5, 0 };
 
int main()
{
    std::map<int, int> un;
 
    for (size_t i = 0; i < sizeof(base) / sizeof(int); ++i)
        ++un[base[i]];
 
    const int HEIGHT = un.size();
    const int LENGTH = 3;
 
    int** arr = new int*[HEIGHT];
    for (int i = 0; i < HEIGHT; ++i)
        arr[i] = new int[LENGTH];
 
    int index = 0;
    for (std::map<int, int>::const_iterator it = un.begin(); 
            it != un.end(); ++it, ++index)
        arr[index][0] = it->first;
 
    for (int i = 0; i < HEIGHT; ++i)
    {
        arr[i][1] = std::count(base, base + sizeof(base) / sizeof(int), arr[i][0]);
        const int* p = std::find(base, base + sizeof(base) / sizeof(int), arr[i][0]);
        arr[i][2] = std::distance(base, p);
    }
 
    for (int i = 0; i < HEIGHT; ++i) 
        for (int j = 0; j < LENGTH; ++j)
        {
            std::cout << arr[i][j];
            std::cout << ((j == LENGTH-1) ? "\n" : " ");
        }
 
    for (int i = 0; i < HEIGHT; ++i)
        delete [] arr[i];
    delete [] arr;
 
    return 0;
}
KoMaTo3Huk
5 / 5 / 1
Регистрация: 01.05.2012
Сообщений: 48
19.03.2013, 02:25  [ТС]     Преобразование массива #4
Цитата Сообщение от MrGluck Посмотреть сообщение
Если порядок следования в первом столбце неважен, то
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
#include <iostream>
#include <algorithm>
#include <iterator>
#include <random>
#include <vector>
#include <unordered_map>
#include <cstddef>
 
int main()
{
    const std::size_t N = 10;
    std::mt19937 gen { std::random_device()() };
    std::uniform_int_distribution<int> uid(0, 99);
    std::vector<int> v(N);
    std::unordered_map<int, std::size_t> m;
    m.reserve(N);
 
    std::generate(v.begin(), v.begin() + N, [&uid, &gen] { return uid(gen); } );
    for (auto &x : v)
    {
        std::cout << x << " ";
        ++m[x];
    }
    std::cout << std::endl << std::endl;
 
    const std::size_t M = m.size();
    int *arr[3];
    for (int i=0; i < 3; i++)
        arr[i] = new int[M];
    auto it = m.cbegin();
    for (std::size_t i=0; i < M; i++)
    {
        arr[0][i] = it->first;
        arr[1][i] = it->second;
        arr[2][i] = std::distance(v.cbegin(), std::find(v.cbegin(), v.cend(), it->first));
        std::cout << arr[0][i] << " " << arr[1][i] << " " << arr[2][i] << std::endl;
        ++it;
    }
 
    for (int i=0; i < 3; i++)
        delete []arr[i];
}
http://liveworkspace.org/code/2LfsX5
Иначе провести небольшие изменения и превратить std::unordered_map в в std::vector<std:air<int, std::size_t>>;

Не по теме:

Зараза, int arr[3][M]; VLA обзывает

это черезчур сложно,можно как-то попроще?
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
19.03.2013, 02:48     Преобразование массива #5
небольшая оптимизация:
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
#include <iostream>
#include <algorithm>
#include <map>
 
const int base[] = { 1, 0, 7, 1, 1, 0, 7, 3, 2, 4, 1, 5, 0 };
 
int main()
{
    std::map<int, int> un;
 
    for (size_t i = 0; i < sizeof(base) / sizeof(int); ++i)
        ++un[base[i]];
 
    const int HEIGHT = un.size();
    const int LENGTH = 3;
 
    int** arr = new int*[HEIGHT];
    for (int i = 0; i < HEIGHT; ++i)
        arr[i] = new int[LENGTH];
 
    int index = 0;
    for (std::map<int, int>::const_iterator it = un.begin(); 
            it != un.end(); ++it, ++index)
        arr[index][0] = it->first;
 
    for (int i = 0; i < HEIGHT; ++i)
    {
        arr[i][1] = std::count(base, base + sizeof(base) / sizeof(int), arr[i][0]);
        const int* p = std::find(base, base + sizeof(base) / sizeof(int), arr[i][0]);
        arr[i][2] = std::distance(base, p);
        std::cout << arr[i][0] << ' ' << arr[i][1] << ' ' << arr[i][2] << '\n';
    }
 
    for (int i = 0; i < HEIGHT; ++i)
        delete [] arr[i];
    delete [] arr;
 
    return 0;
}
Добавлено через 5 минут
Bash
1
2
3
4
5
6
7
8
9
ilyuha21st@coldshoot:~/Projects$ ./prog
0 3 1
1 4 0
2 1 8
3 1 7
4 1 9
5 1 11
7 2 2
ilyuha21st@coldshoot:~/Projects$
Добавлено через 3 минуты
в 5-ю строчку кода можно засунуть любую последовательность. Будет работать всё ок.

Добавлено через 7 минут
можно и ещё короче:
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
#include <iostream>
#include <algorithm>
#include <map>
 
const int base[] = { 1, 0, 7, 1, 1, 0, 7, 3, 2, 4, 1, 5, 0 };
 
int main()
{
    std::map<int, int> un;
 
    for (size_t i = 0; i < sizeof(base) / sizeof(int); ++i)
        ++un[base[i]];
 
    const int HEIGHT = un.size();
    const int LENGTH = 3;
 
    int** arr = new int*[HEIGHT];
    for (int i = 0; i < HEIGHT; ++i)
        arr[i] = new int[LENGTH];
 
    std::map<int, int>::const_iterator it = un.begin();
    for (int i = 0; i < HEIGHT; ++i, ++it)
    {
        arr[i][0] = it->first;
        arr[i][1] = std::count(base, base + sizeof(base) / sizeof(int), arr[i][0]);
        const int* p = std::find(base, base + sizeof(base) / sizeof(int), arr[i][0]);
        arr[i][2] = std::distance(base, p);
        std::cout << arr[i][0] << ' ' << arr[i][1] << ' ' << arr[i][2] << '\n';
    }
 
    for (int i = 0; i < HEIGHT; ++i)
        delete [] arr[i];
    delete [] arr;
 
    return 0;
}
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4924 / 2667 / 243
Регистрация: 29.11.2010
Сообщений: 7,421
19.03.2013, 15:38     Преобразование массива #6
xtorne21st, смысл использования std::map ? Тратить время на ненужную сортировку и на доступ к элементу, который в несколько раз хуже std::unordered_map ?

Добавлено через 1 минуту
Цитата Сообщение от KoMaTo3Huk Посмотреть сообщение
это черезчур сложно,можно как-то попроще?
скажите, какие строчки неясны, нету ни одной класса или функции, который не были бы подробно описаны тут или тут
KoMaTo3Huk
5 / 5 / 1
Регистрация: 01.05.2012
Сообщений: 48
19.03.2013, 16:02  [ТС]     Преобразование массива #7
Цитата Сообщение от MrGluck Посмотреть сообщение
xtorne21st, смысл использования std::map ? Тратить время на ненужную сортировку и на доступ к элементу, который в несколько раз хуже std::unordered_map ?

Добавлено через 1 минуту

скажите, какие строчки неясны, нету ни одной класса или функции, который не были бы подробно описаны тут или тут
дело в том что по программе мы большинство функций не учили поэтому их лучше не использовать
ps: я уже почти сам решил задачу
pps: кстати вот вариант решения у одногруппника и он намного короче и без всяких странных библиотек и ф-ций
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4924 / 2667 / 243
Регистрация: 29.11.2010
Сообщений: 7,421
19.03.2013, 16:20     Преобразование массива #8
KoMaTo3Huk, всего лишь используется подобие ассоциативного массива, где идет связка - число - количество повторов. А в третий столбец добавляется первое найденное положение элемента. По сути, ничего сложного тут нет, кроме незнакомого синтаксиса.

Добавлено через 2 минуты
Кстати, если оперировать лишь массивами, то надо, как минимум, обходить последовательность два раза. Первый - узнать количество элементов для одной из размерности двумерного. А далее делать заполнение с проверками, а есть ли элемент уже там. В моем случае, данные ненужные проверки и итерации не используются.
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
19.03.2013, 16:26     Преобразование массива #9
Цитата Сообщение от MrGluck Посмотреть сообщение
xtorne21st, смысл использования std::map ? Тратить время на ненужную сортировку и на доступ к элементу, который в несколько раз хуже std::unordered_map
Поясните, пожалуйста.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.03.2013, 16:32     Преобразование массива
Еще ссылки по теме:

Внутреннее устройство многомерного массива и неявное преобразование массива в указатель C++
Преобразование одномерного массива C++
Преобразование одномерного массива C++

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

Или воспользуйтесь поиском по форуму:
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4924 / 2667 / 243
Регистрация: 29.11.2010
Сообщений: 7,421
19.03.2013, 16:32     Преобразование массива #10
Цитата Сообщение от xtorne21st Посмотреть сообщение
Поясните, пожалуйста.
контейнер std::map производит балансировку ключей, что является ненужной в задаче и требует дополнительных расходов, также доступ к элементу в std::map производится за логарифмичное размеру время (благодаря, фактически, поиску по сбалансированному дереву), в std::unordered_map то же самое делается почти всегда за константное время.
Т.о. если в задаче не требуется вывести результат с сортировкой по первому столбцу, то использование std::map нецелесообразно.
Yandex
Объявления
19.03.2013, 16:32     Преобразование массива
Ответ Создать тему
Опции темы

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