交换两数是在编程中经常会遇到的问题,如何兼顾时间与空间完成编程会在比赛中有大用,说不定就能解决超时
问题,下面是几种不使用中间变量就能够完成两数交换的方法
异或法
int a = 5, b = 10;
a = a ^ b; // a = 15 (5 ^ 10)
b = a ^ b; // b = 5 (15 ^ 10)
a = a ^ b; // a = 10 (15 ^ 5)
// 交换后 a = 10, b = 5
这种运算方法运算速度很快,在运算速度上甚至超过了C++中函数swap(a,b)
,实测在对10^8
个数进行完全交换只需要5.5s,而使用swap
函数需要5.8s,如果在做编程题使用swap
超时情况下可以考虑这种方法,适合在内存受限或对性能要求较高的场合使用。
但是这种方法局限性很大,只能够对整数int
类型的数做运算,而浮点数不支持异或运算,代码的可读性差。
函数swap
C++ 标准库提供了一个内置的交换函数 std::swap,可以用来交换两个变量的值。使用这个函数非常简单,不需要自己实现交换逻辑。
int a = 5, b = 10;
std::swap(a,b); //交换两数
速度经过编译器的优化,能够达到异或法的速度,同时很简洁,从 C++11 开始,std::swap
可以利用移动语义来提高性能,相较于复制更加的高效。
template <typename T>
void swap(T& a, T& b) {
T temp = std::move(a); // 将 a 的值移动到 temp
a = std::move(b); // 将 b 的值移动到 a
b = std::move(temp); // 将 temp 的值移动到 b
}
元组
使用元组std::tuple
是 C++11 及以上版本中提供的一种方法,可以方便地交换两个或多个值。元组是一个固定大小的集合,可以包含不同类型的值。
#include <iostream>
#include <tuple> // 包含 std::tuple 和 std::tie
void tupleSwap(int& a, int& b) {
std::tie(a, b) = std::make_tuple(b, a);
// 使用 std::tie 和 std::make_tuple 交换值
}
int main() {
int x = 5;
int y = 3;
std::cout << "Before swap: x = " << x << ", y = " << y << std::endl;
tupleSwap(x, y); // 交换 x 和 y 的值
std::cout << "After swap: x = " << x << ", y = " << y << std::endl;
return 0;
}
相比于swap
一次只能交换两个变量,使用元组可以进行多交换,例如
#include <iostream>
#include <tuple> // 包含 std::tuple 和 std::tie
void multipleSwap(int& a, int& b, int& c) {
std::tie(a, b, c) = std::make_tuple(c, a, b);
// 一次性交换三个变量
}
int main() {
int x = 1, y = 2, z = 3;
std::cout << "Before swap: x = " << x << ", y = " << y << ", z = " << z << std::endl;
multipleSwap(x, y, z); // 交换 x, y, z 的值
std::cout << "After swap: x = " << x << ", y = " << y << ", z = " << z << std::endl;
return 0;
}
运行结果:
Before swap: x = 1, y = 2, z = 3
After swap: x = 2, y = 3, z = 1
加减法
int a = 5, b = 10;
a = a + b; // a = 15 (5 + 10)
b = a - b; // b = 5 (15 - 10)
a = a - b; // a = 10 (15 - 5)
// 交换后 a = 10, b = 5
加减运算速度较位运算和swap
速度更慢,但也不失为一种方法。
乘除法
int a = 5, b = 10;
a = a * b; // a = 50 (5 * 10)
b = a / b; // b = 5 (50 / 10)
a = a / b; // a = 10 (50 / 5)
// 交换后 a = 10, b = 5
乘除相较于加减本来就没有优势,该方法还要乘除三遍,建议放在非会员的代码上,速度慢不适合运算,而且还要注意不能有0。