SCU4439 二分+枚举进制+思维

本文探讨了一种通过枚举进位位置解决特定数学问题的方法,并实现了一个C++程序来计算给定整数集合中满足特定条件的进位次数。讨论了如何利用排序和二分搜索来优化算法效率。

 

自己比赛的时候也想了sort一下, 然后二分,但是还是没有想到枚举进位。。

 

这个题考虑进位的位置即可, 首先枚举进位是因为达到了10, 100, 1000..., 1e9

我还在考虑如果只按照各位排序的话,能不能推广到按10位,,100位排序, 想写个这样的sort函数,,,但其实用%100,%1000,然后创一个新的数组就可以了。。。

自己还是这些地方不好。。。

 

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<stack>
#include<cmath>
#include<map>
#include<vector>
#define ll long long
#define inf 0x3f3f3f3f
#define INF 1000000000
#define bug1 cout<<"bug1"<<endl;
#define bug2 cout<<"bug2"<<endl;
#define bug3 cout<<"bug3"<<endl;
using namespace std;
const int maxn=1e5+5;
int a[maxn],b[maxn];


int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;++i)scanf("%d",&a[i]);
        int k=1;
        ll ans=0;
        for(int i=1;i<=9;++i){
            k*=10;
            for(int i=1;i<=n;++i)b[i]=a[i]%k;
            sort(b+1,b+1+n);
            for(int j=1;j<=n;++j){
                int l=j+1,r=n+1;//这个r要是n+1...,还不知道这是不是  左闭右开的意思。。
                while(l<r){//要用自己写的二分,如果用lower——bound 的话会
                    int mid=(l+r)>>1;
                    if(b[mid]+b[j]>=k)
                        r=mid;
                    else l=mid+1;
                }
                //ans+=n-(lower_bound(b+1,b+1+n,k-b[j])-b);//这是用lower——bound的二分,会错。。可能是因为
                ans+=n-l+1;
            }
        }
        cout<<ans<<endl;
    }


}


 

