【问题标题】:Extracting a random word in a string提取字符串中的随机单词
【发布时间】:2020-02-24 11:12:07
【问题描述】:

我想在给定的行中提取一个随机数,因此我调用了一个随机数以将其用作索引。但它一直给我一个错误。

terminated called after throwing an instance of 'std::out_of_range'.

我知道这是因为索引值超出了字符串的大小。但我在我的代码中找不到任何错误。

do {
    int size = line.length();
    srand(time(NULL));
    index = rand() % size;
} while (isspace(line.at(index)));

这是一个随机数生成器。我从文本文件中提取一行。

我用过 做 { } while (isspace(line.at(index))); 因为我不希望它是空间,如果它是空间,为了再次生成一个随机数。

我想要的是这个。

0123456789

示例...索引:4

F---i----L F : First, L : Last

if (index == 0) {
    while (!isspace(line.at(last + 1))) {
        last = last + 1;
    }
}

else if (index == (size - 1))) {

    while (!isspace(line.at(first - 1))) {
        first = first - 1;
    }
}

else {
    while (!isspace(line.at(first - 1))) {
        first = first - 1;
    }

    while (!isspace(line.at(last + 1))) {
        last = last + 1;
    }
}

for (int i = first; i <= last; i++) {
    targetword += line.at(i);
}

这就是我计算第一个和最后一个索引并打印出所选单词的方式,它应该不会出错......

请帮帮我,谢谢

【问题讨论】:

  • 请注意,您应该只调用一次srand() - 这是随机性的初始“种子”。如果您以相同的方式反复播种,您将反复获得 same “随机”数字。或者更好的是,使用更现代的推荐方式来处理随机数:youtube.com/watch?v=LDPMpc-ENqY
  • 当字符串不包含任何空格时会发生什么?您的 while 循环最后递增/递减,直到超出范围。
  • 从 C++11 开始,STL 有一个新的随机数生成器工具(标头 ),它比 C 的 rand 更好。您可以在网上阅读有关它的信息,例如cplusplus.com/reference/random

标签: c++ string random extract word


【解决方案1】:

考虑这个循环(或发布的 sn-p 中的以下任何一个):

if (index == 0) {
    while (!isspace(line.at(last + 1))) {
        last = last + 1;
    }
}

没有检查增加的lastbeeing小于字符串的大小之前调用std::string::at,所以最终会抛出std::out_of_range类型的异常。

另外,std::srand 不应在循环内重复调用,而只能调用一次。如果您可以完全避免使用srandrand,而转向现代的&lt;random&gt; 设施,那就更好了。

如果意图是“从字符串中提取一个随机单词”,您可以将原始字符串拆分为单词,然后选择其中一个

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <string>
#include <cctype>

// Split a string into a vector of words.
auto words_from(std::string const& src)
{
    std::vector<std::string> words;

    // A "word" can contain only alphanumerical characters. Your milage may vary.
    auto is_in_word = [] (char ch) {
        return std::isalnum(static_cast<unsigned char>(ch));
    };

    for (auto it = src.cbegin(); it != src.cend();)
    {
        auto first = std::find_if(it, src.cend(), is_in_word);
        if ( first == src.cend() )
           break;
        ++it;
        auto last = std::find_if_not(it, src.cend(), is_in_word);
        words.emplace_back(first, last);
        it = last;
    }

    return words;   
}

int main()
{
    // Initialize the pseudo-random number generator
    std::random_device rd;
    std::seed_seq ss{rd(), rd(), rd()};
    std::mt19937 rnd_gen{ss};

    std::string source {"The quick brown fox jumps over the lazy dog."};

    // Split the original string into words
    auto words = words_from(source);
    if (words.size() == 0)
        return 0;

    // This will generate uniformly distributed indices in the correct range
    std::uniform_int_distribution<size_t> dist(0, words.size() - 1);

    // Print a random word
    std::cout << words[dist(rnd_gen)] << '\n';
}

可测试here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    相关资源
    最近更新 更多