为什么std :: random_shuffle在std :: vector中创建空值?

时间:2015-12-17 13:47:22

标签: c++ vector

我想改组一个char矢量,但我注意到它创建了空值。以下是代码的一部分:

vector<char> letters_num;
vector<char> shuffle_letters_num;

char default_letters_num[88] = {'a','b','c','d','e','f','g','h','i','j','k',
'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
'P','Q','R','S','T','U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9'
};

letters_num.insert(letters_num.begin(),default_letters_num,default_letters_num+88);

shuffle_letters_num=letters_num;
random_shuffle(shuffle_letters_num.begin(),shuffle_letters_num.end());

shuffle_letters_num 被正确改组,但shuffle_letters_num的大小大于 letters_num

所以当我尝试这样的东西时,迭代器的内容可以是空的:

for(int i = 0; i < size_string; ++i) {
    it=find(shuffle_letters_num.begin(),shuffle_letters_num.end(),string[i]);

    if(it==shuffle_letters_num.end())
    {
        return "";
    }

    if(it==shuffle_letters_num.begin())
    {
        result+=shuffle_letters_num.at(shuffle_letters_num.size()-1);
    }
    else
    {
        it--;
        result += *it;
    }
}

如何在不生成空值的情况下如何随意改变矢量?

2 个答案:

答案 0 :(得分:4)

char default_letters_num[88]

好吧,你定义了一个88个字符的数组,但是你只提供了26 + 26 + 10 = 62个初始值设定项,所以最后的88 - 62 = 16个字符的值为零。

只需用62替换两次出现的88,一切都应该按预期工作。

答案 1 :(得分:2)

最干净的方法可能是直接初始化矢量:

vector<char> letters_num {'a','b','c','d','e','f','g','h','i','j','k',
    'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
    'P','Q','R','S','T','U','V','W','X','Y','Z',
    '0','1','2','3','4','5','6','7','8','9'
};

vector<char> shuffle_letters_num {letters_num};

random_shuffle(shuffle_letters_num.begin(),shuffle_letters_num.end());

如果您仍然使用不支持该编译器的旧编译器,那么您希望让编译器为您计算大小:

char default_letters_num[] = {'a','b','c','d','e','f','g','h','i','j','k',
'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
'P','Q','R','S','T','U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9'
};

...并且使用它,一些函数模板可以正确地找到数组的开头和结尾:

template <class T, size_t N>
T *begin(T (&array)[N]) {
    return array;
}

template <class T, size_t N>
T *end(T (&array)[N]) { 
    return array + N;
}

使用这些,初始化数组中的向量可能如下所示:

vector<char> shuffle_letters_num (begin(letters_num), end(letters(num));

无论哪种方式,我们已经消除了数组中项目的错误倾向手计数,并让编译器为我们做到这一点(它确实比我以前更好)甚至希望如此。