一个小把戏算法,获取大乐透,并且计算出最佳的结果(Qt C++ 和Android共用)

无聊的国庆,总得做点什么好玩的是不是,那就写代码获取大乐透,让后按照自己的算法推测下一期的结果吧。

话不多说,上代码

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    initDataBase();
    auto db = QSqlDatabase::database();
    if(db.isValid())
    {
        QSqlTableModel *model = new QSqlTableModel(this);
        model->setTable(his_tb_name);
        model->setSort(0,Qt::DescendingOrder);
        model->select();
        model->setHeaderData(0, Qt::Horizontal, tr("期号"));
        model->setHeaderData(1, Qt::Horizontal, tr("号码"));
        model->setHeaderData(2, Qt::Horizontal, tr("开奖日期"));


        ui->tableView->setModel(model);
        ui->tableView->resizeColumnsToContents();
        Log(" model db tables "<<model->database().tables());
    }

    connect(this,&Widget::finishedCurrentPage,this,&Widget::onCurrentPageFinished,Qt::QueuedConnection);

    initialChat();

    addLog(QSysInfo::buildAbi());
}

上述代码的作用就是UI入口,主要是创建的sqlite数据库,然后显示最近获取的期号数据

void initDataBase()
{
    QString log;
    auto db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./lotus.db");
    auto ret =  db.open();
    log.append(QString("open db ")+ (ret?" ok ":"error"+db.lastError().text()));
    auto tables = db.tables();

    if(!tables.contains(his_tb_name))
    {
        QString sql =QString("create table %1 (%2 text PRIMARY KEY NOT NULL, %3 text,%4 text);").arg(his_tb_name).arg(Serial_No).arg(front_no).arg(end_no);
        auto retsql = db.exec(sql);
        log.append( " \n create table "+db.lastError().text());
    }

    qDebug()<<" log "<<log;
}

上述代码和名字一致,主要是创建了sqlite和对应的表。

const QString lotusUrl ="https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo=85&provinceId=0&pageSize=100&isVerify=1&pageNo=%1";


const QString end_no ="End_No";
const QString Serial_No ="Serial_No";
const QString front_no ="Front_No";

需要使用的常量,主要是后需要http请求获取彩票数据,然后是表头等


void Widget::getCurrentPageData()
{
    auto mng = manager();

    QUrl url(lotusUrl.arg(currentPage));
    auto reply = mng->get(QNetworkRequest(url));
    connect(reply,&QNetworkReply::finished,this,&Widget::handleReply,Qt::QueuedConnection);
}

void Widget::handleReply()
{
    auto reply = dynamic_cast<QNetworkReply*>(sender());
    auto json = reply->readAll();
    auto doc = QJsonDocument::fromJson(json);
    if(doc.isNull())
    {
        Log(" empty json "<<json<<reply->errorString());
        return ;
    }

    auto value = doc.object().value("value").toObject();

    auto db = QSqlDatabase::database();
    qDebug()<<" tables "<<db.tables();
    QSqlQuery query(db);
    query.prepare(QString("insert into %1 values(?,?,?)").arg(his_tb_name));
    auto records = value.value("list").toArray();
    QVariantList serials;
    QVariantList frontnumbers;
    QVariantList endNumbers;

    QDate minDate;
    QDate maxDate;

    for(auto record : records)
    {
        auto dateString = record.toObject().value("lotteryDrawTime").toString();


        auto tmpDate = QDate::fromString(dateString,Qt::ISODate);
        if(!minDate.isValid())
        {
            minDate = tmpDate;
        }
        if(!maxDate.isValid())
        {
            maxDate = tmpDate;
        }
        if(maxDate<tmpDate)
        {
            maxDate = tmpDate;
        }
        if(minDate>tmpDate)
        {
            minDate  = tmpDate;
        }
        qDebug()<<" date "<<tmpDate;
        if(this->isExist(dateString))
        {
            qDebug()<<" has exists!";
            continue;
        }

        endNumbers<<dateString;
        serials<<record.toObject().value("lotteryDrawNum").toString();
        frontnumbers<<record.toObject().value("lotteryDrawResult").toString();
    }
    query.addBindValue(serials);
    query.addBindValue(frontnumbers);
    query.addBindValue(endNumbers);

    qDebug()<<" from "<<minDate <<" to "<<maxDate;
    if(this->fromDate.isNull() || this->fromDate >minDate)
    {
        this->fromDate = minDate;
    }

    if(this->toDate.isNull() || this->toDate< maxDate)
    {
        this->toDate = maxDate;
    }

    if(!query.execBatch())
    {
        qDebug()<<" exe error "<<query.lastError().text()
                 <<" serial "<<serials.size()
                 <<" front "<<frontnumbers.size()
                 <<" end "<<endNumbers.size()
                 <<" query "<<query.lastQuery();
    }
    qDebug()<<" exe end ";

    emit finishedCurrentPage();
    reply->deleteLater();
}

