【问题标题】:How do I properly use getline() to turn strings to ints?如何正确使用 getline() 将字符串转换为整数?
【发布时间】:2016-09-19 17:27:49
【问题描述】:

我有一个如下所示的输入 txt 文件:

3 2

ATCGATTGA

GACTATACG

我正在使用 fstream,并将其创建为字符串。然后,我可以将 3 和 2 转换为它们自己单独的整数,但也希望将接下来的两行也转换为整数。我正在尝试使用 getline() 因为我被告知这将是最有效的,但无法弄清楚如何将较低的两个创建为他们自己的整数。关于如何让它发挥作用的任何帮助?

【问题讨论】:

  • 等等,你想把ATCGATTGA转换成一个整数吗?这怎么可能?
  • 您使用std::istringstreamstd::stoi 来实现。
  • 我得到前两个的方式是 string.at(0) 和 string.at(2),但对于后面的几行似乎不可行。 txt 文件将始终具有相同的格式,但第二个数字将始终是以下行的数量。
  • @Rakete1111 是的,我在想 A=0 T=1 C=2 G=3 或类似的东西,所以我可以转换为 int。
  • @Chief 那么这些是以 4 为底的数字吗?以 10 为底的数字?例如,AT 的值是多少,它是否与T 的数字相同?他们是一样的吗? A 为 0。

标签: c++ getline


【解决方案1】:

getline 不会将字符串转换为 int。只是不是它打算做的。

如果您想将ATCGATTGA 转换为int,显而易见的方法是将输入视为基数4。如果没有记错,“顺序”通常以A-T-C-G 形式给出。假设这是正确的,您会将它们视为 A=0、T=1、C=2、G=3,并相应地转换序列(但请注意,出于我们的目的,您选择的顺序并不重要,因为只要您对编码和解码使用相同的顺序)。

int cvt_amino(std::string const &amino) { 
    int result = 0;

    for (char c : amino) { 
        result *= 4;
        switch(c) { 
            case 'a':
            case 'A':
                result += 0;
                break;
            case 't':
            case 'T':
                 result += 1;
                 break;
            case 'c':
            case 'C':
                 result += 2;
                 break;
            case 'g':
            case 'G':
                 result += 3;
                 break;
            default:
                throw std::runtime_error("Error: bad argument");
        }
    }
    return result;
}

结果是每个序列的唯一数字(最多可容纳 int 的最大值)。模数错误(我尚未测试此代码)您应该能够将结果转换回生成它的原始序列。

这确实假设每个原始序列的长度是已知/固定的。如果长度可能不同,您将不知道要包含的前导“A”的数量。在这种情况下,您可能希望切换到基数 5,并将映射更改为 A=1、T=2、C=3、G=4。这消除了关于可变长度输入的歧义(但减少了适合给定可变大小的最大长度)。

就从文件中读取数据而言,这似乎很简单,至少假设我们知道输入格式。对于您上面给出的格式,您可能会使用如下内容:

int a, b;

your_file >> a >> b; // read the 3 and 2

// We'll assume an arbitrary number of space-separated sequences after that:
std::string input;
std:vector<int> values;

while (your_file >> input)
    values.push_back(cvt_amino(input));

【讨论】:

  • 问题是如何从主字符串中挑选出行然后转换为整数?
  • @Chief:经过编辑,至少包含了一些关于如何处理该问题的想法。
  • 只要输入具有在“重新序列化”期间可以考虑的固定长度,它就可以工作。否则,如果您有前导As,则长度丢失;您无法从整数重新创建原始字符串。因此,这个方案实际上并不是“每个序列都是唯一的”。
  • @LightnessRacesinOrbit:好点。我确实假设基于问题中的输入长度相同,但可能应该注意到这个假设。如果不正确,请改为以 5 为底,用 A=1、TC=2、C=3、G =4 代替。
  • @Chief:再补充一点:我认为如果你从询问你真正想知道/做什么开始(而且你仍然可以通过提出一个解释格式和您实际想要完成的新问题来做到这一点)。
猜你喜欢
  • 1970-01-01
  • 2015-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
相关资源
最近更新 更多