主頁 > 後端開發 > [Qt基礎內容-08] Qt中MVC的M(Model)

[Qt基礎內容-08] Qt中MVC的M(Model)

2022-09-08 08:51:20 後端開發

Qt中MVC的M(Model)簡單介紹

Qt有自己的MVC框架,分別是model(模型)、view(視圖)、delegate(委托),這篇文章,簡單的介紹以下Qt中有關model(模型)的類以及一些基本的使用,
Qt官方的檔案已經很詳細了,如果想要詳細的去了解,建議花點精力去看官方檔案,

@

目錄
  • Qt中MVC的M(Model)簡單介紹
    • 類繼承的結構
    • QStringListModel
    • QAbstractProxyModel
      • QSortFilterProxyModel
      • QTransposeProxyModel
      • QIdentityProxyModel
    • QSqlQueryModel
      • QSqlTableModel
    • QConcatenateTablesProxyModel
    • QDirModel、QFileSystemModel
    • QStandardItemModel
    • 自定義Model

類繼承的結構

Qt中的模型類,都繼承自QAbstractItemModel,這個類定義了基本的必須的介面,

由于QAbstractItemModel這種帶有abstract的類是抽象類,不建議直接使用,所以本文只介紹可直接使用的類的基本用法,

QStringListModel

根據Qt幫助檔案中的解釋,QStringListModel是一個可編輯的模型,可用于需要在視圖小部件(如QListView或QComboBox)中顯示許多字串的簡單情況,
下面是使用的代碼以及效果展示:

QStringListModel *m_listModel_2 = new QStringListModel;
QStringList list_2  = {"111", "222", "333", "444", "555"};
m_listModel_2->setStringList(list_2);

ui->listView->setModel(m_listModel_2);

展現的效果:
PluginForMyDemo_kYnZ78Hcsa.png

QAbstractProxyModel

??這里有一個Proxy(代理),這個要和Delegate(委托)區分開來,我的理解是,Proxy(代理)主要是應用在model上,用于對原資料進行處理,而Delegate(委托)主要是用來顯示和編輯資料,
??為什么要有這個代理呢?個人理解是,當Model關聯了幾個View時,如果你需要對某一個Model的資料進行排序,那如果不用代理,那么就意味著你原本的Model也會改變,那么所有的View都會改變,那么如果你僅僅只需要當前的view對這個資料進行改變,那么就需要用到代理,幫你把內容進行一個處理,然后發出來,


QSortFilterProxyModel

這個代理,提供了排序和過濾的介面,能夠方便的呼叫,給資料提供一個排序過濾的功能;
根據Qt官方幫助檔案對于QSortFilterProxyModel的介紹:

QSortFilterProxyModel can be used for sorting items, filtering out items, or both. The model transforms the structure of a source model by mapping the model indexes it supplies to new indexes, corresponding to different locations, for views to use. This approach allows a given source model to be restructured as far as views are concerned without requiring any transformations on the underlying data, and without duplicating the data in memory.


QSortFilterProxyModel 可用于排序專案、過濾專案或兩者兼而有之, 該模型通過將其提供的模型索引映射到新索引(對應于不同位置)來轉換源模型的結構,以供視圖使用, 這種方法允許就視圖而言對給定的源模型進行重構,而無需對基礎資料進行任何轉換,也無需復制記憶體中的資料,

