C++
number grouping
programming
algorithms
data structures

Group the numbers C

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Grouping numbers is a common C and C++ task that appears in log processing, analytics, and interview problems. The phrase "group numbers" can mean different things: grouping equal values, grouping by a rule (like odd versus even), or grouping consecutive values into ranges. A good solution starts by defining the grouping rule clearly, then choosing a data structure that makes the operation predictable in both runtime and memory usage. In practice, std::vector, std::unordered_map, and one pass over sorted data solve most cases. This guide walks through practical patterns and shows how to implement them safely and efficiently.

Core Sections

Define the grouping rule before writing code

Many bugs come from coding too early. If the requirement says "group numbers," confirm whether order matters and whether duplicates are meaningful. These questions decide your approach.

  • If order does not matter and you need counts, use a hash map.
  • If order matters and you need contiguous groups, scan the original array.
  • If you need ranges like 1-3, 5-6, sort first, then merge neighbors.

For counting frequencies:

cpp
1#include <unordered_map>
2#include <vector>
3
4std::unordered_map<int, int> countValues(const std::vector<int>& nums) {
5    std::unordered_map<int, int> freq;
6    for (int n : nums) {
7        ++freq[n];
8    }
9    return freq;
10}

This is average O(n) time and O(k) space where k is unique values.

Group consecutive numbers into ranges

If you need output like [1,2,3,5,6,9] -> [1-3, 5-6, 9], sort first and then walk once. This is reliable and easy to test.

cpp
1#include <algorithm>
2#include <utility>
3#include <vector>
4
5std::vector<std::pair<int, int>> groupRanges(std::vector<int> nums) {
6    if (nums.empty()) return {};
7    std::sort(nums.begin(), nums.end());
8
9    std::vector<std::pair<int, int>> ranges;
10    int start = nums[0];
11    int end = nums[0];
12
13    for (size_t i = 1; i < nums.size(); ++i) {
14        if (nums[i] <= end + 1) {
15            end = nums[i];
16        } else {
17            ranges.push_back({start, end});
18            start = end = nums[i];
19        }
20    }
21    ranges.push_back({start, end});
22    return ranges;
23}

This handles duplicates because nums[i] <= end + 1 merges them naturally.

Group by custom buckets

Sometimes grouping means assigning each value to a category, like score buckets (0-9, 10-19, and so on). Create a bucket function and keep the loop simple.

cpp
1#include <map>
2#include <string>
3#include <vector>
4
5std::string bucketFor(int n) {
6    int lower = (n / 10) * 10;
7    int upper = lower + 9;
8    return std::to_string(lower) + "-" + std::to_string(upper);
9}
10
11std::map<std::string, std::vector<int>> groupByBucket(const std::vector<int>& nums) {
12    std::map<std::string, std::vector<int>> grouped;
13    for (int n : nums) {
14        grouped[bucketFor(n)].push_back(n);
15    }
16    return grouped;
17}

std::map keeps keys sorted, which is useful for display and reporting.

Performance guidance

For large input sizes, minimize unnecessary copies. Pass vectors as const& unless you intentionally mutate local copies (as in sorting). If your values are bounded (for example 0..1000), an array counter can outperform hash maps. Also measure before and after changes; assumptions about speed are often wrong on real data.

Common Pitfalls

  • Treating all grouping problems as identical, without first defining whether order, duplicates, or ranges matter.
  • Sorting when you do not need sorted output, which adds O(n log n) cost without value.
  • Using std::unordered_map in code paths that require deterministic key order in output.
  • Forgetting edge cases like empty input, one-element input, negative numbers, or duplicate values.
  • Returning grouped results in an unclear format that forces downstream code to re-parse your data.

Summary

Grouping numbers in C and C++ is straightforward once you choose the right interpretation of "group." Use hash maps for frequency counts, one pass over sorted data for range grouping, and explicit bucket functions for categorical grouping. Keep code readable, isolate the grouping rule, and test edge cases early. Most production issues come from ambiguous requirements, not complex algorithms. If you lock down the grouping contract first, the implementation is usually small, fast, and easy to maintain.


Course illustration
Course illustration

All Rights Reserved.