[英]Sort matrix by scheme
我需要按下面的方案對矩陣的負元素進行排序。 我試圖從另一個角落進行排序,但它也不起作用。 我認為,我需要將矩陣元素放在一維數組中。 它應該在雞尾酒排序中排序,但排序的類型不是我的主要問題。
我的代碼:
int main() {
const int n = 4, m = 4;
int t, v[n*m], arr[n][m], i, j, tmp, lt, rt;
lt = 0;
rt = t;
srand(time(NULL));
for (i = 0; i < n; i++) {
for(j=0; j < m; j++) {
arr[i][j] = rand() % 100 - 50;
}
cout << endl;
}
t = 0;
for (i = 0; i < n; i++) {
for(j = 0; j < m; j++) {
if (arr[i][j] < 0) {
v[t] = arr[i][j];
t++;
}
}
}
while(lt <= rt) {
for (i = rt; i >= lt; i--) {
if(v[i] > v[i-1]) {
swap(v[i], v[i-1]);
}
}
lt++;
for (i = lt; i <=rt; i++) {
if(v[i] > v[i-1]) {
swap(v[i], v[i-1]);
}
}
rt--;
}
for (i = 0; i < t; i++) {
cout << v[i] << " ";
}
int r = 0;
for (i = 0; i < n; i++) {
for(j = 0; j < m; j++) {
if(arr[i][j] < 0) {
arr[i][j] = v[r];
r++;
}
}
}
}
這個問題聽起來很簡單,但事實並非如此。 其中有很多“間接”,您需要使用索引而不是值。
我很快檢查了你的代碼。 它主要是 C 代碼(不是 C++)和錯誤的。
例子:
int t;
rt = t;
有了它,您就有了一個未初始化的變量,用作數組索引。 這是一個致命的錯誤。 您還使用了 VLA(可變長度數組)。 這在 C++ 中是不允許的。 而且您使用的是普通的 C 樣式數組。 這是你不應該做的。 使用std::vector
,它可以動態增長或至少使用std::array
代替。 並且請給你的變量更有意義的名字。
我將向您展示一個(在眾多可能的解決方案中),但我將使用 C++。
手頭問題的核心是找到給定矩陣中元素的行和列索引。 這並不容易。
但是好吧,讓我們從那個開始。 如果您使用矩陣繪制圖片,然后在對角線上添加虛線,您就會看到索引。
如果矩陣的維度是dim
那么總是有dim + dim – 1
對角線。 對角線首先具有增加的元素數量,在碰到中間最長的主要對角線后,元素數量減少。 所以我們迭代所有對角線的數量,由中間對角線分割,並計算相應的行和列索引。 這有點棘手,但過一段時間你就會發現。
生成的行和列索引將存儲在結構中。 具有所有行和列索引的所有對角線將存儲在結構向量中。 此外,我們添加原始矩陣單元格的值。
關於排序。 開發自己的排序算法顯然是您的任務。 為此,我創建了一個函數yourSort
,您可以在其中放入自己的算法。 我只是使用標准算法( std::sort
)。 你可以用你自己的函數替換std::sort
。
在主要我放了一些驅動程序代碼。 首先,我們創建一個矩陣並用隨機值填充它。 然后我們計算行和列索引。 具有負值的條目將被提取和排序。 然后我們將結果復制回原始矩陣。
如上所述,不是那么容易,因為索引的間接性和只使用負數的約束。
但無論如何。 請參見:
#include <iostream>
#include <vector>
#include <utility>
#include <random>
#include <algorithm>
#include <iterator>
#include <iomanip>
// Create types that are easy to understand
using RowIndex = size_t;
using ColumnIndex = size_t;
// Here we store the position (row and column) and the value of one cell in the matrix
struct PositionAndValue {
// Constructors
PositionAndValue() {};
PositionAndValue(const RowIndex r, const ColumnIndex c, const int v) : rowIndex(r), columnIndex(c), value(v) {};
// Data
RowIndex rowIndex{};
ColumnIndex columnIndex{};
int value{};
};
// Main data types
using Columns = std::vector<int>;
using Matrix = std::vector<Columns>;
using Diagonal = std::vector<PositionAndValue>;
// Fill matrix with random values. Standard function
void fillMatrixRandom(Matrix& m) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(-50, 50);
std::for_each(m.begin(), m.end(), [&](Columns &c) {std::for_each(c.begin(), c.end(), [&](int &j) { j = dis(gen);}); });
}
// Calculate the indices for all diagonals
Diagonal calculateDiagonalIndices(const Matrix& matrix) {
// The return value
Diagonal diagonalIndices{};
// Matrix dimension
const size_t MatrixDimension{ matrix.size() };
// Overall number of diagonals for this matrix
const size_t NumberOfDiagonals{ MatrixDimension + MatrixDimension - 1 };
// index of middle (longest) diagonal
const size_t MiddleDiagonal { NumberOfDiagonals / 2 + 1 };
// Counter for element index in one specific diagonal
size_t elementInDiagonal{ 0 };
for (size_t diagonalIndex = 1; diagonalIndex <= NumberOfDiagonals; ++diagonalIndex) {
// If we are above the middle diagonal
if (diagonalIndex <= MiddleDiagonal) {
// Number of elements in diagonal will increase
++elementInDiagonal;
for (size_t j = 0; j < elementInDiagonal; ++j) {
// Calculate row and column and add to result
const RowIndex row{ j };
const ColumnIndex col{ diagonalIndex - j - 1 };
diagonalIndices.emplace_back(PositionAndValue(row, col, matrix[row][col]));
}
}
else {
// We are below the middle diagonal
// Number of elements in diagonal will decrease
--elementInDiagonal;
for (size_t j = 0; j < elementInDiagonal; ++j) {
// Calculate row and column and add to result
const RowIndex row{ diagonalIndex + j - MatrixDimension };
const ColumnIndex col{ MatrixDimension - j - 1 };
diagonalIndices.emplace_back(PositionAndValue(row, col, matrix[row][col]));
}
}
}
return diagonalIndices;
}
// Simple sorting function using std algorithms
template <typename T, typename ValueType>
void yourSort(std::vector<T>& vec, ValueType T::* mPtr) {
// We will extract the negative values
std::vector<ValueType> vt{};
// Extract
std::transform(vec.begin(), vec.end(), std::back_inserter(vt), [&](const T & s) {return s.*mPtr; });
// Sort. ***** Please put here your sorting function
std::sort(vt.begin(), vt.end());
// Put back
std::for_each(vec.begin(), vec.end(), [&, i = 0U](T& s) mutable{s.*mPtr = vt[i++]; });
}
// Driver code
int main() {
// Lets use a matrix of this size
constexpr size_t MatrixDimension = 4U;
// Small lambda for printing a matrix
auto printMatrix = [](const Matrix & m) {std::for_each(m.begin(), m.end(), [](const Columns & c) {
for (int i : c) std::cout << std::setw(4) << i; std::cout << "\n"; }); std::cout << "\n"; };
// Define a matrix and fill it with random values
Matrix matrix(MatrixDimension, Columns(MatrixDimension));
fillMatrixRandom(matrix);
printMatrix(matrix);
// Calulate the indices on the diagonals
Diagonal diagonal{ calculateDiagonalIndices(matrix) };
// Extract the negatives
Diagonal negativesOnDiagonal{};
std::copy_if(diagonal.begin(), diagonal.end(), std::back_inserter(negativesOnDiagonal),
[](const PositionAndValue & pv) { return pv.value < 0; });
// Sort
yourSort(negativesOnDiagonal, &PositionAndValue::value);
// Copy back
std::for_each(negativesOnDiagonal.begin(), negativesOnDiagonal.end(),
[&matrix](const PositionAndValue & pv) { matrix[pv.rowIndex][pv.columnIndex] = pv.value; });
printMatrix(matrix);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.