以下是基本的用法:

  1. 排序

    QTableView* tableview = new QTableView();
    
    QStandardItemModel *model = new QStandardItemModel();
    model->setItem(0, 0, new QStandardItem("Aba"));
    model->setItem(1, 0, new QStandardItem("aba"));
    model->setItem(2, 0, new QStandardItem("ABc"));
    model->setItem(0, 1, new QStandardItem("C"));
    model->setItem(1, 1, new QStandardItem("A"));
    model->setItem(2, 1, new QStandardItem("c"));
    model->setItem(0, 2, new QStandardItem("c"));
    model->setItem(1, 2, new QStandardItem("b"));
    model->setItem(2, 2, new QStandardItem("C"));
    
    QSortFilterProxyModel* sortFilterModel = new QSortFilterProxyModel();
    // 為代理設定源model
    sortFilterModel->setSourceModel(listModel);
    // 設定大小寫敏感
    sortFilterModel->setSortCaseSensitivity();
    
    tableview->setModel(sortFilterModel);
    // 設定開啟點擊表頭進行排序
    tableview->setSortingEnable(true);
    

    ??需注意的是,當你使用QTableView或者QTreeView時,呼叫setSortingEnable并設定為true,就可以設定點擊表頭進行排序,
    image.png
    當然,你可以手動進行排序

    // 對第二列進行升序排序
    ui->tableview->sortByColumn(1, Qt::AscendingOrder);
    

    ??但是這樣排序有一個問題:表的序號沒有進行改變,暫時沒有找到方法來解決,有一個參考的解決方法可以看:QTableView自定義Model實作排序 ,同樣,如果你要自定義排序的規則的話,你可以繼承QSortFilterProxyModel類,然后重寫lessThan函式,重新寫一下里面的排序規則,可以參考Qt官方的例子Custom Sort/Filter Model

  2. 過濾

    過濾的規則你可以選擇

    • 正則運算式
    • 通配符模式
    • 固定字串


    ??在層級結構中,會遞回的去過濾其子節點,同時,當父節點被過濾時,子節點也不會被顯示,
    基本用法如下:

    QStringListModel *m_listModel_2 = new QStringListModel;
    QStringList list_2  = {"111", "222", "333", "444", "555", "a.jpg", "b.jpg"};
    
    QSortFilterProxyModel* listviewFilterModel = new QSortFilterProxyModel;
    // 設定源model
    listviewFilterModel->setSourceModel(m_listModel_2);
    m_listModel_2->setStringList(list_2);
    
    listviewFilterModel->setFilterRegExp(QRegExp(".jpg", Qt::CaseSensitive,
        								 QRegExp::FixedString));
    ui->listView->setModel(listviewFilterModel);
    

    image.png
    ??其他的用法,請參考Qt官方例子Custom Sort/Filter Model
    ??默認的情況下,在源model的資料發生改變時,會自動重新排序或者重新過濾資訊,想要控制這個特性,設定dynamicSortFilter這個屬性,

QTransposeProxyModel

這個類是一個用來行列交換的model,就是說如果源model中有一個索引index(0, 1),那么這個在代理model中就是index(1, 0),

QStandardItemModel *model = new QStandardItemModel();
model->setItem(0, 0, new QStandardItem("2022-9-4 21:11:08"));
model->setItem(1, 0, new QStandardItem("2022-9-5 17:21:08"));
model->setItem(2, 0, new QStandardItem("2022-9-1 13:03:12"));
model->setItem(0, 1, new QStandardItem("C"));
model->setItem(1, 1, new QStandardItem("A"));
model->setItem(2, 1, new QStandardItem("c"));
model->setItem(0, 2, new QStandardItem("c"));
model->setItem(1, 2, new QStandardItem("b"));
model->setItem(2, 2, new QStandardItem("C"));

QTransposeProxyModel* transposeModel = new QTransposeProxyModel;
// 設定源model
transposeModel->setSourceModel(model);
ui->tableView->setModel(transposeModel);

image.png

QIdentityProxyModel

根據官方的檔案:

QIdentityProxyModel can be used to forward the structure of a source model exactly, with no sorting, filtering or other transformation. This is similar in concept to an identity matrix where A.I = A.
Because it does no sorting or filtering, this class is most suitable to proxy models which transform the data() of the source model. For example, a proxy model could be created to define the font used, or the background colour, or the tooltip etc. This removes the need to implement all data handling in the same class that creates the structure of the model, and can also be used to create re-usable components.


QIdentityProxyModel可以用于準確地轉發源模型的結構,不需要排序、過濾或其他轉換,這在概念上類似于單位矩陣,其中A.I = A,
因為它不進行排序或過濾,所以這個類最適合于轉換源模型的data()的代理模型,例如,可以創建一個代理模型來定義所使用的字體、背景顏色或工具提示等,這樣就不需要在創建模型結構的同一個類中實作所有資料處理,并且還可以用于創建可重用的

??也就是說,這個model不會對源model進行任何轉換,只會簡簡單單的進行映射,主要是為了使用者可以通過重寫data()函式,來定制每一個元素所顯示的效果,同時這樣也不會污染源model的資料,方便進行重用,也對應這上面的,proxy(代理)的作用就是一個源model可以在許多個view里設定,且基本互不影響,
??以下代碼源自Qt官方檔案:

class DateFormatProxyModel : public QIdentityProxyModel
 {
   // ...

   void setDateFormatString(const QString &formatString)
   {
     m_formatString = formatString;
   }

   QVariant data(const QModelIndex &index, int role) const override
   {
     if (role != Qt::DisplayRole)
       return QIdentityProxyModel::data(index, role);

     const QDateTime dateTime = sourceModel()->data(SourceClass::DateRole).toDateTime();

     return dateTime.toString(m_formatString);
   }

 private:
   QString m_formatString;
 };

