我要创建一个检查.bin文件中是否存在特定单词的函数。我想使用二进制搜索算法。事情是,我从.bin文件中读取,所以我感到困惑(因为没有线路,对吧?)。功能对我不起作用。它说'具体的词' (由用户输入)不存在,即使它确实存在。 任何帮助都会很好。
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include <algorithm>
using namespace std;
const int buffer_size = 30;
void Create_Bin_File ()
{
ifstream fin ("example.txt");
ofstream fout ("Binary.bin", ios::binary);
const unsigned int RECORD_SIZE = 30; // was BUFFER_SIZE
char buffer[RECORD_SIZE] = {0}; // zero init buffer
while (fin.getline (buffer, RECORD_SIZE))
{
fout.write (buffer, RECORD_SIZE);
// refill buffer with zeroes for next time round
fill_n (buffer, RECORD_SIZE, 0);
}
fin.close ();
fout.close ();
}
void Binary_Search (const string& filename, string SearchVal)
{
ifstream file (filename.c_str(), ios::binary);
if (file.is_open())
{
cout << "The file is opened"<< endl;
cout << "\n";
}
else
{
cout << "Error opening file"<< endl;
cout << "\n";
return; // no point continuing Binary_Search() if file failed to open!
}
const unsigned int RECORD_SIZE = 30; // was BUFFER_SIZE
char buffer[RECORD_SIZE] = {0}; // zero init buffer
int recordCount = 0;
int recordWanted = -1;
while (file.read(buffer, RECORD_SIZE))
{
if(SearchVal == buffer)
{
recordWanted = recordCount;
// if this was just a naive search loop could bail out now...
}
cout << recordCount << " : " << buffer << "\n";
// refill buffer with zeroes for next time round
fill_n (buffer, RECORD_SIZE, 0);
++recordCount;
}
cout << "\n";
cout << "file contains " << recordCount << " records\n";
cout << "\n";
if (recordWanted == -1)
cout << "record wanted could not be found\n";
else
cout << "record wanted is at index " << recordWanted << " records\n";
cout << "\n";
}
int main()
{
Create_Bin_File();
string word;
cout << "Enter word, that you want to find in a file: " << endl;
cin >> word;
Binary_Search("Binary.bin", word);
return 0;
}
TASK: &#34;用C ++编写程序。如果程序使用文件,则不应将文件的整个内容复制到操作内存中。文件组件表示固定长度记录。 H7。编写一个程序,将所有标准C ++保留字放在一个有序表中(据我所知,有序表意味着这些单词按字母顺序排列)。编写一个函数,使用二进制搜索检查输入字符串(长度为30)是否为C ++保留字。表应该作为直接访问文件。 C ++保留程序应该从文本文件中读取。&#34;
关于BinarySearch函数的grek40解决方案:
所以我创建了记录功能:
std::string GetRecord(std::ifstream& inFile, int pos)
{
char buffer[RECORD_SIZE];
// clear possible flags like EOF, before moving the read position
inFile.clear();
// set the file read position to the requested record position
inFile.seekg(pos * RECORD_SIZE, std::ios::beg);
inFile.read(buffer, RECORD_SIZE);
// note: automatic conversion from char[] to std::string
return buffer;
}
二进制搜索功能:(已解决 - 工作!)
void Binary_Search (const string& filename, string SearchVal)
{
ifstream file (filename.c_str(), ios::binary);
if (file.is_open())
{
cout << "The file is opened"<< endl;
cout << "\n";
}
else
{
cout << "Error opening file"<< endl;
cout << "\n";
return; // no point continuing Binary_Search() if file failed to open!
}
int pos = 0;
int lowerLimit = 0;
int recordCount = 73; // Calculated before[I'll change this part, when I get this function working]
// At this point, there's exactly 73 records in .bin file
char buffer[RECORD_SIZE] = {0}; // zero init buffer (while loop will overwrite with record values)
int upperLimit = recordCount;
while ( (lowerLimit < upperLimit) ) // Searching as long as it doesn't find it
{
pos = (lowerLimit + upperLimit) / 2;
std::string buffer = GetRecord(file, pos);
if (buffer == SearchVal)
{
cout << "Found!";
lowerLimit = 1; // For stopping (If found!)
upperLimit = 0; // For stopping
}
else if (SearchVal > buffer)
{
lowerLimit = pos + 1;
}
else if (SearchVal < buffer)
{
upperLimit = pos;
}
}
}
答案 0 :(得分:1)
据我所知,你有一个解决方案,你可以将所有给定的单词从文本文件移动到二进制文件,如果它们存在,你可以在二进制文件中找到单词。
我想你创建了二进制文件,其长度等于(30),每条记录的文本部分都是零终止的。
现在,让我们创建一个函数,该函数接受打开的二进制文件流和记录位置,并返回该记录位置的字符串:
for (i = 0; i < buf.length; i++) {
const byte = buf[i];
const hexChar = byte.toString(16); // convert the decimal `byte` to hex string;
// do something with hexChar, e.g. console.log(hexChar);
}
对于二进制搜索,您应该为搜索位置定义上限和下限。请注意,上限为std::string GetRecord(std::ifstream& inFile, int pos)
{
char buffer[RECORD_SIZE];
// clear possible flags like EOF, before moving the read position
inFile.clear();
// set the file read position to the requested record position
inFile.seekg(pos * RECORD_SIZE, std::ios::beg);
inFile.read(buffer, RECORD_SIZE);
// note: automatic conversion from char[] to std::string
return buffer;
}
,因此您永远不会在基于零的索引中实际访问此位置。
lastItemPosition + 1
只要您找不到结果并int lowerLimit = 0;
int upperLimit = recordCount; // count when reading the lines in .txt
,就需要搜索结果。
您的下一个搜索字词位于lowerLimit < upperLimit
。
将该字词与搜索文字进行比较。在平等方面,你已经完成了。
如果单词小于搜索文本,则结果位置可以是高指数,而不是您刚刚查看的指数。因此,您需要调整position = (lowerLimit + upperLimit) / 2;
如果单词大于搜索文本,则结果位置可以是较低索引,而不是您刚刚查看的位置。 lowerLimit = position + 1
如上所述,您可以使用调整后的上限和下限重复搜索。