C++ C++;空和数组索引

C++ C++;空和数组索引,c++,C++,是否可以执行以下操作: string word = "Hello"; word[3] = null; if(word[3] == null){/.../} 在C++中,基本上使数组元素为空。例如,如果我想从数组中删除重复的字符,我会先将它们设置为null,然后在每次找到包含null的数组索引时将数组向左移动 如果这是不可能的,在C++中做这样的事情的好方法是什么? 如果要删除相邻的重复字符,可以这样做: std::string::iterator new_end = std::unique(w

是否可以执行以下操作:

string word = "Hello";
word[3] = null;
if(word[3] == null){/.../}
<>在C++中,基本上使数组元素为空。例如,如果我想从数组中删除重复的字符,我会先将它们设置为null,然后在每次找到包含null的数组索引时将数组向左移动


如果这是不可能的,在C++中做这样的事情的好方法是什么?

如果要删除相邻的重复字符,可以这样做:

std::string::iterator new_end = std::unique(word.begin(), word.end());
word.erase(new_end, word.end());
如果要标记要删除的任意字符,可以跳过标记,只需为
std::remove\u提供适当的谓词,如果

new_end = std::remove_if(word.begin(), word.end(), IsDuplicate);
word.erase(new_end, word.end());
然而,我想不出一个合适的谓词在这里使用,它不会表现出未定义的行为。我只需编写自己的算法:

template<typename IteratorT>
IteratorT RemoveDuplicates(IteratorT first, IteratorT last)
{
    typedef typename std::iterator_traits<IteratorT>::value_type
            ValueT;
    std::map<ValueT, int> counts;
    for (auto scan=first; scan!=last; ++scan)
    {
        ++counts[*scan];
        if(counts[*scan] == 1)
        {
            *first = std::move(*scan);
            ++first;
        }
    }
    return first;
}
模板
IteratorT RemovedUpplicates(首先是IteratorT,最后是IteratorT)
{
typedef typename std::迭代器特征::值类型
瓦利特;
地图计数;
用于(自动扫描=第一次;扫描!=最后一次;++扫描)
{
++计数[*扫描];
如果(计数[*扫描]==1)
{
*第一个=标准::移动(*扫描);
++第一,;
}
}
先返回;
}

或者,如果您不关心元素的顺序,可以简单地对其排序,然后使用第一种解决方案。

如果要删除相邻的重复字符,可以执行以下操作:

std::string::iterator new_end = std::unique(word.begin(), word.end());
word.erase(new_end, word.end());
如果要标记要删除的任意字符,可以跳过标记,只需为
std::remove\u提供适当的谓词,如果

new_end = std::remove_if(word.begin(), word.end(), IsDuplicate);
word.erase(new_end, word.end());
然而,我想不出一个合适的谓词在这里使用,它不会表现出未定义的行为。我只需编写自己的算法:

template<typename IteratorT>
IteratorT RemoveDuplicates(IteratorT first, IteratorT last)
{
    typedef typename std::iterator_traits<IteratorT>::value_type
            ValueT;
    std::map<ValueT, int> counts;
    for (auto scan=first; scan!=last; ++scan)
    {
        ++counts[*scan];
        if(counts[*scan] == 1)
        {
            *first = std::move(*scan);
            ++first;
        }
    }
    return first;
}
模板
IteratorT RemovedUpplicates(首先是IteratorT,最后是IteratorT)
{
typedef typename std::迭代器特征::值类型
瓦利特;
地图计数;
用于(自动扫描=第一次;扫描!=最后一次;++扫描)
{
++计数[*扫描];
如果(计数[*扫描]==1)
{
*第一个=标准::移动(*扫描);
++第一,;
}
}
先返回;
}

或者,如果您不关心元素的顺序,您可以简单地对其排序,然后使用第一种解决方案。

我认为您应该看看STL中的算法。
您对要删除的内容不是很明确,但这可能会有所帮助:

    std::string string_with_dup("AABBCCDD");
    std::string string_without_dup;
    std::cout << string_with_dup << std::endl;
    // with copy
    std::unique_copy(string_with_dup.begin(), string_with_dup.end(), std::back_inserter(string_without_dup));
    std::cout << string_without_dup << std::endl;
    // or inplace
    string_with_dup.erase(std::unique(string_with_dup.begin(), string_with_dup.end()), string_with_dup.end());
    std::cout << string_with_dup << std::endl;
std::string string_与_dup(“AABBCCDD”);
std::不带重复的字符串;

std::cout我想你应该看看STL中的算法。
您对要删除的内容不是很明确,但这可能会有所帮助:

    std::string string_with_dup("AABBCCDD");
    std::string string_without_dup;
    std::cout << string_with_dup << std::endl;
    // with copy
    std::unique_copy(string_with_dup.begin(), string_with_dup.end(), std::back_inserter(string_without_dup));
    std::cout << string_without_dup << std::endl;
    // or inplace
    string_with_dup.erase(std::unique(string_with_dup.begin(), string_with_dup.end()), string_with_dup.end());
    std::cout << string_with_dup << std::endl;
std::string string_与_dup(“AABBCCDD”);
std::不带重复的字符串;

std::cout这是可能的,因为字符串的单个元素是char数组中的元素,因此可以表示为指针,即。E您可以检索元素的地址。因此,您可以设置
word[3]=null
。如果
构造有效,但编译器会打印警告,这是因为
NULL
只是一个指针常量。备选方案是:
if(!word[3])
if(word[3]==0)


<>但是无论如何,你应该考虑使用STL来删除重复。

这是可能的,因为字符串的单个元素是字符数组中的元素,因此可以表示为指针I。E您可以检索元素的地址。因此,您可以设置

word[3]=null
。如果
构造有效,但编译器会打印警告,这是因为
NULL
只是一个指针常量。备选方案是:
if(!word[3])
if(word[3]==0)


<>但是无论如何,你应该考虑使用STL来删除重复。

< P>如果你想删除所有的副本(不只是相邻的副本),你应该使用类似这样的东西

#include <iostream>
#include <map>
#include <string>
#include <algorithm>

using namespace std;

struct is_repeated {
    is_repeated( map<char,int>& x ) :r(&x) {};
    map<char,int>* r;
    bool operator()( char c ) {
        (*r)[c]++;
        if( (*r)[c] > 1 )
            return true;
        return false;
    }
};

int main (int argc, char**argv)
{
    map<char,int> counter_map;
    string v = "hello hello hello hello hello hello hello";
    cout << v << endl;
    is_repeated counter(counter_map);
    v.erase( remove_if(v.begin(), v.end(), counter ), v.end() );
    cout << v << endl;
}

如果要删除所有重复项(而不仅仅是相邻的重复项),则应将

#include <iostream>
#include <map>
#include <string>
#include <algorithm>

using namespace std;

struct is_repeated {
    is_repeated( map<char,int>& x ) :r(&x) {};
    map<char,int>* r;
    bool operator()( char c ) {
        (*r)[c]++;
        if( (*r)[c] > 1 )
            return true;
        return false;
    }
};

int main (int argc, char**argv)
{
    map<char,int> counter_map;
    string v = "hello hello hello hello hello hello hello";
    cout << v << endl;
    is_repeated counter(counter_map);
    v.erase( remove_if(v.begin(), v.end(), counter ), v.end() );
    cout << v << endl;
}

相邻的重复字符?或者任何重复的字符?很抱歉,不够具体,但我仅使用字符串作为示例。我想知道如何对包含int或其他常规对象的数组执行某些操作。我对任何重复的字符都感兴趣。相邻的重复字符?或者任何重复的字符?很抱歉,没有非常具体,但我只使用字符串作为示例。我想知道如何对包含int或其他一般对象的数组执行某些操作。我对任何重复项都感兴趣。这似乎是一个非常优雅的方法。你能解释一下它的作用吗?@user1066113:第一个调用
unique
函数字符串的范围。它删除所有相邻的重复项,将非重复项向前移动。在移动发生后,它将返回一个迭代器到范围的末尾。然后,此迭代器与字符串成员函数
erase
一起使用,以擦除从该点开始到字符串末尾的元素,有效地重新调整大小@user1066113:第二个函数使用
remove\u if
函数执行非常类似的操作。但是,它可以根据第三个参数提供的任何条件删除元素,而不是相邻的重复项。我刚刚编写了
IsDuplicate
函数。这似乎是一个非常优雅的方法。你能理解吗ou解释它的作用?@user1066113:第一个函数调用字符串整个范围内的
unique
函数。该函数删除所有相邻的重复项,将非重复项向前移动。在移动发生后,它将返回一个迭代器到范围的末尾。然后该迭代器与字符串成员函数一起使用de>erase
删除从该点开始到字符串末尾的元素,有效地调整其大小。@user1066113:第二个使用
remove\u if
函数执行非常类似的操作。而不仅仅是相邻的重复项