1:题目:
(1):二分法查找文件中的某个数据。存在:返回行数,不存在,返回-1。
(2):文件中的数据存放要求:
文件中存放的是递增的整数,且每行一个数。
如:
info.txt
2
6
16
28
49
50
56
85
88
90
99
100
256
(3)输入输出要求
输入:文件名fname、待查找的整数key
输出:存在:返回行数,不存在,返回-1
2、思路
直接用二分法进行操作。
不额外申请多余的内存,复制文件中所有的数据。
直接用文件指针操作到对应位置,用对应位置的值,进行比较操作。
如:想要取到文件中间的值:
in.seekg(0, 2);//将文件指针定位到文件末尾,以便获取文件的行数
int len = in.tellg() / sizeof(int);//len:文件的行数
int mid = len / 2;
//--------获取 文件中间位置 mid 的数据 begin-------
char *buffer;
int SIZE = sizeof(int);//由于文件中所有数据都是int型的整数,所以每取一个数的大小都是 sizeof(int)
buffer = new char[SIZE];
in.seekg(sizeof(int)*mid); //将文件指针定位到 文件中间mid的位置
in.read(buffer, SIZE); //将mid位置的数据存入char* 中
string str = buffer; //将 char* 转换为 string
delete[] buffer;
int mid_value = atoi(str.c_str()); //将 string 转换为 int
//--------获取 文件中间位置 mid 的数据 end-------
自己想的,不太好,
获取到特定位置的值之后,需要进行两次数据格式的转换,
(1)将 char* 转换为 string
(2)将 string 转换为 int
繁琐 !! !!
有好方法的,冒个泡吧。。
3、代码:
int BinarySearchValueInFile(char *fname, int key)
{
ifstream in(fname);
if (!in){ cout << "No such a file ." << endl; return -1; }
in.seekg(0, 2);//将文件指针定位到文件末尾,以便获取文件的行数
int len = in.tellg() / sizeof(int);//len:文件的行数
//---------------------二分法 begin---------------------
int low = 1;
int high = len;
int mid = (low + high) / 2;
while (low <= high)
{
mid = (low + high) / 2;
//--------获取 文件中间位置 mid 的数据 begin-------
char *buffer;
int SIZE = sizeof(int);//由于文件中所有数据都是int型的整数,所以每取一个数的大小都是 sizeof(int)
buffer = new char[SIZE];
in.seekg(sizeof(int)*mid); //将文件指针定位到 文件中间mid的位置
in.read(buffer, SIZE); //将mid位置的数据存入char* 中
string str = buffer; //将 char* 转换为 string
delete[] buffer;
int mid_value = atoi(str.c_str()); //将 string 转换为 int
//--------获取 文件中间位置 mid 的数据 end-------
if (key == mid_value)return mid + 1; //不知道为什么,第0、1、最后一个 数据总是检索不到
else if (key > mid_value) low = mid + 1;
else high = mid - 1;
}
//---------------------二分法 end---------------------
in.close();
return -1;
}
检测代码:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
void test()
{
char fname[40] = "info.txt";
int a[] = { 2, 6, 16, 28, 49, 50, 56, 85, 88, 90, 99, 100, 256 };
for (auto c : a)
cout << c << " row: " << BinarySearchValueInFile(fname, c) << endl;
cout << endl;
}
int main()
{
test();
return 0;
}
3、不足之处
1、最开始的两个数据 和 最后一个数据 总是查找不出来。
2、获取到特定位置的值之后,需要进行两次数据格式的转换,
(1)将 char* 转换为 string
(2)将 string 转换为 int
繁琐 !!
路过的大侠有想法,望不吝赐教!