像上面這樣,多載model類的data函式,輸出定制化的日期格式,
??至于為什么要引入這樣一個類,我的理解是,你在進行繼承的時候,你需要找一個和你要實作的功能類似的父類來繼承,這樣的話就方便一點,但是如果你要實作的子類,功能和前面兩個代理類沒有關系,那么你繼承上面兩個類會進行一些多余的操作,這個時候引入一個只做映射的類,不對源model進行任何的改變,這樣定制化自己的代子類而不進行多余操作,

QSqlQueryModel

QSqlQueryModel提供了一個用于讀取資料庫資料的model,能夠為像QTableView這樣的view提供資料,
常用的函式有:

  1. void setQuery(const QSqlQuery &query)

    void setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase())
    這個函式是用來設定查詢的陳述句以及查詢的資料庫;

  2. QSqlRecord QSqlQueryModel::record(int row) const

    查詢指定第_row_行的資料;

  3. QSqlRecord QSqlQueryModel::record( ) const

    回傳一個空的QSqlRecord,但是里面包含了欄位的資訊;

  4. void fetchMore(const QModelIndex &parent = QModelIndex())

    從資料庫中取得更多的行數,這個只會對不回傳QuerySize的資料庫起作用,例如:oracle;可參看本人寫的博客:QTableView實作在表格內直接對資料庫內容進行修改、新增和洗掉等操作中,關于新增的部分,

其簡單的用法是(代碼源自Qt官方檔案):

QSqlQueryModel *model = new QSqlQueryModel;
// 設定資料庫查詢陳述句,這里如果不指定QSqlDatabase的話,就會使用默認的資料庫連接
model->setQuery("SELECT name, salary FROM employee");
// 設定表格的表頭
model->setHeaderData(0, Qt::Horizontal, tr("Name"));
model->setHeaderData(1, Qt::Horizontal, tr("Salary"));

QTableView *view = new QTableView;
// 為view設定model
view->setModel(model);
view->show();

此處有一個重要的點,那就是你需要自己設定QSqlQueryModel所要訪問的資料庫,根據不同的資料庫,創建不同的QSqlDatabase連接

// 以Sqlite為例
QSqlDatabase m_db;
// 添加QSqlDatabase
// 此處addDatabase函式不指定connectName,就會添加一個defaultConnection
// 上面的setQuery的就可以訪問到默認的資料庫連接了,
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName("D:/database.db");

if(!m_db.open())
{
    qDebug()<<"打開失敗";
    return;
}

同樣,也可以只用model查詢資料庫資料,而不與view系結中去,

QSqlQueryModel model;
model.setQuery("SELECT name, salary FROM employee");
// 獲取第四行資料中欄位salary的值
int salary = model.record(4).value("salary").toInt();

QSqlQueryModel是只讀的,如果想要可讀可寫的話,你可以使用QSqlTableModel

QSqlTableModel

QSqlTableModel繼承自QSqlQueryModel類,是可讀可寫的,
常用的函式:

  1. void setTable(const QString &tableName)

    ?設定需要查詢的資料庫表名為tableName,

  2. void setEditStrategy(QSqlTableModel::EditStrategy strategy)

    ?設定資料編輯的策略,主要有三種策略,分別是有任何改變就提交、行改變提交、手動提交,

  3. bool select()

    ?根據生成的sql陳述句來查詢,

  4. bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole)

    ?設定指定角色的水平標題的標題值,如果orientationQt::Horizontal,并且_section_指的是一個有效的section,則回傳true;否則回傳假;

  5. void setFilter(const QString &filter)

    ?設定過濾規則,filter的內容為,一個沒有where的關鍵字的where陳述句,比如:正常的陳述句"select * from table where name = 'ZhangSan' ",那么此時filter的內容就應該為" name = 'ZhangSan' "

  6. void setSort(int column, Qt::SortOrder order)

    ?設定指定列column排序,注意:呼叫這個函式設定新的排序之后,不會影響當前的資料,需要呼叫select函式來重繪資料,

  7. void revert()

    ?根據官方的檔案中的解釋,如果模型的策略設定為OnRowChangeOnFieldChange,則恢復更改,對OnManualSubmit策略不做任何操作,使用revertAll()恢復OnManualSubmit策略的所有掛起更改,或者使用revertRow()恢復特定行

  8. bool submit()

    ?如果模型的策略設定為OnRowChangeOnFieldChange,則提交當前編輯的行,對OnManualSubmit策略不做任何操作,使用submitAll()OnManualSubmit策略提交所有掛起的更改

最基本的用法:

// 創建/打開資料庫
QSqlDatabase db;

