我想写一个函数,它将返回无重复数字的数量。到目前为止,我已经编写了一个函数,它迭代通过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
答案 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;
}