D - Enough Array

本文介绍了一种使用前缀和与枚举的方法来解决寻找数组中最多的大于特定值K的连续子序列数量的问题。通过实现C++代码,详细展示了如何利用前缀和加速查找过程,以及如何通过枚举策略高效地找到所有符合条件的子序列。

原题地址
题意:找到最多的大于K的连续子序列的个数
思路:前缀和+枚举,想说的都在代码里
代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <math.h>
#include <string.h>
#include<iostream>
using namespace std;
#define ll long long
int cmd(int a ,int b){
    return abs(a)>abs(b);
}
ll arr[1000000]={0};
ll brr[1000000]={0};
ll crr[1000000]={0};
int main() {
    ll n , k;
    cin >>n>>k;
    ll cnt=0;
    ll sum=0;
    for(int i=1;i<=n;i++)
        cin >>arr[i];
    for(int i=1;i<=n;i++)
        brr[i] = brr[i-1]+arr[i];
    int l=0,r=0;
    //下面枚举的方法是从第一个开始找,找到第R个合适的数,然后再从第二个数开始找到第二个数相对应合适的数
    //我的疑惑,有没有可能会出现第二个数到合适的数之间的个数,比第一个数到合适的数之间的个数小。
    //回答:不可能,因为再多一个数的情况下,都没找到合适的数,在少一个数的情况下,个数比前者少是不会发生的
    while(r<=n){//前缀和不超过n
        if(brr[r]-brr[l]<k){//是判断前r-l个和是否大于k
            r++;//表明前r-l个和小于k,r需要后移
            continue;
        }
        cnt+=(n-r)+1;
        //如果前r-l个和大于k的话,意味着剩下n-r个数都满足大于k,加+1是因为当前前缀和也是满足的
        l++;//此时已经算完了前r个了,应该判断前r-l个和
    }
    //因为第一遍已经把1->r个数判断完毕,所以第二个数及其以后数就不用考虑它前面的数了
    cout<<cnt<<endl;
    return 0;
}