主要用于获取当前页面对应的彩票号码,插入到数据库;中间去重;每次都活获取单页网页数据,后续需要继续下一页还是停止,由UI上的天数决定。

这里省略掉关于统计的代码,很简单,就是便利数据库,把所有的数据全部统计一次,后面计算最佳的时候使用到。

所以界面需要先 刷新,按统计,再按最佳

void Widget::on_bestBtn_clicked()
{
    if(lastEnds.isEmpty() || lastFronts.isEmpty())
    {
        on_CalculateBtn_clicked();
    }
    ui->toolBox->setCurrentIndex(2);
    ValueList fronts = convertMapToList(this->lastFronts);
    ValueList ends = convertMapToList(this->lastEnds);

    // get max
    auto theMax = [](const ValuePair&left,const ValuePair&right )
    {
        return left.second>right.second;
    };

    std::stable_sort(fronts.begin(),fronts.end(),theMax);
    std::stable_sort(ends.begin(),ends.end(),theMax);

    qDebug()<<" fronts "<<fronts
             <<"\n ends "<<ends;

    //max team
    QStringList maxValues;
    for(short i=0;i<5;++i)
    {
        auto value =fronts.at(i).first;
        maxValues<< QString::number(value);
    }

    for(short i=0;i<2;++i)
    {
        auto value =ends.at(i).first;
        maxValues<< QString::number(value);
    }

    //min team
    QStringList minValues;
    for(short i=0;i<5;++i)
    {
        auto value =fronts.at(fronts.size()-i-1).first;
        minValues<< QString::number(value);

    }

    for(short i=0;i<2;++i)
    {
        auto value =ends.at(ends.size()-i-1).first;
        minValues<< QString::number(value);
    }

    //middle team
    QStringList middleValues;
    short frontdiff = fronts.size()/3+1;
    short endDiff = ends.size()/3+1;
    for(short i=0;i<5;++i)
    {
        auto value =fronts.at(frontdiff+i).first;
        middleValues<< QString::number(value);

    }

    for(short i=0;i<2;++i)
    {
        auto value =ends.at(endDiff+i).first;
        middleValues<< QString::number(value);
    }

    auto isValueSmaller = [](const QString &left,const QString&right){

        return left.toShort()<right.toShort();
    };

    std::stable_sort(maxValues.begin(),maxValues.end()-2,isValueSmaller);
    std::stable_sort(minValues.begin(),minValues.end()-2,isValueSmaller);
    std::stable_sort(middleValues.begin(),middleValues.end()-2,isValueSmaller);

    QString result = QDateTime::currentDateTime().toString();
    result+=QString("根据玄学推断,下一期开奖结果是:\n");
    result+="\n 最大期望 "+maxValues.join(" -- ");
    result+="\n 最小期望 "+minValues.join(" -- ");
    result+="\n 中间期望 "+ middleValues.join(" -- ");
    addLog(result);

}

上述代码就是彩票计算;

lastFronts是通过点击计算按钮开始统计最近的前区号码(1-35)的出现的频次;
lastEnds对应后区(1-12);

通过统计结果进行排序,分别统计出最高频率组,最低频率组,和中间频率组,这三组结果就是下一期推测(哈哈,纯属搞笑的)

注意,stable_sort是为了保证不同平台的一致性结果;结果测试,如果使用sort函数,Android和我window结果在顺序相同的时候,排序结果不一致;Android在排序过程中把顺序打乱了,因此需要使用稳定排序;

我的代码是基于Qt 6.3可以编译,Android的话需要自己配置,我是用的是33 API;项目使用的是qmake的pro,因为目前qt的6.3还不能很好的支持cmake Android编译,暂时只能这样子;项目中需要网络请求,所以使用了ssl工程,这个是qt的文档说的。事实上也是这样子。下面附上Qt配置Android的环境截图,需要自己搞定 jdk,Android ndk和sdk

后面是我的代码和打包的程序,包括window 11的exe和Android 12能够运行的app

window程序界面

 

Android app界面

以下是资源链接:

lotus源码和app-C++文档类资源-CSDN下载

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值