C++ ---- 二分查找一维数组,二维数组。

1,二分查找

条件:
1)数据是按从小到大或者是从大到小排序的
2)给定一组数据,在所给的排序数据中找出与数据相等的值,并返回它的下标
在这里插入图片描述

2,二维数组二分查找

在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
第一种解法:每一行用二分法查找,遍历所有行
在这里插入图片描述
第二种解法:利用从左到右,从上到下的规律,选择左下角或右上角,当值小时会比一列都小,当值大时会比一行都大。
在这里插入图片描述

看代码运行速度一下从48ms提升到24ms

解析
1. Lambda
首先先说一下这个语法

static const auto io_sync_off = {
… …
}();
这个乍一看很像是函数,但是前后又是[]又是()的,还没函数名没返回值的,感觉又不太像,所以就去请教了一下别人,得到答案是Lambda捕获。

Lambda表达式是C++11引入的特性,是一种描述函数对象的机制,它的主要应用是描述某些具有简单行为的函数。Lambda也可以称为匿名函数。

static const auto function() {
… …
}
static const auto io_sync_off = function();

2.std::ios::sync_with_stdio(false);
函数std :: ios_base :: sync_with_stdio的解释是

Sets whether the standard C++ streams are synchronized to the standard C streams after each input/output operation.
设置在每次输入/输出操作后标准C ++流是否与标准C流同步

随后又看到了一段关于std :: cin的解释

The global objects std::cin and std::wcin control input from a stream buffer of implementation-defined type (derived from std::streambuf), associated with the standard C input stream stdin.

These objects are guaranteed to be constructed before the first constructor of a static object is called and they are guaranteed to outlive the last destructor of a static object, so that it is always possible to read from std::cin in user code.

Unless sync_with_stdio(false) has been issued, it is safe to concurrently access these objects from multiple threads for both formatted and unformatted input.

Once std::cin is constructed, std::cin.tie() returns &std::cout, and likewise, std::wcin.tie() returns &std::wcout. This means that any formatted input operation on std::cin forces a call to std::cout.flush() if any characters are pending for output.

现在大概明白了一些,因为C++中的std :: cin和std :: cout为了兼容C,保证在代码中同时出现std :: cin和scanf或std :: cout和printf时输出不发生混乱,所以C++用一个流缓冲区来同步C的标准流。通过std :: ios_base :: sync_with_stdio函数可以解除这种同步,让std :: cin和std :: cout不再经过缓冲区,自然就节省了许多时间。

3. std::cin.tie(nullptr);
函数std :: ios :: tie的解释是

Get/set tied stream
The first form (1) returns a pointer to the tied output stream.

The second form (2) ties the object to tiestr and returns a pointer to the stream tied before the call, if any.

The tied stream is an output stream object which is flushed before each i/o operation in this stream object.

C++11
By default, the standard narrow streams cin and cerr are tied to cout, and their wide character counterparts (wcin and wcerr) to wcout. Library implementations may also tie clog and wclog.

这个现在看起来就比较容易理解了,因为std :: cin默认是与std :: cout绑定的,所以每次操作的时候(也就是调用”<<”或者”>>”)都要刷新(调用flush),这样增加了IO的负担,通过tie(nullptr)来解除std :: cin和std :: cout之间的绑定,来降低IO的负担使效率提升。

注意
使用std::ios::sync_with_stdio(false)和std::cin.tie(nullptr)之后要避免和scanf和printf混用以避免出现问题。

C++中,二分查找通常用于一维有序数组,但对于二维数组,由于它是矩阵形式的数据结构,我们一般不会直接应用二分查找。因为二分查找依赖于元素的线性排列,而二维数组的索引通常是行优先(i, j)或列优先(j, i)。不过,如果你有一个预处理好的二维有序数组,并且想要查找特定值对应的位置,可以将其视为一维化后进行操作。 以下是一个简单的例子,假设我们要在一维化后的二维数组上进行二分查找: ```cpp #include <vector> #include <iostream> // 二维数组转换为一维 std::pair<int, int> flatten(const std::vector<std::vector<int>>& matrix, int value) { std::vector<int> flat; for (const auto& row : matrix) { for (int elem : row) { if (elem == value) { // 记录下元素所在的原始位置 return {flat.size(), row.size() - 1}; } flat.push_back(elem); } } // 如果没找到,返回{-1, -1} return {-1, -1}; } // 二分查找辅助函数 bool binarySearch(int* arr, int left, int right, int target) { while (left <= right) { int mid = left + (right - left) / 2; if (arr[mid] == target) return true; else if (arr[mid] < target) left = mid + 1; else right = mid - 1; } return false; } // 使用上述函数进行查找 int main() { std::vector<std::vector<int>> matrix = {{1, 3, 5}, {7, 9, 11}, {13, 15, 17}}; int value = 9; std::pair<int, int> result = flatten(matrix, value); if (result.first != -1) { std::cout << "找到了元素,它在原数组中的位置是(" << result.first << ", " << result.second << ")\n"; int row = result.first; int col = result.second; bool found = binarySearch(matrix[row].data(), 0, col, value); // 注意数据类型匹配 if (found) { std::cout << "并且在一维化后的数组中位于索引" << binarySearchResult << "\n"; } else { std::cout << "但在一维化后的数组中未找到\n"; } } else { std::cout << "元素不在数组中\n"; } return 0; } ``` 在这个例子中,`flatten` 函数将二维数组转换为一维,然后 `binarySearch` 用于在一个已排序的一维数组中查找目标值。注意,在二维数组的每个子数组中查找时,需要处理指针和索引的问题,例如 `matrix[row].data()` 用于获取子数组的首地址。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值