用于比较字符串

时间:2017-03-22 17:41:02

标签: c++

我想问你一个问题,但首先我会解释一下......

我在矢量人物中有一个结构SPerson。

typedef struct SPERSON {
   string name;
   string address;
   string birthcertificatenumber;
} SPerson;
std::vector<SPerson> People;
People.resize(100);
counter = 0;

有一个类是添加新人的功能

bool NewPerson(const string & name, const string & address, const string & birthcertifikatenumber)
{
   SPerson sPerson;
   sPerson.name = name;
   sPerson.address = address;
   sPerson.birthcertificatenumber = birthcertificatenumber;
   People[counter] = sPerson;
   counter++;
 return true;
}

在这个功能中,我需要检查是否已经有一个人具有相同的姓名&#34;和&#34;地址或有出生证明号的人

我需要以logharitmicaly搜索它,而不是线性搜索。

我在NewPerson中使用了下面的函数,它按照我想要的方式运行,但是当有大量数据时,它很慢,我需要更快。我听说过lower_bound函数 对于二进制搜索,但我不知道如何将它应用于我的情况。你能给我一个建议吗?谢谢。

 auto it = find_if(begin(People), end(People), [=] (SPerson const& f) { 
    return (((strcasecmp(name.c_str(), f.name.c_str()) == 0) and (strcasecmp(address.c_str(), f.address.c_str()) == 0)) or (f.birthcertifikatenumber == birthcertifikatenumber));  
    });
bool found = (it != end(People)); 
if (found == true)
{    
    return false;
}

@Slava:谢谢,它实际上运作得很好。

我在输入中有这些记录:

  • 姓名:约翰,地址:eee,出生日期证书:abcdef
  • 姓名:Pierre,地址:aaa,出生日期证书:123456
  • 姓名:Jean,地址:bbb,出生日期证书:1234
  • 姓名:Peter,地址:ccc,出生日期证明:ABCDEF

按照这样的方式对birt date cerfificate进行排序:

  • 姓名:Jean,地址:bbb,出生日期证书:1234
  • 姓名:Pierre,地址:aaa,出生日期证书:123456
  • 姓名:Peter,地址:ccc,出生日期证明:ABCDEF
  • 姓名:约翰,地址:eee,出生日期证书:abcdef

通过名称和地址,它的排序如下:

  • 姓名:Jean,地址:bbb,出生日期证书:1234
  • 姓名:约翰,地址:eee,出生日期证书:abcdef
  • 姓名:Peter,地址:ccc,出生日期证明:ABCDEF
  • 姓名:Pierre,地址:aaa,出生日期证书:123456

太好了,谢谢。现在我想通过它的名字和地址或出生日期cerfificat找到一个人,所以我可以调用以下函数: ErasePerson(&#34; Peter&#34;,&#34; ccc&#34;); //用姓名和地址擦除此人 ErasePerson(&#34; 123456&#34); //通过出生日期证明来删除此人

我想使用O(log n),所以现在我想找到具体的人并将其删除。我不知道如何使用lower_bound函数。我尝试了一些东西,但没有成功。我不知道如何创建比较函数,如果我有正确的话。

 struct SPerson {
     string name;
     string address;
     string birthdatecertificate;
};   
std::vector<SPerson> VPeople;
std::vector<size_t> idxNameAddress;

bool People::ErasePerson(const string & name, const string & address)
{
   SPerson Person;
   Person.name = name;
   Person.address = address;
   Person.birthdatecertificate= ""; 

  std::lower_bound(idxNameAddress.begin(), idxNameAddress.end(), Person, cmpFunction);
return false;
}

3 个答案:

答案 0 :(得分:1)

std::lower_bound只能用于已排序的容器(否则,您将获得无效结果......没有警告/错误),而std::vector则不然。

最简单的方法是将元素存储在已排序的容器中。像std::setstd::map一样。然后,您的已排序容器将能够报告对象是否已存在非线性搜索算法。

这些容器将要求您提供比较运算符:

bool operator<(const SPERSON& left, const SPERSON& right )
{
    return left.name < right.name;
}

然后做:

std::set<SPERSON> People;

使用以下方法添加元素:

if ( People.find( sPerson ) == People.end() )
    People.insert( sPerson );
// else: item with same name already exists!

答案 1 :(得分:1)

首先,在C ++中完全没有typedef struct,只需定义你的结构:

struct SPerson {
   string name;
   string address;
   string birthcertificatenumber;
};
std::vector<SPerson> People;

与C不同,您可以使用struct名称而不使用关键字struct,因此该习惯用法是多余的。

现在,为了能够使用std::lower_bound,您的数据必须进行排序。由于您有2个不同的标准,因此您必须创建索引以加快查找速度:

std::vector<SPerson> People;
std::vector<size_t> idxNameAddress;
std::vector<size_t> idxBirthCertificate;

并且您需要在插入新人时更新索引:

bool insertPerson( const SPerson &p ) {
    const auto cmpNameAddress = []( size_t u1, size_t u2 ) {
         const SPerson &p1 = People[u1];
         const SPerson &p2 = People[u2];
         return std::tie( p1.name, p1.address ) < std::tie( p2.name, p2.address );
    }
    const auto cmpBirthSert = []( size_t u1, size_t u2 ) {
         const SPerson &p1 = People[u1];
         const SPerson &p2 = People[u2];
         return p1.birthcertificate < p2.birthcertificate;
    }
}
    size_t newId = People.size();
    People.push_back( p );
    auto p1 = std::equal_range( idxNameAddress.begin(), idxNameAddress.end(), newId, cmpNameAddress );
    auto p2 = std::equal_range( idxBirthCertificate.begin(), idxBirthCertificate.end(), newId, cmpBirthSert );

    if( p1.first != p1.second or p2.first != p2.second ) {
        People.pop_back();
        return false; // already there
    }
    idxNameAddress.insert( p1.first, newId );
    idxBirthCertificate.insert( p2.first, newId );
    return true;
}

答案 2 :(得分:0)

如果您的计划中的空格不是问题,则可以使用<file path="admin/model/customer/customer.php"> <operation> <!-- find the last }, which signify end of the class --> <search regex="true"> <![CDATA[ \}([^}]*?)$ ]]> </search> <add> <!-- add the new function --> <![CDATA[ public function getCustomerGroupTotalCustomers($customer_group_id) { $query = $this->db->query("SELECT COUNT(*) FROM " . DB_PREFIX . "customer WHERE customer_group_id = '" . (int)$customer_group_id . "'"); return $query->row['total']; } } ]]> </add> </operation> </file>

维护地图 m1 。每当您致电std::map时,请更新地图m1。

维护另一张地图 m2 。每当您致电NewPerson()时,请更新地图m2。

每次添加通话NewPerson()时,请拨打m1和m2的NewPerson()

find()是对数的。