久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1076|回復: 9
收起左側

25Q32怎么跟二分法查找結合起來用?

[復制鏈接]
回帖獎勵 30 黑幣 回復本帖可獲得 3 黑幣獎勵! 每人限 1 次
ID:777254 發(fā)表于 2024-8-15 18:23 | 顯示全部樓層 |閱讀模式
1.25Q32中保留N條記錄,每條記錄包含時間加數(shù)據(jù),時間是順序保存的。(數(shù)據(jù)量很大,Mbyte級別,不能讀到RAM中操作)
2.上位機發(fā)送指定時間加次數(shù)M,要求上報指定時間后的M次記錄。

想到的是二分法查找,不知道怎么結合用?大佬們還有更好的方法嗎?
回復

使用道具 舉報

ID:309610 發(fā)表于 2024-8-16 10:34 | 顯示全部樓層
我提交GPT給的方案可以參考一下
你提到的需求是在一個大數(shù)據(jù)文件中查找指定時間后的N條記錄,由于數(shù)據(jù)量較大,無法將整個文件加載到內(nèi)存中,直接在磁盤上進行操作。二分法結合順序讀取是一個合理的解決方案,以下是具體步驟:1. 二分查找定位指定時間由于時間是按順序保存的,二分查找可以幫助我們快速定位到接近目標時間的記錄。讀取文件頭和尾部的記錄,通過它們的時間值計算中間位置(假設你可以通過文件指針直接跳到中間的位置)。二分查找:將中間位置的時間與目標時間進行比較。如果目標時間大于當前時間,繼續(xù)在后半部分查找;反之在前半部分查找。重復這個過程,直到找到目標時間或最接近目標時間的位置。2. 順序讀取N條記錄一旦找到了目標時間的位置,接下來需要順序讀取指定數(shù)量的記錄。將文件指針移到二分查找到的位置,順序讀取接下來的N條記錄。由于時間是順序排列的,所以直接讀取M次就可以獲得所需數(shù)據(jù)。

總結使用二分查找快速定位到目標時間的記錄。順序讀取目標時間之后的N條記錄。這種方法的優(yōu)勢在于只需要在磁盤上進行有限的讀取操作,避免了全量讀取數(shù)據(jù)到內(nèi)存中,可以有效處理大規(guī)模數(shù)據(jù)文件。

在STM32平臺上使用C語言進行二分查找并讀取指定時間后的記錄,結合存儲器25Q32,可以參考以下方案:1. 環(huán)境準備Flash類型: 25Q32是一種SPI Flash存儲器。你需要在STM32上配置SPI接口,確保可以通過SPI協(xié)議訪問25Q32存儲器。文件系統(tǒng)或裸操作: 如果數(shù)據(jù)是按照某種結構直接存儲在Flash中的,你可能需要裸操作Flash存儲器,即通過特定的SPI指令讀取數(shù)據(jù)。2. 數(shù)據(jù)組織假設每條記錄的格式如下:struct Record {
    uint32_t timestamp; // 時間戳,假設是4字節(jié)
    uint8_t data[DATA_LENGTH]; // 數(shù)據(jù)部分
};假設每條記錄長度固定為RECORD_SIZE。3. 二分查找算法實現(xiàn)為了從大文件中高效找到指定時間點后的數(shù)據(jù),可以通過二分查找確定目標時間的起始位置。以下是步驟:3.1 計算記錄總數(shù)你可以通過Flash的總容量除以每條記錄的大小來計算出記錄總數(shù)。#define FLASH_SIZE (4 * 1024 * 1024)  // 25Q32容量 4MB
#define RECORD_SIZE sizeof(struct Record)

