C++ 如何将std::map元素从一个减去到另一个并在C+中更新它+;

C++ 如何将std::map元素从一个减去到另一个并在C+中更新它+;,c++,stl,stdmap,c++03,C++,Stl,Stdmap,C++03,我试图从同一个std::map的每个其他元素中减去std::map的第一个元素。我找不到关于那个的任何东西。可能吗?例如: std::map<char,int> bar; bar['a']=11; //should be deleted from other elements bar['b']=22; bar['c']=33; bar['d']=44; std::cout << "bar contains:\n"; for (std::map<char,int&g

我试图从同一个std::map的每个其他元素中减去std::map的第一个元素。我找不到关于那个的任何东西。可能吗?例如:

std::map<char,int> bar;
bar['a']=11; //should be deleted from other elements
bar['b']=22;
bar['c']=33;
bar['d']=44;

std::cout << "bar contains:\n";
for (std::map<char,int>::iterator it=bar.begin(); it!=bar.end(); ++it)
{
  std::cout <<"key: " <<it->first << " Value=> " << it->second << '\n'; //can i delete here??
  //i want to delete value of a from value of b and update the value of b
}
//the new map should be look like as follows
//bar['a']=11; //or may be 0
//bar['b']=11;
//bar['c']=22;
//bar['d']=33;
std::映射栏;
条['a']=11//应该从其他元素中删除
条['b']=22;
条['c']=33;
条['d']=44;

std::coutC++11解决方案

你可以用这个

如果你想从它本身减去第一个元素,只需删除调用并捕获你想减去的值,因为你要修改第一个映射条目

auto const sub = bar.begin()->second;
std::for_each(bar.begin(), bar.end(), [&sub](std::pair<const char, int>& x){ x.second -= sub; });
auto const sub=bar.begin()->秒;
std::for_each(bar.begin()、bar.end()、[&sub](std::pair&x){x.second-=sub;});
C++03解决方案

从除第一个元素本身以外的所有元素中减去第一个元素

int value = bar.begin()->second;
std::map<char, int>::iterator it = bar.begin();
std::advance(it, 1);
for (; it != bar.end(); ++it)
{
    it->second -= value;
}
int value=bar.begin()->秒;
std::map::iterator it=bar.begin();
std::advance(it,1);
for(;it!=bar.end();++it)
{
它->第二-=值;
}
包含第一个元素

int value = bar.begin()->second;
for (std::map<char, int>::iterator it = bar.begin(); it != bar.end(); ++it)
{
    it->second -= value;
}
int value=bar.begin()->秒;
对于(std::map::iterator it=bar.begin();it!=bar.end();++it)
{
它->第二-=值;
}

您只需在映射上循环,并从每个元素中减去与“first”键关联的值,将结果存储回同一元素中。一种方法如下所示:

现场示范