if (QSqlDatabase::contains("qt_sql_default_connection"))
{
    // 獲取默認的連接
    db = QSqlDatabase::database("qt_sql_default_connection");
}
else
{
    // 建立和SQlite資料庫的連接
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 設定資料庫檔案的名字
    db.setDatabaseName("Database.db");
}

if (db.open()) {
    // 創建表以及往表里插入資料
    QSqlQuery query;
    query.exec("create table person (Name varchar(20), Salary int)");
    query.exec("insert into person values('ZhangSan', 1)");
    query.exec("insert into person values('LiSi', 2)");
    query.exec("insert into person values('WangWu', 3)");
    query.exec("insert into person values('ZhaoLiu', 4)");
    query.exec("insert into person values('QianQi', 5)");
}

QSqlTableModel* tableModel = new QSqlTableModel();
// 設定表名
tableModel->setTable("person");
// 設定編輯策略,設定為需手動提交
tableModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
// 設定表頭資料
tableModel->setHeaderData(0, Qt::Horizontal, "Name");
tableModel->setHeaderData(1, Qt::Horizontal, "Salary");
// 查詢,必須要有,不然沒有資料顯示
tableModel->select();

ui->tableView->setModel(tableModel);

QTableView *view = new QTableView;
view->setModel(tableModel);
view->hideColumn(0); // don't show the ID
view->show();

image.png
通過setFilter函式來設定過濾規則,

tableModel->setFilter("name='ZhangSan' or name = 'WangWu'");

image.png
通過setSort函式來設定排序

tableModel->setSort(0, Qt::AscendingOrder);
tableModel->select();

image.png
其余的用法也可以參看之前寫的博客:QTableView實作在表格內直接對資料庫內容進行修改、新增和洗掉等操作

QConcatenateTablesProxyModel

?這個也是一個代理,其作用是可以聯立多個model,將資料放到一起顯示,顯示的列的數量為所有聯立的model中,列數量最小的model決定,
?簡單的用法為:

QStringList list;
list << "5" << "2" << "1" << "4" << "3";
QStringListModel* listModel = new QStringListModel();
listModel->setStringList(list);

QSqlDatabase db;

if (QSqlDatabase::contains("qt_sql_default_connection"))
{
    // 獲取默認的連接
    db = QSqlDatabase::database("qt_sql_default_connection");
}
else
{
    // 建立和SQlite資料庫的連接
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 設定資料庫檔案的名字
    db.setDatabaseName("Database.db");
}

if (db.open()) {
    // 創建表以及往表里插入資料
    QSqlQuery query;
    query.exec("create table person (Name varchar(20), Salary int)");
    query.exec("insert into person values('ZhangSan', 1)");
    query.exec("insert into person values('LiSi', 2)");
    query.exec("insert into person values('WangWu', 3)");
    query.exec("insert into person values('ZhaoLiu', 4)");
    query.exec("insert into person values('QianQi', 5)");
}

QSqlTableModel* tableModel = new QSqlTableModel();
tableModel->setTable("person");
tableModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
tableModel->setHeaderData(0, Qt::Horizontal, "Name");
tableModel->setHeaderData(1, Qt::Horizontal, "Salary");
tableModel->setSort(0, Qt::AscendingOrder);
tableModel->select();

QConcatenateTablesProxyModel* concatenateModel = new QConcatenateTablesProxyModel;
// 添加源model
concatenateModel->addSourceModel(listModel);
concatenateModel->addSourceModel(tableModel);

ui->tableView->setModel(concatenateModel);

image.png
從上面就可以看出,tableModel中原應該有的第二列,被忽略掉了,因為listModel只有1列,

QDirModel、QFileSystemModel

?根據Qt官方檔案中的描述,已經不建議用QDirModel,建議使用QFileSystemModel,由于兩個類很類似,所以本文只介紹QFileSystemModel,
?QFileSystemModel是一個用于訪問本地檔案系統的類,提供了一些基本的讀、寫檔案或目錄以及創建新的目錄的介面方便使用,常用的函式有:

  1. 獲取檔案的一些資訊

    函式原型 函式功能
    QIcon fileIcon(const QModelIndex &index) const 獲取指定檔案的圖示
    QFileInfo fileInfo(const QModelIndex &index) const 獲取指定檔案的資訊
    QString fileName(const QModelIndex &index) const 獲取指定檔案的名字
    QString filePath(const QModelIndex &index) const 獲取指定檔案的路徑
  2. 目錄操作

    函式原型 函式功能
    bool isDir(const QModelIndex &index) const 判斷指定檔案是否是目錄
    QModelIndex mkdir(const QModelIndex &parent, const QString &name) 在指定的目錄下,創建一個新的子目錄
    bool rmdir(const QModelIndex &index) 洗掉指定目錄

