Как мне распечатать вхождения каждого элемента в области, заданной ограничивающим прямоугольником 2d-матрицы?

#c #multidimensional-array #frequency-distribution

#c #многомерный массив #частотное распределение

Вопрос:

 void searchValidEntries(int arr[101][101], int XL, int YL, int XH, int YH){
  int sizeX = (XL - XH)   1;
  int sizeY = (YH - YL)   1;


  for (int i = XH; i < XH   sizeX; i    ){
    for (int j = YL; j < YL   sizeY; j  ){
      
      cout << arr[i][j] << ' ';

    }
  }

}
 

В приведенном выше коде я перебираю ограничивающий прямоугольник в 2d-массиве.
Координаты массива, которому будет присвоен ограничивающий прямоугольник, и сам массив включаются в качестве параметров в функцию : int arr[101][101], int XL, int YL, int XH, int YH

Прокомментированный код cout << arr[i][j] << ' '; выводит элементы в указанном ограничивающем прямоугольнике, и я запустил его, поэтому я знаю, что он действительно выводится.

Тем не менее, я хочу получить частоту каждого элемента в ограничивающем прямоугольнике, за исключением 0, для распечатки.

Я предполагаю, что требуемый код будет отправлен в цикл for, но я понятия не имею, с чего начать, поскольку сейчас я изучаю всю семантику C .

Я ожидаю вывода чего-то вроде:

 5 --> 3
83 --> 2
23 --> 9
 

Ответ №1:

Для этого существует несколько способов. Я предлагаю использовать вектор< pair< int, int >> .

Каждый элемент этого вектора содержит две вещи:
1 — значение, которое было посещено
2- вхождение этого значения
Я добавил несколько комментариев к своему коду, чтобы прояснить этот метод.

 #include <iostream>
using namespace std;
#include <vector>

void searchValidEntries(int arr[101][101], int XL, int YL, int XH, int YH) {

    vector<pair<int, int>> holder_vec; 

    int sizeX = (XL - XH)   1;
    int sizeY = (YH - YL)   1;


    for (int i = XH; i < XH   sizeX; i  ) {
        for (int j = YL; j < YL   sizeY; j  ) {

            bool thisElementIsNew = true; // By default, it's the first occurence of this element.
            for (autoamp; it : holder_vec) { // Iterate the vector of previously considered elements and chekc this target value.

                if (it.first == arr[i][j]) {
                    it.second  ; // Increase the occurence of this element by one.
                    thisElementIsNew = false; // This value has been previously visited.
                    break; // Stop iterating vector
                }               
            }

            if (thisElementIsNew) { // Add a new pair to holder_vec;
                const pair<int, int> newPair(arr[i][j], 1); // newPair.first = The value of this element.   // newPair.second = the occurence of this value.
                holder_vec.push_back(newPair);  
            }

        }
    }

    // Print result:
    for (const autoamp; it : holder_vec) {
        cout << it.first << " ---> " << it.second << endl;
    }

}
 

Комментарии:

1. Вам не нужно перебирать контейнер, если вы используете, например, map . Что-то вроде этого: map<int, int> nmap; // число, количество std::pair<std::map<int, int>::итератор, bool> ret; for (int i = XL; i < XL sizeX; i ) { for (int j = YL; j < YL sizeY; j ) { если (arr[i][j] > 0) { ret = nmap.insert(std::pair<int, int>(arr[i][j], 1)); если (ret.second == false) ret.first->second ; } } } для (auto i : nmap) cout << i.first << » : » << i.second << endl;