【问题标题】:Is there a Function to move an element in a vector to a new Position inside the same vector是否有一个函数可以将向量中的元素移动到同一向量内的新位置
【发布时间】:2021-09-27 04:01:33
【问题描述】:

我有一个字符串的排序向量,每当添加一个新字符串时,我们都有一个函数可以让我们计算新位置。我应该能够使用这个位置并更新向量。

例子:

  • 输入Vector v1{Acr,Adr,Apr,Arr,Asr};
  • 输入新字符串:Aar

只要添加了字符串 uis,向量就变为 v1{Acr,Adr,Apr,Arr,Asr,Aar};

在添加之后,新位置是使用一个函数计算的,在这种情况下,该函数将返回位置以插入 I1)。

所以经过一些操作后它应该变成v1{Aar,Acr,Adr,Apr,Arr,Asr};

【问题讨论】:

  • 您是否要保持向量的排序?您可能想要std::setstd::vector::insert 可用于在任意位置插入元素,它将所有后续元素向下移动一个位置,为新元素腾出空间。
  • 为什么要在最后添加新元素然后移动它,而不是立即将其插入到正确的位置?
  • std::lower_bound 可用于查找插入位置。

标签: c++ string sorting vector insert


【解决方案1】:

所以你想插入std::vector

那么使用std::vector::insert怎么样?

例子:

v1.insert(v1.begin() + index, new_value);

正如@Jarod42 所说,您可以使用std::lower_bound 来查找插入位置,如下所示:C++ std::lower_bound() function to find insertion point for an index-sorted vector

【讨论】:

    【解决方案2】:

    听起来std::vector::insertstd::lower_bound 的组合应该很合适:

    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    
    int main()
    {
        using std::vector;
        using std::string;
        using std::lower_bound;
        using std::cout;
        vector<string> v1{"Acr","Adr","Apr","Arr","Asr"};
        auto insertionPoint{lower_bound(begin(v1), end(v1), "Aar")};
        v1.insert(insertionPoint, "Aar");
        for (auto&&s:v1) cout << s << " ";
        cout << "\n";
        return 0;
    }   
    

    Demo

    关键元素是:v1.insert(insertionPoint, "Aar");直接插入正确的地方。如果你不想使用lower_bound,因为你已经有了索引(为了这个例子,我们称之为pos),你总是可以这样做v1.insert(begin(v1)+pos, "Aar");

    如果你真的需要在末尾追加(无论出于何种原因),使用std::sort 听起来是最自然的解决方案。虽然效率最低(假设您无论如何都可以修改向量)。

    使用自定义比较功能扩展答案:

    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    class Sth
    {
        std::string name_;
    public:
        explicit Sth(const std::string& s) : name_(s) {}
        const std::string& name() const {return name_;}
    };
    
    
    int main(int, char*[])
    {
        using std::vector;
        using std::string;
        using std::lower_bound;
        using std::cout;
        vector<Sth> v1{Sth("Acr"),Sth("Adr"),Sth("Apr"),Sth("Arr"),Sth("Asr")};
        auto insertionPoint{lower_bound(begin(v1), end(v1), Sth("Aar"),
            [](auto&& lhs, auto&& rhs){return lhs.name() < rhs.name();})};
        v1.insert(insertionPoint, Sth("Aar"));
        for (auto&&s:v1) cout << s.name() << " ";
        cout << "\n";
        return 0;
    }
    

    Demo

    【讨论】:

    • 这看起来不错但是,我的向量不直接包含字符串。它属于 A 类类型,其中包含一个获取名称的方法,并且必须对其进行排序。4
    • @AdityaRamMangalampalli 自定义比较器可以传递给lower_bound,这应该可以解决您的问题。
    【解决方案3】:

    如果我理解正确,您的意思类似于以下内容

    #include <iostream>
    #include <string>
    #include <utility>
    #include <vector>
    #include <iterator>
    #include <algorithm>
    
    int main() 
    {
        std::vector<std::string> v = { "Acr", "Adr", "Apr", "Arr", "Asr" };
        v.push_back( "Aar" );
        
        auto pos = std::upper_bound( std::begin( v ), std::prev( std::end( v ) ),
                   v.back() );
                   
        if ( pos != std::prev( std::end( v ) ) )
        {
            auto s = std::move( v.back() );
            v.pop_back();
            v.insert( pos, s );
        }
        
        for ( const auto &s : v )
        {
            std::cout << s << ' ';
        }
        std::cout << '\n';
        
        return 0;
    }
    

    程序输出是

    Aar Acr Adr Apr Arr Asr
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-14
      • 2019-08-13
      相关资源
      最近更新 更多