基本的用法:

QFileSystemModel* fileModel = new QFileSystemModel;
fileModel->setRootPath(QDir::currentPath());

ui->treeView->setModel(fileModel);
ui->treeView->setRootIndex(fileModel->index(QDir::currentPath()));

image.png

QStandardItemModel

根據Qt官方檔案的描述:

QStandardItemModel provides a classic item-based approach to working with the model. The items in a QStandardItemModel are provided by QStandardItem.


QStandardItemModel提供了一種經典的基于項的方法來處理模型,QStandardItemModel中的項由QStandardItem提供,

QStandardItemModel實作了QAbstractItemModel介面,這意味著該模型可以用于在任何支持該介面的視圖中提供資料(例如QListView, QTableView和QTreeView,以及您自己的自定義視圖),這是一個基于項的模型,像上面介紹的這些,基本都是特例化的一些子類,QStandardItemModel則可以自己創建一個整體的結構,Table、Tree或者List這些,都可以創建并填充資料,

When you want a list or tree, you typically create an empty QStandardItemModel and use appendRow() to add items to the model, and item() to access an item. If your model represents a table, you typically pass the dimensions of the table to the QStandardItemModel constructor and use setItem() to position items into the table. You can also use setRowCount() and setColumnCount() to alter the dimensions of the model. To insert items, use insertRow() or insertColumn(), and to remove items, use removeRow() or removeColumn().
You can set the header labels of your model with setHorizontalHeaderLabels() and setVerticalHeaderLabels().
You can search for items in the model with findItems(), and sort the model by calling sort().
Call clear() to remove all items from the model


當您需要串列或樹時,您通常創建一個空的QStandardItemModel,并使用appendRow()向模型添加項,并使用item()訪問項,如果您的模型表示一個表,您通常將表的維度傳遞給QStandardItemModel建構式,并使用setItem()將專案定位到表中,您還可以使用setRowCount()和setColumnCount()來更改模型的維度,要插入項,請使用insertRow()或insertColumn(),要洗掉項,請使用removeRow()或removeColumn(),您可以使用setHorizontalHeaderLabels()

以Table結構為例,簡單的用法:

QStandardItemModel* model = new QStandardItemModel(4, 4);
for (int row = 0; row < model->rowCount(); ++row) {
    for (int column = 0; column < model->columnCount(); ++column) {
        QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
        model->setItem(row, column, item);
    }
}
model->setHorizontalHeaderLabels({"Column 1", "Column 2", "Column 3", "Column 4"});
ui->tableView->setModel(model);

image.png

自定義Model

有時候會需要對model中的資料進行一種修改, 然后反饋到View上,這個時候,你就需要子類化一個model,然后重寫其data函式,來實作你想要的要求,

下面以Table的內容為例子:
mymodel.h

#ifndef MYMODEL_H
#define MYMODEL_H

#include <QStandardItemModel>

class MyModel : public QStandardItemModel
{
public:
    explicit MyModel();

protected:
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
};
#endif

mymodel.cpp

#include "mymodel.h"

MyModel::MyModel()
{

}

QVariant MyModel::data(const QModelIndex &index, int role) const
{
    // 背景色
    if (index.column() == 1 && role == Qt::BackgroundRole) {
        return QVariant(QColor(Qt::red));
    }

    // 前景色
    if (index.column() == 2 && role == Qt::ForegroundRole) {
        return QVariant(QColor(Qt::blue));
    }

    // 文字位置
    if (index.column() == 3 && role == Qt::TextAlignmentRole) {
        return QVariant(Qt::AlignBottom);
    }

    // 字體
    if (index.column() == 0 && role == Qt::FontRole) {
        return QVariant(QFont("MicroSoft YaHei", 18));
    }

    return QStandardItemModel::data(index, role);
}

使用代碼:

MyModel* model = new MyModel;
for (int row = 0; row < 4; ++row) {
    for (int column = 0; column < 4; ++column) {
        QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
        model->setItem(row, column, item);
    }
}
model->setHorizontalHeaderLabels({"Column 1", "Column 2", "Column 3", "Column 4"});
ui->tableView->setModel(model);

最終呈現的效果為:
image.png
可以根據不同的role,來做到定制化不同的效果,
image.png

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/505486.html

標籤:其他

上一篇:Qt5.14.2使用虛擬鍵盤

下一篇:OpenGL ES EAGLContext 和 EGLContext

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more