矢量只获得重复元素

时间:2015-10-22 18:14:16

标签: c++

我想写一个函数,它将返回无重复数字的数量。到目前为止,我已经编写了一个函数,它迭代通过char并收集到所有数字的向量,但问题来自于我必须从向量仅获得非重复数字。

我的代码:

int norepeat(char *word){
    int i = 0;
    int size = 0;
    vector<int> tab;
    while (word[i] != '\0'){
        if (word[i] >= '0' && word[i] <= '9') {
            int num = word[i];
            tab.push_back(num);
            sort(tab.begin(),tab.end());
            unique(tab.begin(),tab.end());
            size = tab.size();
        }
        ++i;
    }
    return size;
}

修改

几个例子应该如何运作:

norepeat("de32ge2sa3ds1") => 1
norepeat("defegtdsg") => 0
norepeat("12341234") => 0
norepeat("1yle2le49") => 4

4 个答案:

答案 0 :(得分:3)

创建数字地图 - &gt;数字计数。

然后遍历地图并计算计数为1的位数。

int norepeat(char *word){
   int i = 0;
   std::map<char, int> m;
   while (word[i] != '\0'){
      if ( isdigit(word[i] )
         m[word[i]]++;
      ++i;
   }

   int count = 0;
   for ( auto& p : m )
   {
      if ( p.second == 1 )
         ++count;
   }

   return count;
}

使用不支持C ++ 11的编译器时,for循环可以更改为:

   std::map<char, int>::iterator iter = m.begin();
   std::map<char, int>::iterator end = m.end();
   for ( ; iter != end; ++iter )
   {
      if ( iter->second == 1 )
         ++count;
   }

答案 1 :(得分:2)

C ++的优点是能够将来自C ++标准模板库的Plain-Old-Data指针和libc函数与算法混合使用:(注意:使用一些C ++ 11特性)

#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <ctype.h>

using namespace std;

size_t norepeat(const char* word) {
    vector<char>            digits;
    vector<char>::iterator  uniq;

    // Filter the digits
    copy_if(word, word+strlen(word), back_inserter(digits), ::isdigit);

    // get the unique ones
    sort(digits.begin(), digits.end());
    uniq = unique(digits.begin(), digits.end());

    // return amount
    size_t uniques    = std::distance(digits.begin(), uniq);
    size_t duplicates = std::distance(uniq, digits.end());
    return uniques - duplicates;
}

int main( void ) {
    cout << norepeat("hello 123 world 124") << endl;
    cout << norepeat("hello world") << endl;
    return 0;
}

输出:

2
0

修改

只是为了笑:写了一个count-output-iterator-class;它会将复制到其中的值的出现次数计入value - >的地图中。 unsigned int。结合count_if算法(使用C ++ lambda),norepeat函数本身只有三个语句:变量声明,过滤数字并返回计数结果:

#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <ctype.h>

using namespace std;

template <typename T>
struct counter : public iterator<output_iterator_tag, T> {
    typedef map<T, unsigned int> counter_type;

    counter(counter_type* ptr) : mapptr( ptr ) {}

    // decorate with dereference and assignment
    counter<T>& operator=( const T& t ) {
        mapptr->operator[]( t )++;
        return *this;
    }
    counter<T>& operator++() { return *this; }
    counter<T>& operator*() { return *this; }

    counter_type*   mapptr;
};

size_t norepeat(const char* word) {
    typename counter<char>::counter_type countert;

    // Filter the digits
    copy_if(word, word+strlen(word), counter<char>(&countert), ::isdigit);

    // Count the ones that have a value of one
    return count_if(countert.begin(), countert.end(),
                    [](const counter<char>::counter_type::value_type& kv) {
                          return kv.second==1; } );
}

int main( void ) {
    cout << norepeat("hello 123 world 124") << endl; 
    cout << norepeat("hello world") << endl; 
    return 0;
}

答案 2 :(得分:1)

由于我的上一个答案是基于对该问题的误读,这是怎么回事?

int norepeat(const char *word){
    int i = 0;
    int size = 0;
    int arr[10] = {0}; // there are only 10 unique possibilities,
                       // so we'll mark them when found
    while (word[i] != '\0')
    {
        if (std::isdigit(word[i])) 
        {
            int num = word[i] - '0'; // get numeric value of digit to use as index
            arr[num]++; // count the number of times we've seen this digit
        }
        ++i;
    }
    for (i = 0; i < 10; i++)
    {
        if (arr[i] == 1) // count all element seen only once
        {
            size++;
        }
    }
    return size;
}

这个插头是非常有限的,因为它只适用于十进制数字,但稍作修改就可以做大写或小写字符。有std::map ......可能性是无限的!我将在一秒钟内添加完整性。

修改

地图版。

int norepeat(const char *word){
    int i = 0;
    int size = 0;
    std::map<char, int> counts; 

    while (word[i] != '\0')
    {
        if (std::isdigit(word[i])) // could use any or no filtering logic here
        {
            counts[word[i]]++;
        }
        ++i;
    }
    for (auto &count: counts)
    {
        if (count.second == 1) // count all element seen only once
        {
            size++;
        }
    }
    return size;
}

答案 3 :(得分:0)

int norepeat(char *word){

int i = 0;
int size = 0;
vector<int> tab;
while (word[i] != '\0'){
    if (word[i] >= '0' && word[i] <= '9') {
        int num = word[i];
        tab.push_back(num);
    }
    ++i;
}

size = std::distance( unique(tab.begin(),tab.end()), tab.end() );
return size;

}