逆置问题无非就是选取某些元素进行交换
本文先考虑全逆置和区间逆置
然后引出最前面和最后面逆置
最后用前面的思路求解循环移位问题
下图给出对循环移位的两种方法其实思路是一致的
聪明的小伙伴可能已经发现了,其实上述所有思路都可以用 一个区间逆置函数 实现
// main function main.cpp
#include
#include
#include "SolutionOfReverse.h"
int main() {
std::vector<int> vec{
2, 3, 4, 5, 6, 7, 8, 9 };
SolutionOfReverse myreverse(vec);
std::cout << "print all the elements:" << '\n';
myreverse.print(vec);
std::cout << "reverse all the elements:" << '\n';
myreverse.reverse(vec);
myreverse.print(vec);
std::cout << "reverse from 2 to 4:" << '\n';
myreverse.reverse(vec, 2, 4);
myreverse.print(vec);
std::cout << "reverse the first 3 elements:" << '\n';
myreverse.reverseFirst(vec, 3);
myreverse.print(vec);
std::cout << "reverse the last 3 elements:" << '\n';
myreverse.reverseLast(vec, 3);
myreverse.print(vec);
std::cout << "circulate 3 positions to the left:" << '\n';
myreverse.moveToLeft(vec, 3);
myreverse.print(vec);
std::cout << "circulate 3 positions to the right:" << '\n';
myreverse.moveToRight(vec, 3);
myreverse.print(vec);
system("pause");
return 0;
}
接下来是类的头文件
// SolutionOfReverse.cpp
#pragma once
#include
#include
typedef unsigned int size_t;
class SolutionOfReverse
{
public:
SolutionOfReverse();
SolutionOfReverse(std::vector<int> _vec);
~SolutionOfReverse();
// print all the elements
void print(std::vector<int>&);
// reverse all the elements
void reverse(std::vector<int>&);
// reverse from begin to end;
void reverse(std::vector<int>&, size_t, size_t);
// reverse the first k elements
void reverseFirst(std::vector<int>&, size_t);
// reverse the last k elements
void reverseLast(std::vector<int>&, size_t);
// circulate k positions to the left
void moveToLeft(std::vector<int>&, int);
// circulate k positions to the right
void moveToRight(std::vector<int>&, int);
private:
inline void swap(int& a, int& b);
private:
std::vector<int> vec;
};
头文件中函数的实现
// SolutionOfReverse.cpp
#include "SolutionOfReverse.h"
SolutionOfReverse::SolutionOfReverse() {
}
SolutionOfReverse::SolutionOfReverse(std::vector<int> _vec) : vec(_vec) {
}
SolutionOfReverse::~SolutionOfReverse() {
}
inline void SolutionOfReverse::swap(int& a, int& b) {
auto temp = a;
a = b;
b = temp;
}
// print all the elements
void SolutionOfReverse::print(std::vector<int>& vec) {
for (auto const& v : vec) {
std::cout << v << ' ';
}
std::cout << '\n';
}
// reverse all the elements
void SolutionOfReverse::reverse(std::vector<int>& vec) {
size_t r = vec.size() - 1;
size_t l = 0;
while (l < r) {
using std::swap;
swap(vec[l++], vec[r--]);
}
}
// reverse from begin to end
// 与数组下标相对应
void SolutionOfReverse::reverse(std::vector<int>& vec, size_t begin, size_t end) {
if (begin > end) {
std::cerr << "区间错误" << '\n';
return;
}
if (end > vec.size()) {
std::cerr << "越界" << '\n';
return;
}
while (begin < end) {
using std::swap;
swap(vec[begin++], vec[end--]);
}
}
// reverse the first k elements
void SolutionOfReverse::reverseFirst(std::vector<int>& vec, size_t k) {
if (k > vec.size()) {
std::cerr << "越界" << '\n';
return;
}
size_t l = 0;
while (l < k) {
using std::swap;
swap(vec[l++], vec[--k]); // k 要先减一
}
}
// reverse the last k elements
void SolutionOfReverse::reverseLast(std::vector<int>& vec, size_t k) {
auto n = vec.size();
if (k > n) {
std::cerr << "越界" << '\n';
return;
}
auto l = n - k;
while (l < n) {
using std::swap;
swap(vec[l++], vec[--n]); // n 先减一不然会越界
}
}
// circulate k positions to the left
void SolutionOfReverse::moveToLeft(std::vector<int>& vec, int k) {
auto n = vec.size();
k %= n;
// reverse(vec, 0, k - 1);
// reverse(vec, k, n - 1);
reverseFirst(vec, k); // 逆置前 k 个元素
reverseLast(vec, n - k); // 逆置后 n - k 个元素
reverse(vec);
}
// circulate k positions to the right
void SolutionOfReverse::moveToRight(std::vector<int>& vec, int k) {
auto n = vec.size();
k %= n;
// reverse(vec, 0, n - k - 1);
// reverse(vec, n - k, n - 1);
reverseFirst(vec, n - k); // 逆置前 n - k 个元素
reverseLast(vec, k); // 逆置后 k 个元素
reverse(vec);
}
全用一个区间逆置函数解决,为了简便采用面向过程实现
#include
#include
// circulate k positions to the left
void moveToLeft(std::vector<int>& vec, int k);
// reverse from begin to end
// 与数组下标相对应
void reverse(std::vector<int>& vec, size_t begin, size_t end);
// print all the elements
void print(std::vector<int>& vec);
// circulate k positions to the right
void moveToRight(std::vector<int>& vec, int k);
int main() {
std::vector<int> vec{
2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << "print all the elements:" << '\n';
print(vec);
std::cout << "reverse all the elements:" << '\n';
auto n = vec.size();
reverse(vec, 0, n - 1);
print(vec);
std::cout << "reverse from 2 to 4:" << '\n';
reverse(vec, 2, 4);
print(vec);
std::cout << "reverse the first 3 elements:" << '\n';
reverse(vec, 0, 2);
print(vec);
std::cout << "reverse the last 3 elements:" << '\n';
reverse(vec, n - 3, n - 1);
print(vec);
std::cout << "circulate 3 positions to the left:" << '\n';
moveToLeft(vec, 3);
print(vec);
std::cout << "circulate 3 positions to the right:" << '\n';
moveToRight(vec, 3);
print(vec);
system("pause");
return 0;
}
// circulate k positions to the left
void moveToLeft(std::vector<int>& vec, int k) {
auto const n = vec.size();
k %= n;
reverse(vec, 0, k - 1);
reverse(vec, k, n - 1);
reverse(vec, 0, n - 1);
}
// reverse from begin to end
// 与数组下标相对应
void reverse(std::vector<int>& vec, size_t begin, size_t end) {
if (begin > end) {
std::cerr << "区间错误" << '\n';
return;
}
if (end > vec.size()) {
std::cerr << "越界" << '\n';
return;
}
while (begin < end) {
using std::swap;
swap(vec[begin++], vec[end--]);
}
}
// print all the elements
void print(std::vector<int>& vec) {
for (auto const& v : vec) {
std::cout << v << ' ';
}
std::cout << '\n';
}
// circulate k positions to the right
void moveToRight(std::vector<int>& vec, int k) {
auto const n = vec.size();
k %= n;
reverse(vec, 0, n - k - 1);
reverse(vec, n - k, n - 1);
reverse(vec, 0, n - 1);
}