0

データベースに送信されるデータを収集するフォームを作成しました。

データベースには 2 つのテーブルがあり、1 つはメインで、もう 1 つはそれと 1 対多の関係にあります。

わかりやすくするために、名前を付けます。メイン テーブルは Table1、子テーブルは ElectricEnergy です。

テーブルでは、ElectricEnergy は月と年のエネルギー消費量が格納されているため、テーブルには次のスキーマがあります。

電気エネルギー< #ElectricEnergy_pk, $Table1_pk, January,February, ...,December, Year>

フォームでは、ユーザーは特定の年のデータを入力できます。私はこれを次のように説明しようとします:

年: 2012

1月:20.5kW/h

2月: 250.32 kW/h

等々。

塗りつぶされたテーブルは次のようになります。

   YEAR | January | February | ... | December | Table1_pk | ElectricEnergy_pk |
   2012 |   20.5  |  250.32  | ... |   300.45 |      1    |     1             |
   2013 |   10.5  |  50.32   | ... |   300    |      1    |     2             |
   2012 |   50.5  |  150.32  | ... |   400.45 |      2    |     3             |

消費後の保管可能年数が不明なため、保管用に使用することにvectorしました。

ベクトルには配列を含めることができず、13 (12 か月 + 年) の配列が必要なので、フォーム データをベクトルに格納することにしました。

データには小数が含まれているため、ベクトル型はdoubleです。

ちょっとした説明:

vector<double> DataForSingleYear;
vector< vector<double> > CollectionOfYears.

データをベクター DataForSingleYear に正常にプッシュでき、これらすべての年をベクター CollectionOfYears に正常にプッシュできます。

問題は、ユーザーが同じ年を編集ボックスに何度も入力し、毎月の消費量に異なる値を追加して、値が重複することです。

次のようになります。

    YEAR | January | February | ... | December | Table1_pk | ElectricEnergy_pk |
    2012 |   20.5  |  250.32  | ... |   300.45 |      1    |     1             | 
    2012 |    2.5  |    50.32 | ... |   300    |      1    |     2(duplicate!) | 
    2013 |   10.5  |    50.32 | ... |   300    |      1    |     3             |
    2012 |   50.5  |  150.32  | ... |   400.45 |      2    |     4             |

私の質問は:

その値がベクトルに含まれているかどうかを確認するための最良の解決策は何ですか?

その質問が「大まかな」ものであることはわかっていますが、始めるためだけに少なくともアイデアを使用できます。

注: 年はベクトルの末尾にあるため、反復子の位置は 12 です。データベースに挿入されるデータの順序は重要ではありません。並べ替えの要件はまったくありません。

SOアーカイブをブラウズすることで、の使用に関する提案を見つけましたstd::setが、そのドキュメントには、挿入時に要素を変更できないと書かれており、それは私にとって受け入れられないオプションです.

std::findに面白そうです。

(この部分は、質問を編集したときに削除されました:

、しかし最後の要素を処理せず、年はベクトルの最後にあります。std::findそれは変わる可能性があり、私を助けることができるなら、私はその小さな調整を喜んで行います.

)

私の頭をよぎった唯一のことは、ベクトルをループして、値が既に存在するかどうかを確認することでしたが、それが最善の解決策ではないと思います:

    wchar_t temp[50];  
    GetDlgItemText( hwnd, IDC_EDIT1, temp, 50 );  // get the year 
    double year = _wtof( temp );  // convert it to double, 
                                  // so I can push it to the end of the vector 

    bool exists = false; // indicates if the year is already in the vector

   for( vector< vector <double> >::size_type i = 0;
        i < CollectionOfYears.size(); i++ )

      if( CollectionOfYears[ i ] [  ( vector<double>::size_type ) 12 ]  == year ) 
      {   
        exists = true; 
        break; 
      }

   if( !exists) 
     // store main vector in the database
   else
     MessageBox( ... , L”Error”, ... );

私は C++ と純粋な Win32 を使用して、MS Visual Studio で Windows XP に取り組んでいます。

追加のコードが必要な場合は、質問してください。投稿します。

ありがとうございました。

4

1 に答える 1

2

find_if とラムダ フィルターを使用する:

auto match = std::find_if(CollectionOfYears.begin(), CollectionOfYears.end(), 
                           [&year](v){ return year == v.last(); })
if (match == CollectionOfYears.end()){ //no value previously

}

これでも配列全体が反復されます。より効率的な検索が必要な場合は、配列をソートしたままにして、バイナリ検索または std::set を使用する必要があります。

vector::end() は、最後の要素の後の要素に iterator を返すことに注意してください。これが、std::find が最後の値を無視する理由です (既に範囲外であるためです!)。

于 2013-08-21T21:49:46.313 に答える