【问题标题】:Creating an array without duplicates创建一个没有重复的数组
【发布时间】:2013-11-14 06:24:27
【问题描述】:

我的问题如下。如何使用 const char * 中使用的所有字符创建一个数组,以使该数组没有任何重复。例如:

const char *pass = "Qqqqqqqwwwww11111" 

应该创建一个数组

Q  |  q  |  w  |  1

可变通行证由用户指定,因此很难确定它的外观。

【问题讨论】:

  • 这很容易;你试过什么? (提示:std::unordered_set<char>。)
  • 数组总是保证排序的吗?
  • 否,例如 pass 可能看起来像“Dma3q”。
  • 重复的字符总是连续的吗?

标签: c++ arrays algorithm duplicates


【解决方案1】:

据我了解,您想删除所有重复项并且顺序很重要,因此 std::unique 是不够的。

虽然您的元素类型很小,例如 char - 您可以使用 array/std::vector/std::bitset 来记住之前遇到过哪些元素:

Live Demo

template<typename I, typename O>
I remove_duplicates(I first, I last, O out)
{
    using T = typename iterator_traits<I>::value_type;
    using limits = numeric_limits<T>;

    constexpr auto min = limits::lowest();
    constexpr auto max = limits::max();

    bitset<size_t(max - min) + 1> had_before;

    while(first != last)
    {
        T x = *first;
        size_t i = x - min;
        if(!had_before[i])
        {
            had_before.set(i);
            *out = x;
            ++out;
        }
        ++first;
    }
    return out;
}

int main()
{
    char s[] = "Qqqqqqqwwwww111qq1q1Qa";
    auto first = begin(s), last = end(s);
    auto new_last = remove_duplicates(first, last, first);
    for_each(first, new_last, [](char x) { cout << x; });
}

输出是:

Qqw1a

【讨论】:

    【解决方案2】:

    如果您的意思是创建一个没有相邻重复元素的数组,那么首先您应该计算字符串传递中有多少个唯一元素,然后为数组动态分配内存并复制其中的唯一元素。 该任务可以使用标准算法简单地完成。例如

    char *a = 0;
    
    size_t n = std::strlen( pass );
    
    if ( n != 0 )
    {
        size_t count = 1 + std::inner_product( pass + 1, pass + n, pass, 0u, 
                                               std::plus<size_t>(),
                                               std::not_equal_to<const char>() );
    
        a = new char[count + 1];
    
        std::unique_copy( pass, pass + n + 1, a );
    }
    

    或者写起来会更简单

    char *a = 0;
    
    size_t n = 1 + std::strlen( pass );
    
    size_t count = 1 + std::inner_product( pass + 1, pass + n, pass, 0u, 
                                           std::plus<size_t>(),
                                           std::not_equal_to<const char>() );
    
    a = new char[count];
    
    std::unique_copy( pass, pass + n, a );
    

    【讨论】:

      【解决方案3】:

      众多解决方案之一是使用std::sortstd::unique。使用std::string(或std::vector,...)也更简单更安全。

      #include <iostream>
      #include <algorithm>
      
      int main() {
          char *pass = "Qqqqqqqwwwww11111"; // or by user input
      
          // using std::string is easier and safer (works similarly with std::vector)
          std::string data(pass);
      
          // Remove duplicates with std::sort and std::unique
          std::sort(data.begin(), data.end());
          auto end = std::unique(data.begin(), data.end());
      
          // Remove duplicates – if needed.
          data.erase(end, data.end());
      
          // Print the unique chars
          std::cout << data << std::endl;
          return 0;
      }
      

      根据您的操作,您可能不需要erase data 的重复元素。在这种情况下,请记住 end 是第一个重复元素上的​​迭代器(或者,如果数据首先没有重复,则它等于 data.end())。

      注意:在使用 std::unique 之前,您绝对需要对数据进行排序。

      Here you can try this code.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-14
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 2013-04-27
        • 1970-01-01
        • 2021-10-13
        • 1970-01-01
        相关资源
        最近更新 更多