在数组中提取和排序数据?

时间:2014-09-02 20:55:54

标签: c++ arrays

这是我的阵列:

int grid[gridsize+1] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 2, 2, 4, 1, 5, 3, 3, 6, 2, 6, 4, 5, 5, 5, 3, 6, 2, 6, 4, 4, 5, 5, 5, 6, 6, 6, 4, 7, 7, 8, 5, 8, 8, 8, 4, 7, 7, 8, 8, 8, 8, 8, 4, 7, 7, 7, 7, 8, 8, 8 };

每个数字代表一种颜色,我想为每个唯一的数字创建多个数组。创建的数组将存储原始数组中该数字的位置。

e.g

colour1[5]
[0]=0       //because the number 1 is stored in element 0.
[1]=1
[2]=8
[3]=9

每次运行时网格中的数字都会改变,所以事情需要是动态的吗? 我可以编写效率低下的代码来实现这一点,但它只是重复性的,我无法理解将其转化为可以放入函数的方法。

这就是我所拥有的;

int target_number = 1
grid_size = 64;
int counter = -1;
int counter_2 = -1;
int colour_1;
while (counter < grid_size + 1){
   counter = counter + 1;
   if (grid[counter] == target)
       counter_2 = counter_2 + 1;
       colour_1[counter_2] = counter;
   }
}

我必须为每种颜色执行此操作,当我尝试创建一个函数时,它无法访问main中的主数组,因此没用。

4 个答案:

答案 0 :(得分:1)

也许最好使用一些关联容器,例如std::unordered_mapstd::multimap

这是一个示范程序

#include <iostream>
#include <map>

int main()
{
    int grid[] = 
    { 
        1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 2, 2, 
        4, 1, 5, 3, 3, 6, 2, 6, 4, 5, 5, 5, 3, 6, 2, 6, 
        4, 4, 5, 5, 5, 6, 6, 6, 4, 7, 7, 8, 5, 8, 8, 8, 
        4, 7, 7, 8, 8, 8, 8, 8, 4, 7, 7, 7, 7, 8, 8, 8 
    };

    std::multimap<int, int> m;

    int i = 0;
    for ( int x : grid )
    {
        m.insert( { x, i++ } );
    }

    std::multimap<int, int>::size_type n = m.count( 1 );
    std::cout << "There are " << n << " elements of color 1:";

    auto p = m.equal_range( 1 );

    for ( ; p.first != p.second ; ++p.first )
    {
        std::cout << ' ' << p.first->second;
    }

    std::cout << std::endl;

    return 0;
}

输出

There are 6 elements of color 1: 0 1 8 9 10 17

或者

#include <iostream>
#include <map>

int main()
{
    int grid[] = 
    { 
        1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 2, 2, 
        4, 1, 5, 3, 3, 6, 2, 6, 4, 5, 5, 5, 3, 6, 2, 6, 
        4, 4, 5, 5, 5, 6, 6, 6, 4, 7, 7, 8, 5, 8, 8, 8, 
        4, 7, 7, 8, 8, 8, 8, 8, 4, 7, 7, 7, 7, 8, 8, 8 
    };

    std::multimap<int, int> m;

    int i = 0;
    for ( int x : grid )
    {
        m.insert( { x, i++ } );
    }

    for ( auto first = m.begin(); first != m.end(); )
    {
        auto n = m.count( first->first );
        std::cout << "There are " << n 
                  << " elements of color " << first->first << ":";

        auto p = m.equal_range( first->first );

        for ( ; p.first != p.second ; ++p.first )
        {
            std::cout << ' ' << p.first->second;
        }

        std::cout << std::endl;

        first = p.first;
    }

    return 0;
}

输出

There are 6 elements of color 1: 0 1 8 9 10 17
There are 10 elements of color 2: 2 3 4 5 6 7 14 15 22 30
There are 6 elements of color 3: 11 12 13 19 20 28
There are 7 elements of color 4: 16 24 32 33 40 48 56
There are 8 elements of color 5: 18 25 26 27 34 35 36 44
There are 7 elements of color 6: 21 23 29 31 37 38 39
There are 8 elements of color 7: 41 42 49 50 57 58 59 60
There are 12 elements of color 8: 43 45 46 47 51 52 53 54 55 61 62 63

答案 1 :(得分:1)

我认为您最好使用计数排序,这是一种排序算法,可以很好地排序大型简单类型组,其中许多重复值优于O(n log n)时间。这是一些示例代码,为了清楚起见注释:

// set up our grid
int grid_raw[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 2, 2, 4, 1, 5, 3, 3, 6, 2, 6, 4, 5, 5, 5, 3, 6, 2, 6, 4, 4, 5, 5, 5, 6, 6, 6, 4, 7, 7, 8, 5, 8, 8, 8, 4, 7, 7, 8, 8, 8, 8, 8, 4, 7, 7, 7, 7, 8, 8, 8};

// build a vector using our raw list of numbers.  This calls the range constructor:
// (number 3) http://www.cplusplus.com/reference/vector/vector/vector/
// The trick to using sizeof is that I don't have to change anything if my grid's
// size changes (sizeof grid_raw gives the number of bytes in the whole array, and
// sizeof *grid_raw gives the number of bytes in one element, so dividing yields
// the number of elements.
std::vector<int> grid(grid_raw, grid_raw + sizeof grid_raw / sizeof *grid_raw);

// count the number of each color.  std::map is an associative, key --> value
// container that's good for doing this even if you don't know how many colors
// you have, or what the possible values are.  Think of the values in grid as being
// colors, not numbers, i.e. ++buckets[RED], ++buckets[GREEN], etc...
// if no bucket exists for a particular color yet, then it starts at zero (i.e,
// the first access of buckets[MAUVE] will be 0, but it remembers each increment)
std::map<int, int> buckets;
for (vector<int>::iterator i = grid.begin(); i != grid.end(); ++i)
    ++buckets[*i];

// build a new sorted vector from buckets, which now contains a count of the number
// of occurrences of each color.  The list will be built in the order of elements
// in buckets, which will default to the numerical order of the colors (but can
// be customized if desired).
vector<int> sorted;
for (map<int, int>::iterator b = buckets.begin(); b != buckets.end(); ++b)
    sorted.insert(sorted.end(), b->second, b->first);

// at this point, sorted = {1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, ...}

Read more about the Counting Sort (includes example python code)

这是一个ideone,用于演示对网格进行排序。

我并非100%确定这会回答您的问题...但您在标题中包含了排序,即使您在问题正文中没有说明任何内容。

答案 2 :(得分:1)

您可以使用vector<vector<int>>代表您的计数器。不需要地图或排序。

编辑:添加额外的传递以确定最大颜色,因此不需要调整运行时。

以下是代码:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    int grid[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, /*...*/};
    const size_t gridSize = std::end(grid) - std::begin(grid);
    int maxColor = *std::max_element(std::begin(grid), std::end(grid));
    std::vector<std::vector<int>> colorPos(maxColor);

    for (size_t i = 0; i < gridSize; ++i)
        colorPos[grid[i] - 1].push_back(i);

    for (size_t i = 0; i < colorPos.size(); ++i) {
        std::cout << (i + 1) << ": ";
        for (int p : colorPos[i])
            std::cout << p << ' ';
        std::cout << std::endl;
    }

    return 0;
}

输出:

1: 0 1 8 9 10 17
2: 2 3 4 5 6 7 14 15 22 30
3: 11 12 13 19 20 28
4: 16 24 32 33 40 48 56
5: 18 25 26 27 34 35 36 44
6: 21 23 29 31 37 38 39
7: 41 42 49 50 57 58 59 60
8: 43 45 46 47 51 52 53 54 55 61 62 63

答案 3 :(得分:1)

如果您不被迫使用普通数组,我可以为位置向量提出​​颜色映射:

  • map是一个关联容器,对于任何颜色键都返回一个引用
  • 此处使用的引用将是包含所有位置的vector(一种动态数组)。

您的输入网格包含颜色代码:

typedef int colorcode;   // For readability, to make diff between counts, offsets, and colorcodes
colorcode grid[] = { 1, 1, /* .....input data as above.... */ ,8  };
const size_t gridsize = sizeof(grid) / sizeof(int);

然后您将定义颜色贴图:

map<colorcode, vector<int>> colormap;
//      ^^^ key      ^^^ value maintained for the key  

通过这种方法,您的color1[..]将被更动态的corlormap[1][..]取代。并且非常容易来填充:

for (int i = 0; i < gridsize; i++) 
    colormap[grid[i]].push_back(i);  // add the new position to the vector returned for the colormap of the color 

要验证结果,您可以遍历地图,并为每个现有值迭代这些位置:

for (auto x : colormap) {     // for each color in the map 
    cout << "Color" << x.first << " : ";  // display the color (key)
    for (auto y : x.second)     // and iterate through the vector of position 
        cout << y << " ";
    cout << endl;
}

您不确定您拥有多少种不同的颜色代码,但是您希望存储以便进行评估