我正在学习C ++并正在使用搜索/排序算法。
我正在尝试对未排序的项目列表执行二进制搜索并返回原始数组索引。我必须先对它进行排序,所以为了保留原始索引,我创建了一个2D数组,将数据放在第一列中,将原始索引放在第二列中。 (我把它减少了一点,这就是为什么我必须把//插入数据项。)
template <class TYPE>
int SomeClass<TYPE>::find(TYPE data)
{
TYPE(*ary)[2] = new TYPE[size()][2];
for (int i = 0; i < size(); i++)
{
ary[i][0] = //insert data items here;
ary[i][1] = i;
}
//reading the data items and indexes into the new 2D array works
someSort(ary, size());
return bsearch(ary, 0, size()-1, data);
}
假设您有一些排序算法。作为一个例子,我只是在下面添加冒泡,因为它没有占用太多空间来编写。
template <class DT>
void SomeClass<TYPE>::someSort(TYPE A[][2], int n)
{
int i, j;
for (i = 0; i < n- 1; i++)
{
for (j = 0; j < n- i - 1; j++)
{
if (A[j] > A[j + 1])
swap(&A[j][0], &A[j + 1][0]);
}
}
}
好吧,我的问题是你如何修改2D数组的二进制搜索并返回原始值(位于数组的第二个插槽中)? (如果有问题,请随意修改我的排序示例。)
template <class TYPE>
int SomeClass<TYPE>::bsearch(TYPE A[][2], int left, int right, TYPE data)
{
while (right>= left)
{
int mid = left + (right+ left) / 2;
if (A[mid][0] == data)
return A[mid][1];
if (A[mid][0] > data)
right= mid- 1;
else
left= mid+ 1;
}
return -1;
}
答案 0 :(得分:0)
您需要检查二进制搜索实现,因为它不正确。这是改进版本:
template <class TYPE>
int SomeClass<TYPE>::bsearch(TYPE A[][2], int left, int right, TYPE data)
{
while (right>= left)
{
int mid = left + (right - left) / 2; // <== corrected here.
if (A[mid][0] == data)
return A[mid][1];
if (A[mid][0] > data)
right= mid- 1;
else
left= mid+ 1;
}
return -1;
}
虽然学习手动编码算法更好,但你应该知道C ++提供了二进制搜索或快速/合并排序等常用算法的实现。
例如,您可以定义保存原始数组中值和位置的值对struct vp
:
struct vp
{
TYPE val;
int pos;
bool operator<(const vp& vp) const {
return val < vp.val;
}
static bool cmp(TYPE b, const vp& a) {
return b < a.val;
}
};
然后您可以使用std::sort对值对进行排序:
vp *arr = ...
std::sort(arr, arr+size());
然后,您可以使用lower_bound或upper_bound在价值对数组中进行二元搜索:
auto p = std::upper_bound(arr, arr+size(), data, vp::cmp);
但是你需要解释正确的返回值,以确定是否在数组中找到了值。