2013-08-21 74 views
0

我制作了一个表单,用于收集随后发送到数据库的数据。检查向量中是否已经存在该值

数据库有2个表,其中一个是主表,另一个是主表,另一个表与它是一对多关系。

为了清楚起见,我将它们命名为:主表是Table1,子表是ElectricEnergy。

在表ElectricEnergy存储的能耗,通过几个月的一年,因此此表下面的模式:

ElectricEnergy < #ElectricEnergy_pk,$ Table1_pk,一月,二月,...,月,年>

在表格中,用户可以输入特定年份的数据。我会尽力来说明这个波纹管:

年份:2012

1月:20.5千瓦/小时

2月:250.32千瓦/小时

等。

填充表看起来像这样:

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

你是什么意思'std :: find'不处理最后一个元素?不,你不能修改'std :: set'的成员,但你可以'擦除'和'插入'一个新的。 –

+0

在下面的答案中,向我解释了为什么我关于std :: find的注释是错误的。谢谢你的评论波特先生。 – AlwaysLearningNewStuff

+0

@Jonathan Potther,我有一个问题,波特先生,关于双打的比较:我在网上读过一些地方,如果你比较两个双打(比如5,5和5,5),可能会因默认精度而出现错误。在我的问题中,年份是双倍的,但它没有小数,因为年份是整数。有可能会出现精确度问题,因为年份会是double类型的吗?谢谢。问候。 – AlwaysLearningNewStuff

回答

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()将迭代器返回到最后一个元素之后的元素。这就是为什么std :: find会忽略最后一个值(因为它已经超出了界限!)。

+0

你对std :: find的回答帮助我理解了我的错误。至于你的解决方案,我从来没有使用过lambda筛选器和find_if,所以我很难理解你的代码。在报告结果之前,我需要研究它。谢谢您的回答。 – AlwaysLearningNewStuff

+0

我有一个问题,凯斯基宁先生,关于双打的比较:我已经在网上阅读过某个地方,如果你比较两个双打(比如5,5和5,5),可能会因默认精度而出现错误。在我的问题中,年份是双倍的,但它没有小数,因为年份是整数。有可能会出现精确度问题,因为年份会是double类型的吗?谢谢。问候。 – AlwaysLearningNewStuff