uint32_t total_records = FLASH_SIZE / RECORD_SIZE;3.2 實現(xiàn)二分查找二分查找用于找到指定時間戳的位置。uint32_t binary_search(uint32_t target_time) {
    uint32_t low = 0;
    uint32_t high = total_records - 1;
   
    while (low <= high) {
        uint32_t mid = (low + high) / 2;
        struct Record record;
        read_record(mid, &record); // 從flash讀取第mid條記錄
        
        if (record.timestamp < target_time) {
            low = mid + 1;
        } else if (record.timestamp > target_time) {
            high = mid - 1;
        } else {
            return mid; // 找到精確時間
        }
    }
   
    return low; // 沒有精確匹配,返回最接近的記錄位置
}3.3 從指定位置讀取M條記錄找到目標位置后,可以順序讀取接下來的M條記錄。void read_next_n_records(uint32_t start_index, uint32_t n) {
    for (uint32_t i = 0; i < n; ++i) {
        struct Record record;
        read_record(start_index + i, &record); // 讀取并處理記錄
        // process_record(&record);
    }
}4. SPI Flash讀操作實現(xiàn)在STM32上實現(xiàn)SPI讀取25Q32 Flash中的數(shù)據(jù),需要使用STM32的HAL庫或直接操作寄存器。4.1 SPI Flash讀記錄的實現(xiàn)void read_record(uint32_t index, struct Record *record) {
    uint32_t address = index * RECORD_SIZE;
   
    // 使用SPI讀取數(shù)據(jù)
    uint8_t cmd[4];
    cmd[0] = READ_COMMAND;           // 讀取命令(通常為0x03)
    cmd[1] = (address >> 16) & 0xFF; // 地址高字節(jié)
    cmd[2] = (address >> 8) & 0xFF;  // 地址中字節(jié)
    cmd[3] = address & 0xFF;         // 地址低字節(jié)
   
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); // 拉低片選(CS)
    HAL_SPI_Transmit(&hspi1, cmd, 4, HAL_MAX_DELAY);       // 發(fā)送讀命令和地址
    HAL_SPI_Receive(&hspi1, (uint8_t*)record, RECORD_SIZE, HAL_MAX_DELAY); // 讀取數(shù)據(jù)
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);   // 拉高片選(CS)
}5. 總結使用二分查找算法在SPI Flash中查找指定時間戳的位置。從該位置開始順序讀取指定數(shù)量的記錄。在STM32上通過SPI接口實現(xiàn)對25Q32的讀操作。這個方案在STM32平臺上效率較高,能夠處理大規(guī)模數(shù)據(jù)存儲器中的查找和讀取操作。
回復

使用道具 舉報

ID:910662 發(fā)表于 2024-8-16 11:07 | 顯示全部樓層
如果時間是均勻的,計算即可;如果是隨機的,除了二分法,還有黃金分割法更優(yōu),你不妨試試。不過Mbyte也不是很大,二分法也不錯。
回復

使用道具 舉報

ID:777254 發(fā)表于 2024-8-16 11:53 | 顯示全部樓層
dhjmw 發(fā)表于 2024-8-16 11:07
如果時間是均勻的,計算即可;如果是隨機的,除了二分法,還有黃金分割法更優(yōu),你不妨試試。不過Mbyte也不 ...

時間不是規(guī)律增加的,因為外部可以設置這個時間間隔,間隔在1-99內(nèi)。
回復

使用道具 舉報

ID:844772 發(fā)表于 2024-8-19 15:12 | 顯示全部樓層
1、我覺得二分法就不錯的;
2、但更建議使用插值法,因為雖然時間間隔可調但估計不會頻繁調整所以時間隨機性不那么大適合插值法;
3、前邊提的黃金分割法是不是需要構建斐波那契數(shù)列啊,這在單片機上需要消耗不少內(nèi)存啊;
4、如果插值法不能滿足要求,還可以試試先用分塊法粗篩,再用插值法。
回復

使用道具 舉報

ID:777254 發(fā)表于 2024-8-19 20:36 | 顯示全部樓層
glinfei 發(fā)表于 2024-8-19 15:12
1、我覺得二分法就不錯的;
2、但更建議使用插值法,因為雖然時間間隔可調但估計不會頻繁調整所以時間隨機 ...