#包括
#包括
int main(){
//设置问题。。。
std::mapfoo;
foo['a']=11;
foo['b']=22;
foo['c']=33;
foo['d']=44;
//获取“a”键的值。。。
常量int值=foo['a'];
//从每个元素中减去该值。。。
用于(自动元素:foo(&E){
element.second-=值;
}
//输出映射以验证结果。。。
用于(自动元素:foo(&E){

std::cout您可以使用标准算法
std::for\u头
中声明的每个

<>如果你的编译器支持C++ 2014,那么代码看起来就像

#include <iostream>
#include <map>
#include <algorithm>
#include <iterator>

int main() 
{
    std::map<char, int> bar;

    bar['a'] = 11;
    bar['b'] = 22;
    bar['c'] = 33;
    bar['d'] = 44;

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;

    if ( !bar.empty() )
    {        
        std::for_each( std::next( bar.begin() ), bar.end(), 
                       [value = ( *bar.begin() ).second] ( auto &p ) { p.second -= value; } );
    }            

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;
}    
if ( !bar.empty() )
{
    auto value = ( *bar.begin() ).second;
    std::for_each( std::next( bar.begin() ), bar.end(), 
                   [value] ( std::pair<const char, int> &p ) { p.second -= value; } );
} 
<>如果你的编译器只支持C++ 2011,那么程序中的主循环看起来像

#include <iostream>
#include <map>
#include <algorithm>
#include <iterator>

int main() 
{
    std::map<char, int> bar;

    bar['a'] = 11;
    bar['b'] = 22;
    bar['c'] = 33;
    bar['d'] = 44;

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;

    if ( !bar.empty() )
    {        
        std::for_each( std::next( bar.begin() ), bar.end(), 
                       [value = ( *bar.begin() ).second] ( auto &p ) { p.second -= value; } );
    }            

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;
}    
if ( !bar.empty() )
{
    auto value = ( *bar.begin() ).second;
    std::for_each( std::next( bar.begin() ), bar.end(), 
                   [value] ( std::pair<const char, int> &p ) { p.second -= value; } );
} 
if(!bar.empty())
{
自动值=(*bar.begin()).second;
std::for_each(std::next(bar.begin()),bar.end(),
[value](std::pair&p){p.second-=value;});
} 
例如,可以使用基于范围的for循环来实现这一点

#include <iostream>
#include <map>

int main() 
{
    std::map<char, int> bar;

    bar['a'] = 11;
    bar['b'] = 22;
    bar['c'] = 33;
    bar['d'] = 44;

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;

    if ( !bar.empty() )
    {        
        auto value = ( *bar.begin() ).second;
        bool first = true;
        for ( auto &p : bar )
        {
            if ( first ) first = !first;
            else p.second -= value;
        }
    }

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;
}    
#包括
#包括
int main()
{
地图条;
条['a']=11;
条['b']=22;
条['c']=33;
条['d']=44;
用于(常数自动和p:bar)
{
std::cout
int value=bar.begin()->秒;
for(std::map::reverse_迭代器it=bar.rbegin();it!=bar.rend();it++){
它->秒-=bar.begin()->秒;
}
bar.begin()->second=值;

你在循环中尝试过
it->second=it->second-bar['a']
吗?@tobi303,不会
bar.begin()->第二个
比假设第一个键是
'a'
?@jonathan据我所知,地图通常并不意味着元素的任何特定顺序,因此对我来说,通过它的键而不是它在地图中的位置来识别元素似乎更自然。无论如何,这取决于它应该如何使用。我可以想象gine用例,其中
bar.begin()
'a'
起作用的情况一样,都更有意义better@tobi303,不,一个
std::map
是非常明确的顺序,这是它的核心属性之一。顺序非常具体,由第三个模板参数决定。另一方面,
std::unordered_map
并不意味着任何特定的或不确定的属性dering(线索在名字里!)OP非常清楚地说“减去第一个元素”,这就是
bar.begin()
@JonathanWakely()所指的元素,好的,谢谢你的澄清。不过我不会称之为“更好”,而是“更一般”(请注意,他还清楚地说明了第一个元素实际上是一个“a”。我知道,这是一个令人毛骨悚然的元素,所以无需担心……)通过你的
it=bar.rbegin();it!=bar.rend();it++)
,你可以从所有元素中减去第一个元素(即将其值设置为0),但问题是“从其他元素中减去std::map的第一个元素”(突出显示我的元素)。是的,在问题中,说//或可能是0,所以我不只是将begin()设为0
const int*value=nullptr;(auto&elt:foo)if(value)elt.second-=value;else value=&elt.second;
如果第一个元素的键不是
'a'
?@JonathanWakely我的答案使用了问题中的信息。根据其他情况进行的修改留给读者作为练习,读者应该有足够的能力认识到这一点,并以此为例学习inspi定量,而不是他们问题的复制粘贴解决方案。我想说的是,对于一个映射,你更可能要减去“与已知键相关联的值”,而不是减去“与基于
运算符定义的第一个元素相关联的值”
bar.begin()->second
而不是
(*bar.begin()).second
?如果Stepanov不希望我们使用
运算符->
,他就不会给我们了。@Jonathan Wakely它们是相同的两种形式。你可以选择你喜欢的任何形式。如果我使用_each和std::next,编译器会显示一个错误,但是为什么?错误说--“next”不是“std”的成员,尽管标题是相同的像你一样@CoryKramer@NazmulHossain你使用的编译器有C++11功能吗?我使用的是g++(Debian 4.4.5-8)4.4.5版本。我想我没有权限更新它!!@CoryKramer。任何其他可能的使用方法。感谢您的快速回复。@NazmulHossain,那么您将无法访问这些C++11功能。请参阅我的编辑以获取C++03方法。@NazmulHossain您还应该尝试麻烦您的计算机管理员升级您的gcc版本,您就是我们的版本
{ a, 11 } { b, 22 } { c, 33 } { d, 44 } 
{ a, 11 } { b, 11 } { c, 22 } { d, 33 } 
if ( !bar.empty() )
{
    auto value = ( *bar.begin() ).second;
    std::for_each( std::next( bar.begin() ), bar.end(), 
                   [value] ( std::pair<const char, int> &p ) { p.second -= value; } );
} 
#include <iostream>
#include <map>

int main() 
{
    std::map<char, int> bar;

    bar['a'] = 11;
    bar['b'] = 22;
    bar['c'] = 33;
    bar['d'] = 44;

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;

    if ( !bar.empty() )
    {        
        auto value = ( *bar.begin() ).second;
        bool first = true;
        for ( auto &p : bar )
        {
            if ( first ) first = !first;
            else p.second -= value;
        }
    }

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;
}    
#include <iostream>
#include <map>
#include <algorithm>
#include <iterator>

int main() 
{
    std::map<char, int> bar;

    bar['a'] = 11;
    bar['b'] = 22;
    bar['c'] = 33;
    bar['d'] = 44;

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;

    if ( !bar.empty() )
    {
        // the initializer can be any element not only the first one          
        const auto &value = *bar.begin(); 
        for ( auto &p : bar )
        {
            if ( p.first != value.first  ) p.second -= value.second;
        }
    }

    for ( const auto &p : bar )
    {
        std::cout << "{ " << p.first << ", " << p.second << " } ";
    }
    std::cout << std::endl;
}    
int value = bar.begin()->second;

for(std::map<char,int>::reverse_iterator it=bar.rbegin(); it != bar.rend(); it++) {
    it->second -= bar.begin()->second;
}
bar.begin()->second = value;