gpt4 book ai didi

c++ - 分割大量文本数据的算法

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:56:16 24 4
gpt4 key购买 nike

我有一个动态填充的文本区域(具体来说,我在 Qt 中有一个 QPlainTextEdit,但它对于算法建议并不重要)。

现在的问题是有时会出现大量数据,随着越来越多的数据进入我的应用程序变得很重,因为所有文本数据都在主内存中。

所以我想到了以下几点。我们可以使用一个文件来存储所有文本数据并动态地只显示有限数量的数据,但同时我必须通过创建在新行时触发的滚动事件来让用户误以为数据大小就是文件的大小来了。

这样的问题有没有标准的算法?

最佳答案

子类 QAbstractListModel 在那里实现缓存。读取单元格值时,您正在从缓存中获取数据并在缓存中不存在值时更新它。

调整 QTableView,通过改变委托(delegate)来实现所需的单元格可视化。请注意,您必须使用 QTableView,因为其他 QAbstractItemView 有损坏的元素回收,它们不能很好地处理非常大的模型(QTableView 不有这样的问题)。

有一段时间我自负地编写了大文件的十六进制查看器,并用 2GB 的文件大小对其进行了测试,它运行良好。

好的,我找到了我的旧代码,这可能是一个很好的例子:

#include <QAbstractTableModel>

class LargeFileCache;

class LageFileDataModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit LageFileDataModel(QObject *parent);

// QAbstractTableModel
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;

signals:

public slots:
void setFileName(const QString &fileName);

private:
LargeFileCache *cachedData;
};

// ----- cpp file -----
#include "lagefiledatamodel.h"
#include "largefilecache.h"
#include <QSize>

static const int kBytesPerRow = 16;

LageFileDataModel::LageFileDataModel(QObject *parent)
: QAbstractTableModel(parent)
{
cachedData = new LargeFileCache(this);
}

int LageFileDataModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return (cachedData->FileSize() + kBytesPerRow - 1)/kBytesPerRow;
}

int LageFileDataModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return kBytesPerRow;
}

QVariant LageFileDataModel::data(const QModelIndex &index, int role) const
{
if (index.parent().isValid())
return QVariant();
if (index.isValid()) {
if (role == Qt::DisplayRole) {
qint64 pos = index.row()*kBytesPerRow + index.column();
if (pos>=cachedData->FileSize())
return QString();
return QString("%1").arg((unsigned char)cachedData->geByte(pos), 2, 0x10, QChar('0'));
} else if (role == Qt::SizeHintRole) {
return QSize(30, 30);
}
}

return QVariant();
}

void LageFileDataModel::setFileName(const QString &fileName)
{
beginResetModel();
cachedData->SetFileName(fileName);
endResetModel();
}

这是一个缓存实现:

class LargeFileCache : public QObject
{
Q_OBJECT
public:
explicit LargeFileCache(QObject *parent = 0);

char geByte(qint64 pos);
qint64 FileSize() const;

signals:

public slots:
void SetFileName(const QString& filename);

private:
static const int kPageSize;

struct Page {
qint64 offset;
QByteArray data;
};

private:
int maxPageCount;
qint64 fileSize;

QFile file;
QQueue<Page> pages;
};

// ----- cpp file -----
#include "largefilecache.h"

const int LargeFileCache::kPageSize = 1024*4;

LargeFileCache::LargeFileCache(QObject *parent)
: QObject(parent)
, maxPageCount(1024)
, fileSize(0)
{

}

char LargeFileCache::geByte(qint64 pos)
{
// largefilecache
if (pos>=fileSize)
return 0;

for (int i=0, n=pages.size(); i<n; ++i) {
int k = pos - pages.at(i).offset;
if (k>=0 && k< pages.at(i).data.size()) {
pages.enqueue(pages.takeAt(i));
return pages.back().data.at(k);
}
}

Page newPage;
newPage.offset = (pos/kPageSize)*kPageSize;
file.seek(newPage.offset);
newPage.data = file.read(kPageSize);
pages.push_front(newPage);

while (pages.count()>maxPageCount)
pages.dequeue();

return newPage.data.at(pos - newPage.offset);
}

qint64 LargeFileCache::FileSize() const
{
return fileSize;
}

void LargeFileCache::SetFileName(const QString &filename)
{
file.close();
pages.clear();
file.setFileName(filename);
file.open(QFile::ReadOnly);
fileSize = file.size();
}

因为我处理的是行数据,所以我手动写了缓存,但是你可以使用QCache这应该可以帮助您执行缓存逻辑。

关于c++ - 分割大量文本数据的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43767260/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com