** • @file XRayControl.h • • @brief 射线源封装 • • • 射线源封装 • • • @author jyh • • @version 1.0.0 • • @date 2023年12月14日 • • @note 新建 / #ifndef XRAYCONTROL_H #define XRAYCONTROL_H #include #include #include <QtSerialPort/QSerialPort> // 提供访问串口的功能 #include “SerialPortHelp\HamamatsuHelp.h” #include “WebSocket\CometCubeHelper.h” namespace drive { class XRayControl : public QObject { Q_OBJECT public: XRayControl(QObject parent = Q_NULLPTR); ~XRayControl(); bool Init(); bool UnInit(); void SetXRayRst(); void SetSyncWarmUp(); void SetWarmUp(); int SetXRaySwitch(bool bIsOpen); int SetXRayElectricParams(int nVol, int nCur); XRayMonitorStatus GetAutoXRaySts(); XRayMonitorStatus GetXRayStatus(); int GetXRayUseTime(); bool SyncXRayClose(int nTime = XRAY_SYNC_WAIT); bool SyncXRayOpen(int nVol, int nCur, int nTime = 40); bool AutoMotionReady(); XRayMonitorMap GetXRayMonitorMap(); int GetOutputVoltage() const { return m_nOutVol; } int GetOutputCurrent()const { return m_nOutCur; } private: SerialPortBase m_pXRayHelp; //射线源串口类 QThread m_pXRayThread; //射线源子线程 XRayMonitorMap m_XRayStatusMap; //监听数据信息 //XRayType m_XRayType; //射线源类型 XRayMonitorStatus m_XRayStatus; //射线源状态 XRaySettingParams m_stXRaySettingParams; //射线源串口设置参数结构体 int m_nOutVol; //输出电压 int m_nOutCur; //输出电流 int m_nUseTime; /!< 射线源使用时间 >/ void GetMonitorParams(); signals: void SigXRayRst(); void SigXRayWarmUp(); void SigRevFrameData(const QString& str, bool nResult); void SigUpdateXRayStatus(XRayMonitorStatus status, int nVol, int nCur); void SigUpdateXRayUseTime(int nUseTime); void SigUnInit(); void SigSetXRayElectricParams(int nVol, int nCur); void SigSetXRaySwitch(bool bStatus); public slots : void OnXRayStatusChanged(QMap<SerialPortCommand, int> qMapStatus); }; } #endif #include “XRayControl.h” #include “common\PiercingEyeSetting.h” • #include using namespace drive; const int g_SerialFailedTimes = 3; //串口发送重试次数 drive::XRayControl::XRayControl(QObject * parent) :QObject(parent) , m_pXRayHelp(NULL) , m_nOutVol(0) , m_nOutCur(0) , m_nUseTime(0) { } drive::XRayControl::~XRayControl() { delete m_pXRayThread; m_pXRayThread = nullptr; } bool drive::XRayControl::Init() { m_stXRaySettingParams = common::PiercingEyeSetting::GetInstall().GetXRayPortParams(); switch (m_stXRaySettingParams.eXRayType) { case Hamamatsu_L10941_05: if (NULL == m_pXRayHelp) { m_pXRayHelp = new drive::HamamatsuHelp(); } break; case Hamamatsu_L9181_05: break; case Comet_Cube: if (NULL == m_pXRayHelp) { m_pXRayHelp = new drive::CometCubeHelper(); } break; default: break; } for (int i = XRMT_STS; i < XRMT_NUMS; i++) { m_XRayStatusMap[i] = 0; } m_pXRayThread = new QThread; m_pXRayHelp->moveToThread(m_pXRayThread); m_pXRayHelp->SetPortParams(m_stXRaySettingParams.sPortName, (QSerialPort::BaudRate)m_stXRaySettingParams.nBaudRate); connect(m_pXRayThread, &QThread::started, m_pXRayHelp, &SerialPortBase::OnSerialThreadStarted); connect(m_pXRayThread, &QThread::finished, m_pXRayHelp, &QObject::deleteLater); //射线源数据更新 connect(m_pXRayHelp, &SerialPortBase::SigMapParamsUpdate, this, &XRayControl::OnXRayStatusChanged, Qt::UniqueConnection); //射线源使用时间刷新 connect(m_pXRayHelp, &SerialPortBase::SigUpdateXRayUseTime, this, &XRayControl::SigUpdateXRayUseTime); //射线源逆初始化 connect(this, &XRayControl::SigUnInit, m_pXRayHelp, &SerialPortBase::UnInit); //射线源软复位 connect(this, &XRayControl::SigXRayRst, m_pXRayHelp, &SerialPortBase::OnResetXRay); //射线源预热指令 connect(this, &XRayControl::SigXRayWarmUp, m_pXRayHelp, &SerialPortBase::OnWarmUpXRay); //设置电压电流 connect(this, &XRayControl::SigSetXRayElectricParams, m_pXRayHelp, &SerialPortBase::OnSetXRayParams); //开启或关闭射线源 connect(this, &XRayControl::SigSetXRaySwitch, m_pXRayHelp, &SerialPortBase::OnSwitchXRay); m_pXRayThread->start(); return false; } bool drive::XRayControl::UnInit() { emit SigSetXRaySwitch(false); //添加阻塞 QEventLoop loop; connect(m_pXRayHelp, &SerialPortBase::SigUnitFinished, &loop, &QEventLoop::quit); emit SigUnInit(); loop.exec(); m_pXRayThread->quit(); m_pXRayThread->wait(); return false; } void drive::XRayControl::SetXRayRst() { emit SigXRayRst(); } void drive::XRayControl::SetSyncWarmUp() { } void drive::XRayControl::SetWarmUp() { emit SigXRayWarmUp(); } int drive::XRayControl::SetXRaySwitch(bool bIsOpen) { emit SigSetXRaySwitch(bIsOpen); if (!bIsOpen && m_XRayStatus == XRMS_On) //只有开源后关源才设置成准备就绪 { m_XRayStatus = XRMS_StandBy; } return true; } int drive::XRayControl::SetXRayElectricParams(int nVol, int nCur) { emit SigSetXRayElectricParams(nVol, nCur); return 0; } XRayMonitorStatus drive::XRayControl::GetAutoXRaySts() { XRayMonitorStatus nXRaySts = GetXRayStatus(); switch (nXRaySts) { case XRMS_NeedWarmUp: break; case XRMS_WarmUp: break; case XRMS_StandBy: break; case XRMS_On: break; case XRMS_Protected: { SetXRayRst(); QThread::msleep(1000); nXRaySts = GetXRayStatus(); }break; case XRMS_Failure: case XRMS_TsfOn: case XRMS_LockOn: { QThread::msleep(1000); nXRaySts = GetXRayStatus(); }break; default: break; } return nXRaySts; } XRayMonitorStatus drive::XRayControl::GetXRayStatus() { //重新获取下状态 XRayMonitorMap xRayStatus = GetXRayMonitorMap(); OnXRayStatusChanged(xRayStatus); return m_XRayStatus; } int drive::XRayControl::GetXRayUseTime() { return m_nUseTime; } bool drive::XRayControl::SyncXRayClose(int nTime) { SetXRaySwitch(false); int nWait = 0; while (nWait < nTime) { if (m_nOutVol < 1 && m_nOutCur < 1) { //qDebug(“XRayOpen Wait Time == %d ms”, nWait * XRAY_WAIT_TIME); LOG_DEBUG(“XRay Close Wait Time == %d ms”, nWait * XRAY_WAIT_TIME); //QThread::msleep(XRAY_WAIT_TIME); break; } QThread::msleep(XRAY_WAIT_TIME); nWait++; } if (nWait >= nTime) { return false; } m_XRayStatus = XRMS_StandBy; return true; } bool drive::XRayControl::SyncXRayOpen(int nVol, int nCur, int nTime) { SetXRayElectricParams(nVol, nCur); SetXRaySwitch(true); int nIdx = 0; while (nIdx < nTime) { if (nVol<= (m_nOutVol+1)&&nCur <= (m_nOutCur + 1)) { qDebug(“XRayOpen Wait Time == %d ms”, nIdx*XRAY_WAIT_TIME); break; } QThread::msleep(XRAY_WAIT_TIME); nIdx++; } if (nIdx >= nTime) { return false; } return true; } XRayMonitorMap drive::XRayControl::GetXRayMonitorMap() { return m_pXRayHelp->GetXRayMonitorMap(); } bool drive::XRayControl::AutoMotionReady() { switch (m_XRayStatus) { case XRMS_NeedWarmUp: { emit SigRevFrameData(tr(“C_XRayNeedWarmUp”), false); return false; } case XRMS_WarmUp: { emit SigRevFrameData(tr(“C_XRayWarmUp”), false); return false; } break; case XRMS_StandBy: case XRMS_On: { //射线源状态正常 emit SigRevFrameData(tr(“C_XRayReady”), true); }break; case XRMS_Protected: case XRMS_Failure: case XRMS_TsfOn: case XRMS_LockOn: { //启动失败,射线源连锁关闭 emit SigRevFrameData(tr(“C_XRayLockOn”), false); return false; }break; default: break; } return true; } void drive::XRayControl::GetMonitorParams() { m_pXRayHelp->SendCommand(XRSCH_SAR, 0); } void drive::XRayControl::OnXRayStatusChanged(XRayMonitorMap qMapStatus) { XRayMonitorStatus nStatus = XRMS_NeedWarmUp; for (int i = XRMT_STS; i < XRMT_NUMS; i++) { m_XRayStatusMap[i] = qMapStatus[i]; } if (m_XRayStatusMap[XRMT_STS] == 5 && m_XRayStatusMap[XRMT_SIN] == 1) { nStatus = XRMS_LockOn; } else { nStatus = (XRayMonitorStatus)m_XRayStatusMap[XRMT_STS]; } if (m_nOutVol != m_XRayStatusMap[XRMT_SHV] || m_nOutCur != m_XRayStatusMap[XRMT_SCU] || m_XRayStatus != nStatus) { m_nOutVol = m_XRayStatusMap[XRMT_SHV]; m_nOutCur = m_XRayStatusMap[XRMT_SCU]; m_XRayStatus = nStatus; LOG_DEBUG("XRayMonitorStatus:Sts: %d; vol:%d ; Cur:%d ", m_XRayStatus, m_nOutVol, m_nOutCur); emit SigUpdateXRayStatus(m_XRayStatus, m_nOutVol, m_nOutCur); } if (m_nUseTime != m_XRayStatusMap[XRMT_XST_TIME]) { m_nUseTime = m_XRayStatusMap[XRMT_XST_TIME]; emit SigUpdateXRayUseTime(m_nUseTime); } } 讲讲这些代码,仔细讲解每一行,然后给出整体的运行流程 #pragma once #include “common\global.h” #include “common\LogDefines.h” #include “common\PiercingEyeSetting.h” #include #include #include <QtSerialPort/QSerialPort> // 提供访问串口的功能 #include <QtSerialPort/QSerialPortInfo> // 提供系统中存在的串口信息 #define XRAY_USE_TIME_STEP (500) /!< 监听间隔时间 >/ #define SERIAL_OK (0) /!< 串口值 >/ #define XRAY_RECEIVE_NULL (0x1F000001) /!< 射线源空 >/ #define XRAY_RECEIVE_ERR (0x1F000002) /!< 射线源接收数据异常 >/ #define XRAY_SEND_ERR (0x1F000003) /!< 射线源下发数据异常 >/ typedef int SerialPortCommand; //串口指令 Q_DECLARE_METATYPE(SerialPortCommand); typedef QMap<SerialMonitorNum, int> XRayMonitorMap; //串口监听状态表 Q_DECLARE_METATYPE(XRayMonitorMap); namespace drive { //串口配置参数 struct SerialParams { QString sPortName; /!< 串口名称 >/ QSerialPort::BaudRate nBaudRate; /!< 波特率 >/ QByteArray bytStart; /!< 帧头 >/ QByteArray bytEnd; /!< 帧尾 >/ }; /** • 射线源基类 / class SerialPortBase : public QObject { Q_OBJECT public: SerialPortBase(); ~SerialPortBase(); virtual int SendCommand(const SerialPortCommand& nCmd, const QByteArray& value = QByteArray()); virtual const QByteArray SendSyncCommand(const SerialPortCommand& nCmd, const QByteArray& value = QByteArray()); virtual void SetPortParams(QString sPortName, QSerialPort::BaudRate nBaudRate); virtual void SetTimeInterval(int nInterval = 1000); virtual int Init(); virtual int UnInit(); public slots : virtual void OnSerialThreadStarted(); virtual void OnSendMonitorCommand(); virtual void OnConnectXRay(bool bStatus); virtual void OnSwitchXRay(bool bStatus); virtual void OnSwitchXRaySetParams(bool bStatus,int nVol,int nCur); virtual void OnSetXRayParams(int nVol, int nCur); virtual void OnWarmUpXRay(); virtual void OnResetXRay(); XRayMonitorMap GetXRayMonitorMap(); signals: void SigMapParamsUpdate(XRayMonitorMap pStatusMap); void SigUpdateXRayUseTime(int nTime); void SigErrMsg(const QString& msg); void SigInitFinished(); void SigUnitFinished(); protected: virtual int Analysis(SerialPortCommand nCmd, QByteArray bytArray); virtual QByteArray GetCommand(SerialPortCommand cmd, const QByteArray& bytValue); bool OpenSerialPort(QObject parent = NULL); bool IsSerialPortOpen(); protected: QSerialPort* m_pSerialPort; /!< 串口指针 >/ SerialParams m_stuSerialParams; /!< 串口数据配置结构体 >/ XRayMonitorMap m_StatusMap; /!< 监听数据信息 >/ QTimer* m_pMonitorTimer; /!< 监听计时器 >/ int m_nTimerInterval; /!< 定时器刷新频率 >/ QMutex m_SerialMutex; /!< 串口锁 >/ }; } • #include “SerialPortBase.h” drive::SerialPortBase::SerialPortBase() :m_pSerialPort(NULL) , m_pMonitorTimer(NULL) , m_nTimerInterval(500) { m_stuSerialParams.bytStart = “”; m_stuSerialParams.bytEnd = “\r”; //注册串口指令 qRegisterMetaType(“SerialPortCommand”); //注册射线源监控Map qRegisterMetaType(“XRayMonitorMap”); } drive::SerialPortBase::~SerialPortBase() { if (NULL != m_pMonitorTimer) { delete m_pMonitorTimer; m_pMonitorTimer = NULL; } if (NULL != m_pSerialPort) { delete m_pSerialPort; m_pSerialPort = NULL; } } QByteArray drive::SerialPortBase::GetCommand(SerialPortCommand cmd, const QByteArray& bytValue) { return QByteArray(); } bool drive::SerialPortBase::OpenSerialPort(QObject* parent) { if (NULL == m_pSerialPort) { //qDebug() << "Thread ID OpenSerialPort: " << QThread::currentThreadId(); m_pSerialPort = new QSerialPort(parent); } if (!m_pSerialPort->isOpen()) { m_pSerialPort->setPortName(m_stuSerialParams.sPortName); m_pSerialPort->setBaudRate(m_stuSerialParams.nBaudRate); if (!m_pSerialPort->open(QIODevice::ReadWrite)) { LOG_ERROR(“Seriel IS NULL OPEN FAILED !:%s”, m_stuSerialParams.sPortName.toLatin1().data()); return false; } LOG_ERROR(“Seriel IS NULL OPEN SUCCESS !:%s”, m_stuSerialParams.sPortName.toLatin1().data()); } return true; } bool drive::SerialPortBase::IsSerialPortOpen() { if (m_pSerialPort->isOpen()) { return true; } return OpenSerialPort(this); } void drive::SerialPortBase::OnSendMonitorCommand() { } void drive::SerialPortBase::OnConnectXRay(bool bStatus) { } void drive::SerialPortBase::OnSwitchXRay(bool bStatus) { } void drive::SerialPortBase::OnSwitchXRaySetParams(bool bStatus, int nVoltage, int nCurrent) { } void drive::SerialPortBase::OnSetXRayParams(int nVol, int nCur) { } void drive::SerialPortBase::OnWarmUpXRay() { } void drive::SerialPortBase::OnResetXRay() { } XRayMonitorMap drive::SerialPortBase::GetXRayMonitorMap() { return m_StatusMap; } int drive::SerialPortBase::SendCommand(const SerialPortCommand& nCmd, const QByteArray& value) { QByteArray receiveData; constexpr int maxRetries = 3;//重发次数 int retryCount = 0; do { retryCount++; receiveData = SendSyncCommand(nCmd, value); } while (SERIAL_OK != Analysis(nCmd, receiveData) && retryCount < maxRetries); return 0; } const QByteArray drive::SerialPortBase::SendSyncCommand(const SerialPortCommand& nCmd, const QByteArray& value) { if (!IsSerialPortOpen()) { qWarning() << “[SendSyncCommand] Failed to open serial port”; return QByteArray(“ERR_NOTOPEN”); } const QByteArray sendBytes = GetCommand(nCmd, value); if (sendBytes.isEmpty()) { qWarning() << “[SendSyncCommand] Failed to generate command”; return QByteArray(“ERR_SENDDATA_NULL”); } const int bytesWritten = m_pSerialPort->write(sendBytes); if (bytesWritten != sendBytes.length()) { qWarning() << “[SendSyncCommand] Failed to write all data to serial port”; return QByteArray(“ERR_WRITE_LOST”); } QThread::msleep(20); QByteArray receiveData; while (m_pSerialPort->waitForReadyRead(10)) { const QByteArray tempData = m_pSerialPort->readAll(); receiveData.append(tempData); if (receiveData.contains(‘\r’)) { break; } } LOG_TRACE(“sendBytes: %s; bytesWritten: %d; receiveData: %s”, sendBytes.trimmed().toStdString().c_str(), bytesWritten, receiveData.trimmed().toStdString().c_str()); QThread::msleep(10); m_pSerialPort->flush(); return receiveData; } void drive::SerialPortBase::SetPortParams(QString sPortName, QSerialPort::BaudRate nBaudRate) { m_stuSerialParams.sPortName = sPortName; m_stuSerialParams.nBaudRate = nBaudRate; } void drive::SerialPortBase::SetTimeInterval(int nInterval) { m_nTimerInterval = nInterval; } int drive::SerialPortBase::Init() { return 0; } int drive::SerialPortBase::UnInit() { qDebug() << "Thread ID UnInit: " << QThread::currentThreadId(); if (NULL != m_pMonitorTimer && m_pMonitorTimer->isActive()) { LOG_INFO(“XRay Monitor Timer Stop!”); m_pMonitorTimer->stop(); } if (NULL != m_pSerialPort && m_pSerialPort->isOpen()) { LOG_INFO(“XRay Port Close”); m_pSerialPort->close(); } emit SigUnitFinished(); return 0; } int drive::SerialPortBase::Analysis(SerialPortCommand nCmd, QByteArray bytArray) { return SERIAL_OK; } void drive::SerialPortBase::OnSerialThreadStarted() { }讲讲这些代码 #pragma once #include “SerialPortBase.h” #ifndef HAMAMATSUHELP_H #define HAMAMATSUHELP_H namespace drive { //滨松射线源指令 enum XRayStatusCommandHamamatsu :SerialPortCommand { XRCCH_XON, /!< 开启射线源 >/ XRCCH_XOF, /!< 关闭射线源 >/ XRCCH_HIV, /!< 管电压设定 >/ XRCCH_CUR, /!< 管电流设定 >/ XRCCH_WUP, /!< 预热开始:在“STS 0”或“STS 2”状态时,发送“WUP”指令即开始预热 >/ XRCCH_RST, /!< 复位指令,解除过载保护,STS为4时 >/ XRSCH_SAR, /!< 状态汇总确认,左到右以此为STS,SHV,SCU >/ XRSCH_STS, /!< 状态确认 >/ XRSCH_SHV, /!< 输出管电压确认 >/ XRSCH_SCU, /!< 输出管电流确认 >/ XRSCH_SNR, /!< 依次为SER,SIN,SPH >/ XRSCH_SER, /!< 硬件错误确认 0-正常;3-电路板异常1;4-电路板异常2; >/ XRSCH_SPH, /!< 预热监控 0-预热完成;1-预热中 >/ XRSCH_SIN, /!< 联锁确认 0-联锁闭合;1-联锁断开 >/ XRSCH_TYP, /!< 返回射线源型号 >/ XRSCH_SXT, /!< 获取射线源使用时间参数 >/ XRCCH_NULL, /!< 保留值 >/ }; class HamamatsuHelp :public SerialPortBase { Q_OBJECT public: HamamatsuHelp(); ~HamamatsuHelp(); //初始化 int Init() override; //获取指令 QByteArray GetCommand(SerialPortCommand cmd, const QByteArray& bytValue) override; //解析指令 int Analysis(SerialPortCommand nCmd, QByteArray bytArray) override; public slots : //子线程启动槽函数 void OnSerialThreadStarted() override; //发送监听指令 void OnSendMonitorCommand() override; //开关射线源 void OnSwitchXRay(bool bStatus) override; //下发电压电流并开关射线源 void OnSwitchXRaySetParams(bool bStatus, int nVol, int nCur) override; //下发电压电流参数 void OnSetXRayParams(int nVol, int nCur) override; //射线源预热 void OnWarmUpXRay() override; //射线源软复位 void OnResetXRay() override; private: int m_nXRayUseTime; /!< 射线源使用时间监听计时 >/ }; #pragma region RadiationHelp 辐射探测器控制 #define RADIATION_MON_REC_LENGTH (22) /!< 辐射剂量仪返回结果长度 >/ class RadiationHelp :public SerialPortBase { union RadiationUnion { float f; char c[4]; uint u; }; enum RadiationInstrumentStatus :SerialPortCommand { RIS_Monitor = 1, //辐射监控 RIS_GetParams = 2, //参数获取 RIS_SetParams = 3, //参数设置 }; enum RadiationOrder { R0_ID, //设备地址,起始位 R0_CMD, //命令 R0_ARG, //参数 R0_LEN, //DATA 段的长度 R0_DATA, //包中含有的数据,无则为空。 R0_CHECKSUM, //校验码(除CHECKSUM 外所有字节的累加和) R0_Nums }; Q_OBJECT public: RadiationHelp(); ~RadiationHelp(); int Init() override; QByteArray GetCommand(SerialPortCommand cmd, const QByteArray& bytValue) override; int Analysis(SerialPortCommand nCmd, QByteArray bytArray) override; private: QByteArray m_SendCommand; RadiationUnion m_stRadiationParams; int SendCommand(const SerialPortCommand& nCmd, const QByteArray& value = QByteArray()) override; float ConvertEndian(float fValue); public slots : /** • @brief OnXRayThreadStarted • • • 子线程启动 • • / void OnSerialThreadStarted() override; /* • @brief OnSendMonitorCommand • • • 发送监听指令 • • / void OnSendMonitorCommand() override; signals: void SigRadiationParamsUpdate(SerialMonitorNum eCmd, float fValue); }; #pragma endregion #pragma region LightRegulationStatus 光源控制串口 /* • 光源控制指令 / enum LightRegulationStatus :SerialPortCommand { LRS_SX = 1, //参数设置 LRS_MON = 3, //参数监听 LRS_OPEN = 4, //常亮 LRS_CLOSE = 5, //常灭 }; class LightRegulation :public SerialPortBase { Q_OBJECT public: LightRegulation(); ~LightRegulation(); int Init() override; QByteArray GetCommand(SerialPortCommand cmd, const QByteArray& bytValue) override; int Analysis(SerialPortCommand nCmd, QByteArray bytArray) override; private: QString m_qstrChannel; //通道设置 int m_nType; /!< 光源控制器型号 >*/ public slots : //void OnSerialThreadStarted() override; }; #pragma endregion } #endif#include “HamamatsuHelp.h” drive::HamamatsuHelp::HamamatsuHelp() { } drive::HamamatsuHelp::~HamamatsuHelp() { } int drive::HamamatsuHelp::Init() { for (int i = XRMT_STS; i < XRMT_NUMS; i++) { m_StatusMap[i] = 0; } m_stuSerialParams.bytStart = “”; m_stuSerialParams.bytEnd = “\r”; m_nXRayUseTime = XRAY_USE_TIME_STEP; return 0; } QByteArray drive::HamamatsuHelp::GetCommand(SerialPortCommand cmd, const QByteArray& bytValue) { QByteArray qbRec = m_stuSerialParams.bytStart; switch (cmd) { case XRCCH_XON: qbRec += “XON”; break; case XRCCH_XOF: qbRec += “XOF”; break; case XRCCH_HIV: qbRec += QString(“HIV %1”).arg(QString(bytValue)).toLatin1(); break; case XRCCH_CUR: qbRec += QString(“CUR %1”).arg(QString(bytValue)).toLatin1(); break; case XRCCH_RST: qbRec += “RST”; break; case XRSCH_SAR: qbRec += “SAR”; break; case XRSCH_SNR: qbRec += “SNR”; break; case XRSCH_SXT: qbRec += “SXT”; break; case XRSCH_SIN: qbRec += “SIN”; break; case XRSCH_SER: qbRec += “SER”; break; case XRCCH_NULL: // 无需处理 break; } qbRec += m_stuSerialParams.bytEnd; return qbRec; } int drive::HamamatsuHelp::Analysis(SerialPortCommand nCmd, QByteArray receiveData) { //qDebug() << receiveData; if (receiveData.isEmpty()) { LOG_ERROR(“receiveData is Null”); return XRAY_RECEIVE_ERR; } if (receiveData.startsWith(“ERR”)) { //解析一下错误 LOG_ERROR(“XRay Command Error %s!”, receiveData.toStdString().data()); return XRAY_RECEIVE_ERR; } if (!receiveData.endsWith(‘\r’)) { LOG_ERROR(“Get SerialPort Data Error: %s!”, receiveData.toStdString().data()); return XRAY_RECEIVE_ERR; } QString receiveString = QString::fromLatin1(receiveData, receiveData.size()); QStringList qStrList = receiveString.split(" “); switch (nCmd) { case XRSCH_SAR: { if (qStrList.count() == 8 && qStrList[0] == “SAR”) { for (int i = 0; i <= 2; i++) { m_StatusMap[i + XRMT_STS] = qStrList[i + 1].toInt(); } emit SigMapParamsUpdate(m_StatusMap); return SERIAL_OK; } }break; case XRSCH_SXT: { if (qStrList.count() == 2 && qStrList[0] == “SXT”) { m_StatusMap[XRMT_XST_TIME] = qStrList[1].toInt(); emit SigMapParamsUpdate(m_StatusMap); emit SigUpdateXRayUseTime(m_StatusMap[XRMT_XST_TIME]); return SERIAL_OK; } }break; case XRCCH_XON: { if (qStrList[0].contains(“XON”)) { return SERIAL_OK; } }break; case XRCCH_XOF: { if (qStrList[0].contains(“XOF”)) { return SERIAL_OK; } }break; case XRCCH_HIV: { if (qStrList[0] == “HIV”) { return SERIAL_OK; } }break; case XRCCH_CUR: { if (qStrList[0] == “CUR”) { return SERIAL_OK; } }break; case XRCCH_RST: { if (qStrList[0].contains(“RST”)) { return SERIAL_OK; } }break; default: { return SERIAL_OK; }break; } return XRAY_RECEIVE_ERR; } void drive::HamamatsuHelp::OnSendMonitorCommand() { SendCommand(XRSCH_SXT); SendCommand(XRSCH_SAR); SendCommand(XRSCH_SIN); SendCommand(XRSCH_SER); } void drive::HamamatsuHelp::OnSwitchXRay(bool bStatus) { SendCommand(bStatus ? XRCCH_XON : XRCCH_XOF); } void drive::HamamatsuHelp::OnSwitchXRaySetParams(bool bStatus, int nVol, int nCur) { SendCommand(XRCCH_HIV, QByteArray::number(nVol)); SendCommand(XRCCH_CUR, QByteArray::number(nCur)); SendCommand(bStatus ? XRCCH_XON : XRCCH_XOF); } void drive::HamamatsuHelp::OnSetXRayParams(int nVol, int nCur) { SendCommand(XRCCH_HIV, QByteArray::number(nVol)); SendCommand(XRCCH_CUR, QByteArray::number(nCur)); } void drive::HamamatsuHelp::OnWarmUpXRay() { SendCommand(XRCCH_WUP); } void drive::HamamatsuHelp::OnResetXRay() { SendCommand(XRCCH_RST); } void drive::HamamatsuHelp::OnSerialThreadStarted() { OpenSerialPort(this); Init(); if (m_pMonitorTimer == nullptr) { m_pMonitorTimer = new QTimer(); m_pMonitorTimer->setInterval(m_nTimerInterval); connect(m_pMonitorTimer, &QTimer::timeout, this, &HamamatsuHelp::OnSendMonitorCommand); QThread::msleep(m_nTimerInterval); m_pMonitorTimer->start(); } } drive::RadiationHelp::RadiationHelp() { } drive::RadiationHelp::~RadiationHelp() { } int drive::RadiationHelp::Init() { m_stuSerialParams.bytStart[0] = 0xA4; m_stuSerialParams.bytEnd = “”; return 0; } QByteArray drive::RadiationHelp::GetCommand(SerialPortCommand cmd, const QByteArray& nValue) { QByteArray qbytRec = “”; QString strRec = “”; switch (cmd) { case RIS_Monitor: { strRec = “A401000000000000A500”; qbytRec = strRec.toLatin1(); qbytRec = QByteArray::fromHex(qbytRec); break; } case RIS_GetParams: { strRec = “A401000000000000A600”; qbytRec = strRec.toLatin1(); qbytRec = QByteArray::fromHex(qbytRec); } } return qbytRec; } int drive::RadiationHelp::SendCommand(const SerialPortCommand& nCmd, const QByteArray& value) { if (IsSerialPortOpen()) { QByteArray bytArr = GetCommand(nCmd, value); m_pSerialPort->write(bytArr); QThread::msleep(5); if (m_pSerialPort->waitForReadyRead(200)) { int index = 0; QByteArray recData = m_pSerialPort->readAll(); qDebug() << “Send:” << bytArr << " Read:” << recData; m_pSerialPort->flush(); return Analysis(nCmd, recData); } } return 0; } int drive::RadiationHelp::Analysis(SerialPortCommand nCmd, QByteArray bytArray) { QByteArray sRec = bytArray.toHex(); switch (nCmd) { case RIS_Monitor: { if (sRec.startsWith(“a401”)) { if (sRec.size() >= 32) { QByteArray rec0 = sRec.mid(24, 8); //大小端转化 RadiationUnion stRaiation = { 0 }; stRaiation.u = rec0.toUInt(nullptr, 16); float f0 = 0; memcpy(&f0, &rec0, sizeof(rec0)); float fDoseRate = ConvertEndian(stRaiation.f); emit SigRadiationParamsUpdate(RadiationMonitorType::RMT_DoseRate, fDoseRate); } } }break; default: break; } return 0; } float drive::RadiationHelp::ConvertEndian(float fValue) { RadiationUnion d1, d2; d1.f = fValue; d2.c[0] = d1.c[3]; d2.c[1] = d1.c[2]; d2.c[2] = d1.c[1]; d2.c[3] = d1.c[0]; return d2.f; } void drive::RadiationHelp::OnSendMonitorCommand() { SendCommand(RIS_Monitor); } void drive::RadiationHelp::OnSerialThreadStarted() { Init(); OpenSerialPort(this); if (NULL == m_pMonitorTimer) { m_pMonitorTimer = new QTimer(); m_pMonitorTimer->setInterval(10000); //SendCommand(RIS_Monitor);//用于发送初始参数设置 connect(m_pMonitorTimer, &QTimer::timeout, this, &RadiationHelp::OnSendMonitorCommand); QThread::msleep(500); m_pMonitorTimer->start(); } } drive::LightRegulation::LightRegulation() { } drive::LightRegulation::~LightRegulation() { } int drive::LightRegulation::Init() { m_qstrChannel = ‘A’ + common::PiercingEyeSetting::GetInstall().GetLightRegulationParams().nChannel; m_nType = common::PiercingEyeSetting::GetInstall().GetLightRegulationParams().nType; OpenSerialPort(); return 0; } QByteArray drive::LightRegulation::GetCommand(SerialPortCommand cmd, const QByteArray& bytValue) { QByteArray qbytRec = “”; switch (cmd) { case LRS_SX: { switch (m_nType) { case 0: qbytRec = QString(“S%1%2#”).arg(m_qstrChannel).arg(QString(bytValue).rightJustified(4, ‘0’)).toLatin1(); break; case 1: default: qbytRec = QString(“SL%1%2#”).arg(m_qstrChannel).arg(QString(bytValue).rightJustified(4, ‘0’)).toLatin1(); break; } break; } case LRS_MON: qbytRec = QString(“SL%1#”).arg(m_qstrChannel).toLatin1(); break; case LRS_OPEN: qbytRec = QString(“SW%10001#”).arg(m_qstrChannel).toLatin1(); break; case LRS_CLOSE: qbytRec = QString(“SW%10000#”).arg(m_qstrChannel).toLatin1(); break; default: return QByteArray(); } return qbytRec; } int drive::LightRegulation::Analysis(SerialPortCommand nCmd, QByteArray bytArray) { return 0; }讲讲这些代码,每个模块之间的关系,还有每个类具体是做什么的,详细一点 •
最新发布
10-16
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值