目前遇到個難題,就是在FLASH空間內(nèi),如果存儲到盡頭,會從起始地址開始覆蓋回滾覆蓋存,這樣就會出現(xiàn)整個存儲空間,地址從小到大的數(shù)據(jù),其記錄的時間并不是按先后順序的,總不能把所有記錄數(shù)據(jù)讀出來排序吧
回復

使用道具 舉報

ID:1034262 發(fā)表于 2024-8-20 15:42 | 顯示全部樓層
二分法用于間隔恒定的單調參數(shù)有效,時間順序雖然單調,但是間隔不恒定,效果欠佳,但還是可以用。
更好的辦法是時間和數(shù)據(jù)分開存放(類似電腦文件系統(tǒng)的目錄項、鏈表、數(shù)據(jù)),特別是數(shù)據(jù)比較大時特別有效,讀出時間查找,然后讀出對應的數(shù)據(jù)、
回復

使用道具 舉報

ID:844772 發(fā)表于 2024-8-21 08:56 | 顯示全部樓層
li1069136863 發(fā)表于 2024-8-19 20:36
目前遇到個難題,就是在FLASH空間內(nèi),如果存儲到盡頭,會從起始地址開始覆蓋回滾覆蓋存,這樣就會出現(xiàn)整 ...

運行一段時間,必然一直按你說的這種情況存儲,可以理解順序是 CDAB ,A<B<C<D,而且C=B+1;如果沒有做數(shù)據(jù)索引,那就先看在AB段還是在CD段 即(X>C還是X<B),然后再二分法去找,當然分后的新中點要先對分段,比如X在AB段,二分后的新點E如果大于B,那就丟棄再找。這里有很多可以優(yōu)化的地方,比如利用一次是刪除多少等條件,迅速發(fā)現(xiàn)DA點,及其X是否在記錄中;或者刪除舊數(shù)據(jù)時直接記錄一下,可以省不少時間。
回復

使用道具 舉報

ID:777254 發(fā)表于 2024-8-21 14:19 | 顯示全部樓層
glinfei 發(fā)表于 2024-8-21 08:56
運行一段時間,必然一直按你說的這種情況存儲,可以理解順序是 CDAB ,A

是做了索引,索引保存的是記錄的總次數(shù),還有最新的一條記錄跟基地址的偏移量,主要是這兩個變量。我先按照你的思路捋一下
回復

使用道具 舉報

ID:844772 發(fā)表于 2024-8-21 15:51 | 顯示全部樓層
li1069136863 發(fā)表于 2024-8-21 14:19
是做了索引,索引保存的是記錄的總次數(shù),還有最新的一條記錄跟基地址的偏移量,主要是這兩個變量。我先按 ...

那就相當于分兩個塊,分別搜索啊,但有個問題,查找A的偏移要注意,因為刪除是按頁面刪的,所以會有空白區(qū),可以理解DA之間有空白區(qū),
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久免费精彩视频 | 午夜欧美| 亚洲精品一区二区网址 | 91一区二区| 日韩成人免费视频 | 久久久免费电影 | 国产在线播 | 免费看国产精品视频 | 一区二区三区欧美大片 | 黄色成人亚洲 | 日本五月婷婷 | 国产精品免费视频一区 | 国产一级淫片a直接免费看 免费a网站 | 成人国产精品视频 | 欧美久久一级特黄毛片 | 干狠狠 | 一区二区三区精品视频 | 成人性生交大免费 | 国产在线观看一区 | 国产韩国精品一区二区三区 | 日韩高清av | 成年人在线观看视频 | 精品国偷自产在线 | 国产免费播放视频 | 国产伦精品一区二区三区高清 | 黄色一级片在线播放 | 欧美色999| 精品欧美一区二区精品久久久 | 正在播放国产精品 | 在线观看中文字幕一区二区 | 一区二区手机在线 | 国产高清不卡 | 国产成人啪免费观看软件 | 日韩蜜桃视频 | 精品久久久久久久久久久久久久 | 国产成人免费视频网站视频社区 | 国产精品免费大片 | 久久一区二区三区四区五区 | 夜夜干夜夜操 | 97伦理电影| 国产精品一区在线 |