向量只得到没有重复元素

Vector get only no repeating elements

本文关键字:元素 向量      更新时间:2023-10-16

我想写一个函数,它将返回没有重复数字的数量。到目前为止,我已经编写了一个函数,该函数正在遍历 char 并收集向量所有数字,但是当我必须仅从向量获取非重复数字时,问题就来了。

我的代码:

int norepeat(char *word){
    int i = 0;
    int size = 0;
    vector<int> tab;
    while (word[i] != ''){
        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

创建数字映射 -> 位计数。

然后循环访问地图并计算计数为 1 的位数。

int norepeat(char *word){
   int i = 0;
   std::map<char, int> m;
   while (word[i] != ''){
      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;
   }

C++的好处是能够混合来自C++标准模板库的普通旧数据指针和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

编辑

只是为了笑:写了一个计数输出迭代器类;它计算复制到其中的值的出现到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;
}

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

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] != '')
    {
        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;
}

这个噱头真的很有限,因为它只适用于十进制数字,但只要稍加修改,它就可以做大写或小写字符。使用标准::地图...可能性是无限的!为了一会儿的完整性,我将添加它。

编辑

地图版本。

int norepeat(const char *word){
    int i = 0;
    int size = 0;
    std::map<char, int> counts; 
                            
    while (word[i] != '')
    {
        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;
}
int norepeat(char *word){
int i = 0;
int size = 0;
vector<int> tab;
while (word[i] != ''){
    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;

}