C:\Qt\Qt5.3.1\5.3\mingw482_32\include\QtCore\qvector.h:229: error: within this context new (from++) T(); ^#ifndef QVECTOR_H #define QVECTOR_H #include <QtCore/qalgorithms.h> #include <QtCore/qiterator.h> #include <QtCore/qlist.h> #include <QtCore/qrefcount.h> #include <QtCore/qarraydata.h> #include <iterator> #include <vector> #include <stdlib.h> #include <string.h> #ifdef Q_COMPILER_INITIALIZER_LISTS #include <initializer_list> #endif #include <algorithm> QT_BEGIN_NAMESPACE class QRegion; template <typename T> class QVector { typedef QTypedArrayData<T> Data; Data *d; public: inline QVector() : d(Data::sharedNull()) { } explicit QVector(int size); QVector(int size, const T &t); inline QVector(const QVector<T> &v); inline ~QVector() { if (!d->ref.deref()) freeData(d); } QVector<T> &operator=(const QVector<T> &v); #ifdef Q_COMPILER_RVALUE_REFS inline QVector(QVector<T> &&other) : d(other.d) { other.d = Data::sharedNull(); } inline QVector<T> operator=(QVector<T> &&other) { qSwap(d, other.d); return *this; } #endif inline void swap(QVector<T> &other) { qSwap(d, other.d); } #ifdef Q_COMPILER_INITIALIZER_LISTS inline QVector(std::initializer_list<T> args); #endif bool operator==(const QVector<T> &v) const; inline bool operator!=(const QVector<T> &v) const { return !(*this == v); } inline int size() const { return d->size; } inline bool isEmpty() const { return d->size == 0; } void resize(int size); inline int capacity() const { return int(d->alloc); } void reserve(int size); inline void squeeze() { reallocData(d->size, d->size); if (d->capacityReserved) { // capacity reserved in a read only memory would be useless // this checks avoid writing to such memory. d->capacityReserved = 0; } } inline void detach(); inline bool isDetached() const { return !d->ref.isShared(); } #if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) return; if (!sharable) detach(); if (d == Data::unsharableEmpty()) { if (sharable) d = Data::sharedNull(); } else { d->ref.setSharable(sharable); } Q_ASSERT(d->ref.isSharable() == sharable); } #endif inline bool isSharedWith(const QVector<T> &other) const { return d == other.d; } inline T *data() { detach(); return d->begin(); } inline const T *data() const { return d->begin(); } inline const T *constData() const { return d->begin(); } void clear(); const T &at(int i) const; T &operator[](int i); const T &operator[](int i) const; void append(const T &t); void prepend(const T &t); void insert(int i, const T &t); void insert(int i, int n, const T &t); void replace(int i, const T &t); void remove(int i); void remove(int i, int n); inline void removeFirst() { Q_ASSERT(!isEmpty()); erase(d->begin()); } inline void removeLast(); inline T takeFirst() { Q_ASSERT(!isEmpty()); T r = first(); removeFirst(); return r; } inline T takeLast() { Q_ASSERT(!isEmpty()); T r = last(); removeLast(); return r; } QVector<T> &fill(const T &t, int size = -1); int indexOf(const T &t, int from = 0) const; int lastIndexOf(const T &t, int from = -1) const; bool contains(const T &t) const; int count(const T &t) const; // QList compatibility void removeAt(int i) { remove(i); } int length() const { return size(); } T takeAt(int i) { T t = at(i); remove(i); return t; } // STL-style typedef typename Data::iterator iterator; typedef typename Data::const_iterator const_iterator; #if !defined(QT_STRICT_ITERATORS) || defined(Q_QDOC) inline iterator begin() { detach(); return d->begin(); } inline const_iterator begin() const { return d->constBegin(); } inline const_iterator cbegin() const { return d->constBegin(); } inline const_iterator constBegin() const { return d->constBegin(); } inline iterator end() { detach(); return d->end(); } inline const_iterator end() const { return d->constEnd(); } inline const_iterator cend() const { return d->constEnd(); } inline const_iterator constEnd() const { return d->constEnd(); } #else inline iterator begin(iterator = iterator()) { detach(); return d->begin(); } inline const_iterator begin(const_iterator = const_iterator()) const { return d->constBegin(); } inline const_iterator cbegin(const_iterator = const_iterator()) const { return d->constBegin(); } inline const_iterator constBegin(const_iterator = const_iterator()) const { return d->constBegin(); } inline iterator end(iterator = iterator()) { detach(); return d->end(); } inline const_iterator end(const_iterator = const_iterator()) const { return d->constEnd(); } inline const_iterator cend(const_iterator = const_iterator()) const { return d->constEnd(); } inline const_iterator constEnd(const_iterator = const_iterator()) const { return d->constEnd(); } #endif iterator insert(iterator before, int n, const T &x); inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); } iterator erase(iterator begin, iterator end); inline iterator erase(iterator pos) { return erase(pos, pos+1); } // more Qt inline int count() const { return d->size; } inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); } inline const T &first() const { Q_ASSERT(!isEmpty()); return *begin(); } inline T& last() { Q_ASSERT(!isEmpty()); return *(end()-1); } inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); } inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; } inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; } QVector<T> mid(int pos, int len = -1) const; T value(int i) const; T value(int i, const T &defaultValue) const; // STL compatibility typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef qptrdiff difference_type; typedef iterator Iterator; typedef const_iterator ConstIterator; typedef int size_type; inline void push_back(const T &t) { append(t); } inline void push_front(const T &t) { prepend(t); } void pop_back() { removeLast(); } void pop_front() { removeFirst(); } inline bool empty() const { return d->size == 0; } inline T& front() { return first(); } inline const_reference front() const { return first(); } inline reference back() { return last(); } inline const_reference back() const { return last(); } // comfort QVector<T> &operator+=(const QVector<T> &l); inline QVector<T> operator+(const QVector<T> &l) const { QVector n = *this; n += l; return n; } inline QVector<T> &operator+=(const T &t) { append(t); return *this; } inline QVector<T> &operator<< (const T &t) { append(t); return *this; } inline QVector<T> &operator<<(const QVector<T> &l) { *this += l; return *this; } QList<T> toList() const; static QVector<T> fromList(const QList<T> &list); static inline QVector<T> fromStdVector(const std::vector<T> &vector) { QVector<T> tmp; tmp.reserve(int(vector.size())); std::copy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; } inline std::vector<T> toStdVector() const { std::vector<T> tmp; tmp.reserve(size()); std::copy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; } private: friend class QRegion; // Optimization for QRegion::rects() void reallocData(const int size, const int alloc, QArrayData::AllocationOptions options = QArrayData::Default); void reallocData(const int sz) { reallocData(sz, d->alloc); } void freeData(Data *d); void defaultConstruct(T *from, T *to); void copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom); void destruct(T *from, T *to); bool isValidIterator(const iterator &i) const { return (i <= d->end()) && (d->begin() <= i); } class AlignmentDummy { Data header; T array[1]; }; }; #ifdef Q_CC_MSVC // behavior change: an object of POD type constructed with an initializer of the form () // will be default-initialized # pragma warning ( push ) # pragma warning ( disable : 4345 ) #endif template <typename T> void QVector<T>::defaultConstruct(T *from, T *to) { if (QTypeInfo<T>::isComplex) { while (from != to) { new (from++) T(); } } else { ::memset(static_cast<void *>(from), 0, (to - from) * sizeof(T)); } } #ifdef Q_CC_MSVC # pragma warning ( pop ) #endif template <typename T> void QVector<T>::copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom) { if (QTypeInfo<T>::isComplex) { while (srcFrom != srcTo) new (dstFrom++) T(*srcFrom++); } else { ::memcpy(static_cast<void *>(dstFrom), static_cast<const void *>(srcFrom), (srcTo - srcFrom) * sizeof(T)); } } #if defined(Q_CC_MSVC) #pragma warning( push ) #pragma warning( disable : 4127 ) // conditional expression is constant #endif template <typename T> void QVector<T>::destruct(T *from, T *to) { if (QTypeInfo<T>::isComplex) { while (from != to) { from++->~T(); } } } #if defined(Q_CC_MSVC) #pragma warning( pop ) #endif template <typename T> inline QVector<T>::QVector(const QVector<T> &v) { if (v.d->ref.ref()) { d = v.d; } else { if (v.d->capacityReserved) { d = Data::allocate(v.d->alloc); d->capacityReserved = true; } else { d = Data::allocate(v.d->size); } if (d->alloc) { copyConstruct(v.d->begin(), v.d->end(), d->begin()); d->size = v.d->size; } } } template <typename T> void QVector<T>::detach() { if (!isDetached()) { #if QT_SUPPORTS(UNSHARABLE_CONTAINERS) if (!d->alloc) d = Data::unsharableEmpty(); else #endif reallocData(d->size, int(d->alloc)); } Q_ASSERT(isDetached()); } template <typename T> void QVector<T>::reserve(int asize) { if (asize > int(d->alloc)) reallocData(d->size, asize); if (isDetached()) d->capacityReserved = 1; Q_ASSERT(capacity() >= asize); } template <typename T> void QVector<T>::resize(int asize) { int newAlloc; const int oldAlloc = int(d->alloc); QArrayData::AllocationOptions opt; if (asize > oldAlloc) { // there is not enough space newAlloc = asize; opt = QArrayData::Grow; } else if (!d->capacityReserved && asize < d->size && asize < (oldAlloc >> 1)) { // we want to shrink newAlloc = asize; opt = QArrayData::Grow; } else { newAlloc = oldAlloc; } reallocData(asize, newAlloc, opt); } template <typename T> inline void QVector<T>::clear() { *this = QVector<T>(); } template <typename T> inline const T &QVector<T>::at(int i) const { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::at", "index out of range"); return d->begin()[i]; } template <typename T> inline const T &QVector<T>::operator[](int i) const { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range"); return d->begin()[i]; } template <typename T> inline T &QVector<T>::operator[](int i) { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range"); return data()[i]; } template <typename T> inline void QVector<T>::insert(int i, const T &t) { Q_ASSERT_X(i >= 0 && i <= d->size, "QVector<T>::insert", "index out of range"); insert(begin() + i, 1, t); } template <typename T> inline void QVector<T>::insert(int i, int n, const T &t) { Q_ASSERT_X(i >= 0 && i <= d->size, "QVector<T>::insert", "index out of range"); insert(begin() + i, n, t); } template <typename T> inline void QVector<T>::remove(int i, int n) { Q_ASSERT_X(i >= 0 && n >= 0 && i + n <= d->size, "QVector<T>::remove", "index out of range"); erase(d->begin() + i, d->begin() + i + n); } template <typename T> inline void QVector<T>::remove(int i) { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::remove", "index out of range"); erase(d->begin() + i, d->begin() + i + 1); } template <typename T> inline void QVector<T>::prepend(const T &t) { insert(begin(), 1, t); } template <typename T> inline void QVector<T>::replace(int i, const T &t) { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::replace", "index out of range"); const T copy(t); data()[i] = copy; } template <typename T> QVector<T> &QVector<T>::operator=(const QVector<T> &v) { if (v.d != d) { QVector<T> tmp(v); tmp.swap(*this); } return *this; } template <typename T> QVector<T>::QVector(int asize) { Q_ASSERT_X(asize >= 0, "QVector::QVector", "Size must be greater than or equal to 0."); if (Q_LIKELY(asize > 0)) { d = Data::allocate(asize); d->size = asize; defaultConstruct(d->begin(), d->end()); } else { d = Data::sharedNull(); } } template <typename T> QVector<T>::QVector(int asize, const T &t) { Q_ASSERT_X(asize >= 0, "QVector::QVector", "Size must be greater than or equal to 0."); if (asize > 0) { d = Data::allocate(asize); d->size = asize; T* i = d->end(); while (i != d->begin()) new (--i) T(t); } else { d = Data::sharedNull(); } } #ifdef Q_COMPILER_INITIALIZER_LISTS template <typename T> QVector<T>::QVector(std::initializer_list<T> args) { if (args.size() > 0) { d = Data::allocate(args.size()); // std::initializer_list<T>::iterator is guaranteed to be // const T* ([support.initlist]/1), so can be memcpy'ed away from by copyConstruct copyConstruct(args.begin(), args.end(), d->begin()); d->size = int(args.size()); } else { d = Data::sharedNull(); } } #endif template <typename T> void QVector<T>::freeData(Data *x) { destruct(x->begin(), x->end()); Data::deallocate(x); } template <typename T> void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::AllocationOptions options) { Q_ASSERT(asize >= 0 && asize <= aalloc); Data *x = d; const bool isShared = d->ref.isShared(); if (aalloc != 0) { if (aalloc != int(d->alloc) || isShared) { QT_TRY { // allocate memory x = Data::allocate(aalloc, options); Q_CHECK_PTR(x); // aalloc is bigger then 0 so it is not [un]sharedEmpty #if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Q_ASSERT(x->ref.isSharable() || options.testFlag(QArrayData::Unsharable)); #endif Q_ASSERT(!x->ref.isStatic()); x->size = asize; T *srcBegin = d->begin(); T *srcEnd = asize > d->size ? d->end() : d->begin() + asize; T *dst = x->begin(); if (QTypeInfo<T>::isStatic || (isShared && QTypeInfo<T>::isComplex)) { // we can not move the data, we need to copy construct it while (srcBegin != srcEnd) { new (dst++) T(*srcBegin++); } } else { ::memcpy(static_cast<void *>(dst), static_cast<void *>(srcBegin), (srcEnd - srcBegin) * sizeof(T)); dst += srcEnd - srcBegin; // destruct unused / not moved data if (asize < d->size) destruct(d->begin() + asize, d->end()); } if (asize > d->size) { // construct all new objects when growing QT_TRY { defaultConstruct(dst, x->end()); } QT_CATCH (...) { // destruct already copied objects destruct(x->begin(), dst); QT_RETHROW; } } } QT_CATCH (...) { Data::deallocate(x); QT_RETHROW; } x->capacityReserved = d->capacityReserved; } else { Q_ASSERT(int(d->alloc) == aalloc); // resize, without changing allocation size Q_ASSERT(isDetached()); // can be done only on detached d Q_ASSERT(x == d); // in this case we do not need to allocate anything if (asize <= d->size) { destruct(x->begin() + asize, x->end()); // from future end to current end } else { defaultConstruct(x->end(), x->begin() + asize); // from current end to future end } x->size = asize; } } else { x = Data::sharedNull(); } if (d != x) { if (!d->ref.deref()) { if (QTypeInfo<T>::isStatic || !aalloc || (isShared && QTypeInfo<T>::isComplex)) { // data was copy constructed, we need to call destructors // or if !alloc we did nothing to the old 'd'. freeData(d); } else { Data::deallocate(d); } } d = x; } Q_ASSERT(d->data()); Q_ASSERT(uint(d->size) <= d->alloc); #if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Q_ASSERT(d != Data::unsharableEmpty()); #endif Q_ASSERT(aalloc ? d != Data::sharedNull() : d == Data::sharedNull()); Q_ASSERT(d->alloc >= uint(aalloc)); Q_ASSERT(d->size == asize); } template<typename T> Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i) const { if (uint(i) >= uint(d->size)) { return T(); } return d->begin()[i]; } template<typename T> Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i, const T &defaultValue) const { return uint(i) >= uint(d->size) ? defaultValue : d->begin()[i]; } template <typename T> void QVector<T>::append(const T &t) { const T copy(t); const bool isTooSmall = uint(d->size + 1) > d->alloc; if (!isDetached() || isTooSmall) { QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default); reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt); } if (QTypeInfo<T>::isComplex) new (d->end()) T(copy); else *d->end() = copy; ++d->size; } template <typename T> void QVector<T>::removeLast() { Q_ASSERT(!isEmpty()); Q_ASSERT(d->alloc); if (!d->ref.isShared()) { --d->size; if (QTypeInfo<T>::isComplex) (d->data() + d->size)->~T(); } else { reallocData(d->size - 1); } } template <typename T> typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t) { Q_ASSERT_X(isValidIterator(before), "QVector::insert", "The specified iterator argument 'before' is invalid"); int offset = std::distance(d->begin(), before); if (n != 0) { const T copy(t); if (!isDetached() || d->size + n > int(d->alloc)) reallocData(d->size, d->size + n, QArrayData::Grow); if (QTypeInfo<T>::isStatic) { T *b = d->end(); T *i = d->end() + n; while (i != b) new (--i) T; i = d->end(); T *j = i + n; b = d->begin() + offset; while (i != b) *--j = *--i; i = b+n; while (i != b) *--i = copy; } else { T *b = d->begin() + offset; T *i = b + n; memmove(i, b, (d->size - offset) * sizeof(T)); while (i != b) new (--i) T(copy); } d->size += n; } return d->begin() + offset; } template <typename T> typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend) { Q_ASSERT_X(isValidIterator(abegin), "QVector::erase", "The specified iterator argument 'abegin' is invalid"); Q_ASSERT_X(isValidIterator(aend), "QVector::erase", "The specified iterator argument 'aend' is invalid"); const int itemsToErase = aend - abegin; if (!itemsToErase) return abegin; Q_ASSERT(abegin >= d->begin()); Q_ASSERT(aend <= d->end()); Q_ASSERT(abegin <= aend); const int itemsUntouched = abegin - d->begin(); // FIXME we could do a proper realloc, which copy constructs only needed data. // FIXME we ara about to delete data maybe it is good time to shrink? // FIXME the shrink is also an issue in removeLast, that is just a copy + reduce of this. if (d->alloc) { detach(); abegin = d->begin() + itemsUntouched; aend = abegin + itemsToErase; if (QTypeInfo<T>::isStatic) { iterator moveBegin = abegin + itemsToErase; iterator moveEnd = d->end(); while (moveBegin != moveEnd) { if (QTypeInfo<T>::isComplex) static_cast<T *>(abegin)->~T(); new (abegin++) T(*moveBegin++); } if (abegin < d->end()) { // destroy rest of instances destruct(abegin, d->end()); } } else { destruct(abegin, aend); memmove(abegin, aend, (d->size - itemsToErase - itemsUntouched) * sizeof(T)); } d->size -= itemsToErase; } return d->begin() + itemsUntouched; } template <typename T> bool QVector<T>::operator==(const QVector<T> &v) const { if (d->size != v.d->size) return false; if (d == v.d) return true; T* b = d->begin(); T* i = b + d->size; T* j = v.d->end(); while (i != b) if (!(*--i == *--j)) return false; return true; } template <typename T> QVector<T> &QVector<T>::fill(const T &from, int asize) { const T copy(from); resize(asize < 0 ? d->size : asize); if (d->size) { T *i = d->end(); T *b = d->begin(); while (i != b) *--i = copy; } return *this; } template <typename T> QVector<T> &QVector<T>::operator+=(const QVector &l) { uint newSize = d->size + l.d->size; const bool isTooSmall = newSize > d->alloc; if (!isDetached() || isTooSmall) { QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default); reallocData(d->size, isTooSmall ? newSize : d->alloc, opt); } if (d->alloc) { T *w = d->begin() + newSize; T *i = l.d->end(); T *b = l.d->begin(); while (i != b) { if (QTypeInfo<T>::isComplex) new (--w) T(*--i); else *--w = *--i; } d->size = newSize; } return *this; } template <typename T> int QVector<T>::indexOf(const T &t, int from) const { if (from < 0) from = qMax(from + d->size, 0); if (from < d->size) { T* n = d->begin() + from - 1; T* e = d->end(); while (++n != e) if (*n == t) return n - d->begin(); } return -1; } template <typename T> int QVector<T>::lastIndexOf(const T &t, int from) const { if (from < 0) from += d->size; else if (from >= d->size) from = d->size-1; if (from >= 0) { T* b = d->begin(); T* n = d->begin() + from + 1; while (n != b) { if (*--n == t) return n - b; } } return -1; } template <typename T> bool QVector<T>::contains(const T &t) const { T* b = d->begin(); T* i = d->end(); while (i != b) if (*--i == t) return true; return false; } template <typename T> int QVector<T>::count(const T &t) const { int c = 0; T* b = d->begin(); T* i = d->end(); while (i != b) if (*--i == t) ++c; return c; } template <typename T> Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int len) const { if (len < 0) len = size() - pos; if (pos == 0 && len == size()) return *this; if (pos + len > size()) len = size() - pos; QVector<T> copy; copy.reserve(len); for (int i = pos; i < pos + len; ++i) copy += at(i); return copy; } template <typename T> Q_OUTOFLINE_TEMPLATE QList<T> QVector<T>::toList() const { QList<T> result; result.reserve(size()); for (int i = 0; i < size(); ++i) result.append(at(i)); return result; } template <typename T> Q_OUTOFLINE_TEMPLATE QVector<T> QList<T>::toVector() const { QVector<T> result(size()); for (int i = 0; i < size(); ++i) result[i] = at(i); return result; } template <typename T> QVector<T> QVector<T>::fromList(const QList<T> &list) { return list.toVector(); } template <typename T> QList<T> QList<T>::fromVector(const QVector<T> &vector) { return vector.toList(); } Q_DECLARE_SEQUENTIAL_ITERATOR(Vector) Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Vector) /* ### Qt 5: ### This needs to be removed for next releases of Qt. It is a workaround for vc++ because ### Qt exports QPolygon and QPolygonF that inherit QVector<QPoint> and ### QVector<QPointF> respectively. */ #ifdef Q_CC_MSVC QT_BEGIN_INCLUDE_NAMESPACE #include <QtCore/qpoint.h> QT_END_INCLUDE_NAMESPACE #if defined(QT_BUILD_CORE_LIB) #define Q_TEMPLATE_EXTERN #else #define Q_TEMPLATE_EXTERN extern #endif Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPointF>; Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPoint>; #endif QT_END_NAMESPACE #endif // QVECTOR_H用QT creator 5.3.1写修改此问题
06-11
import numpy as np import pandas as pd from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score from keras.models import Sequential from keras.layers import LSTM, Dense import time # ------------------------------- # 1. 加载数据 # ------------------------------- data = pd.read_excel(r"C:/Users/12203/Desktop/空气质量数据全new.xlsx") # 创建时间索引(可选) index = pd.date_range(start='2021-01-01', periods=len(data), freq='D') data.index = index # 定义分箱边界和标签 bins = [0, 50, 100, 150, 200, 300, float('inf')] labels = ['Excellent', 'Good', 'Light pollution', 'Moderate pollution', 'Heavy pollution', 'Severe pollution'] data['Air Quality'] = pd.cut(data['AQI'], bins=bins, labels=labels, right=True, include_lowest=True) # ------------------------------- # 2. 提取特征与目标变量 # ------------------------------- features = ['PM2.5', 'PM10', 'NO2', 'SO2', 'CO', 'O3_8h'] target = 'AQI' X = data[features].values # shape: (n_samples, 6) y = data[target].values # shape: (n_samples,) # ------------------------------- # 3. 归一化处理 # ------------------------------- scaler_X = MinMaxScaler() scaler_y = MinMaxScaler() X_scaled = scaler_X.fit_transform(X) y_scaled = scaler_y.fit_transform(y.reshape(-1, 1)).flatten() # ------------------------------- # 4. 划分训练集和测试集(最后365天为测试集) # ------------------------------- train_size = len(X_scaled) - 365 X_train_full = X_scaled[:train_size] y_train_full = y_scaled[:train_size] X_test_full = X_scaled[train_size:] y_test_full = y_scaled[train_size:] print(f"训练集大小: {len(X_train_full)}") print(f"测试集大小: {len(X_test_full)}") # ------------------------------- # 5. 构造时序样本函数(✅ 包含 x_t) # ------------------------------- def create_dataset_with_xt(X, y, sequence_length): """ 构造 LSTM 输入数据,其中每个样本包含 [x_{t-n+1}, ..., x_{t}] 共 sequence_length 天, 用于预测 y_t(第 t 天的 AQI)。 """ if sequence_length >= len(X): return np.array([]), np.array([]) n_samples = len(X) - sequence_length + 1 # 可构造的样本数 n_features = X.shape[1] X_seq = np.zeros((n_samples, sequence_length, n_features)) y_seq = np.zeros((n_samples,)) for i in range(sequence_length - 1, len(X)): start_idx = i - sequence_length + 1 end_idx = i + 1 X_seq[i - sequence_length + 1] = X[start_idx:end_idx] # x_{t-seq_len+1} ~ x_t y_seq[i - sequence_length + 1] = y[i] # y_t return X_seq, y_seq # ------------------------------- # 6. 实验参数设置 # ------------------------------- sequence_lengths = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] units = 64 batch_size = 32 results = {} # ------------------------------- # 7. 遍历不同 sequence_length 训练模型 # ------------------------------- for seq_len in sequence_lengths: print(f"\n🚀 Training with sequence_length = {seq_len} (including x_t)") # 构建训练/测试数据集(包含 x_t) X_train_pad, y_train_pad = create_dataset_with_xt(X_train_full, y_train_full, seq_len) X_test_pad, y_test_pad = create_dataset_with_xt(X_test_full, y_test_full, seq_len) if len(X_train_pad) == 0 or len(X_test_pad) == 0: print("❌ Not enough samples after padding.") continue # 构建 LSTM 模型 model = Sequential([ LSTM(units, activation='relu', return_sequences=True, input_shape=(seq_len, X_train_full.shape[1])), LSTM(units, activation='relu'), Dense(1) ]) model.compile(optimizer='adam', loss='mse') # 训练并计时 start_time = time.time() model.fit(X_train_pad, y_train_pad, epochs=200, batch_size=batch_size, verbose=0) end_time = time.time() # 在训练集上预测 pred_scaled = model.predict(X_train_pad, verbose=0) pred_inv = scaler_y.inverse_transform(pred_scaled).flatten() true_inv = scaler_y.inverse_transform(y_train_pad.reshape(-1, 1)).flatten() # 计算评估指标 rmse = np.sqrt(mean_squared_error(true_inv, pred_inv)) mae = mean_absolute_error(true_inv, pred_inv) r2 = r2_score(true_inv, pred_inv) # 计算调整后 R²(防止过拟合惩罚) n = len(true_inv) k = seq_len * X.shape[1] # 参数量级估算(实际LSTM更多,这里仅粗略比较趋势) if k >= n - 1 or n <= k + 1: r2_adj = float('nan') else: r2_adj = 1 - (1 - r2) * (n - 1) / (n - k - 1) # 存储结果 results[seq_len] = { "RMSE": rmse, "MAE": mae, "R2": r2, "Adjusted_R2": r2_adj, "Training Time (s)": end_time - start_time } # ------------------------------- # 8. 输出结果 # ------------------------------- print("\n" + "="*60) print("📊 最终结果汇总(包含 x_t)") print("="*60) for seq_len, res in results.items(): print(f"Sequence Length: {seq_len}") print(f" RMSE: {res['RMSE']:>8.4f}") print(f" MAE: {res['MAE']:>8.4f}") print(f" R²: {res['R2']:>8.4f}") print(f" Adjusted R²: {res['Adjusted_R2']:>8.4f}" if not np.isnan(res["Adjusted_R2"]) else " Adjusted R²: NaN") print(f" Training Time: {res['Training Time (s)']:>8.2f}s") print("-" * 40) # ------------------------------- # 9. 可视化最优 sequence_length 性能对比 # ------------------------------- import matplotlib.pyplot as plt seq_lens = list(results.keys()) rmses = [results[l]['RMSE'] for l in seq_lens] r2s_adj = [results[l]['Adjusted_R2'] for l in seq_lens] fig, ax1 = plt.subplots(figsize=(10, 6)) ax1.plot(seq_lens, rmses, marker='o', color='red', label='Train RMSE') ax1.set_xlabel('Sequence Length (days)') ax1.set_ylabel('Train RMSE', color='red') ax1.tick_params(axis='y', labelcolor='red') ax1.grid(True, alpha=0.3) ax2 = ax1.twinx() ax2.plot(seq_lens, r2s_adj, marker='s', color='green', label='Adjusted $R^2$') ax2.set_ylabel('Adjusted $R^2$', color='green') ax2.tick_params(axis='y', labelcolor='green') plt.title('Model Performance vs Sequence Length (Including $x_t$)') fig.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05), ncol=2) plt.tight_layout() plt.show() 修改以上代码,利用随机搜索得到sequence_lengths = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]batch_sizes = [1, 8, 16, 32, 64, 128, 256]units_list = [8, 16, 32, 64, 128, 256] 以调整后的R2最大为目标的最优参数
最新发布
10-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值