提取和排序数组中的数据

Extracting and sorting data in an array?

本文关键字:数据 数组 排序 提取      更新时间:2023-10-16

这是我的数组:

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 };

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

例如

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中的主数组,所以没有用。

您只需使用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

我认为您最好使用计数排序,这是一种非常好的排序算法,可以在比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, ...}

阅读更多关于计数排序(包括示例python代码)

这里有一个ideone演示如何对网格进行排序。

我不能百分之百肯定这能回答你的问题。。。但你在标题中包含了排序,尽管你在问题正文中没有对此发表任何看法。

也许最好使用一些关联容器,例如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

如果你不被迫使用普通数组,我可以提出一个颜色到位置向量的映射:

  • 映射是一个关联容器,对于任何颜色键,它都返回一个引用
  • 这里使用的引用将是包含所有位置的向量(一种动态数组)

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

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;
}

你不确定你有多少不同的颜色代码,但你想为账户存储