C++ 二分法查找文件中的某个数据

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
繁琐 !!
路过的大侠有想法,望不吝赐教!

猜你喜欢

转载自blog.csdn.net/qq_29567701/article/details/80257692
今日推荐