输出与数组不符合预期

时间:2015-10-30 10:28:48

标签: c++ arrays loops io binary

我正在编写一个代码,我在其中输入用户用户文本,将其转换为二进制文件,将每个二进制字符存储在数组中的元素中,然后为{{1}打印AT随机0 GC。但是1似乎不遵循这个规则,它们随机出现在每个数字上; 0和1.因此,如果二进制文件是ATGC,我需要输出为0010101。此外,当我将二进制文件存储在int变量中时,它前面的零点就会消失。有没有办法保留它?

ATGACTG

2 个答案:

答案 0 :(得分:1)

我不知道为什么你写了这么多错误的代码,但我设法提取(和更改)实际完成工作的代码。

#include <iostream>
#include <string>
#include <bitset>
#include <ctime>

int main()
{
    int i = 0, a[8];
    std::string myString;

    std::cout << "Type your text: " << std::endl;
    std::getline(std::cin, myString);

    for(auto x : std::bitset<8>(myString).to_string())
        a[i++] = x == '1';

    std::cout << std::endl;
    srand(time(0));

    for(int j = 0; j < i; ++j)
        if(a[j] == 0)
            std::cout << (rand() % 2 ? "T" : "A");
        else if(a[j] == 1)
            std::cout << (rand() % 2 ? "C" : "G");

    std::cout << std::endl;
}

这是main的整洁版本:

int main()
{
    std::vector<int> a; // using std::vector
    std::bitset<8> bs;

    std::cout << "Type your text: " << std::endl;
    std::cin >> bs; // std::bitset can be read from stream via operator>>

    for(auto x : bs.to_string())
        a.push_back(x == '1');

    std::cout << std::endl;
    srand(time(0));

    for(auto x : a)
        if(x == 0)
            std::cout << (rand() % 2 ? "T" : "A");
        else if(x == 1)
            std::cout << (rand() % 2 ? "C" : "G");

    std::cout << std::endl;
}

请问您是否需要某些特定部分的解释。

答案 1 :(得分:0)

told你不要将字符串转换为整数。你没听。这就是领先0消失的原因。

您的输出接缝完全是随机的,因为在从a读取信息时,您会颠倒序列中的字符顺序。

以下是我解决问题的方法:run online

#include <iostream>
#include <string>
#include <bitset>
#include <ctime>
#include <cstdlib>

int main()
{
    std::cout << "Type your text: " << std::endl;
    std::string in_str;
    std::getline(std::cin, in_str);

    std::string binary_str;

    for(int i = 0; i < in_str.size(); ++i)
    {
        char c = in_str.at(i);
        binary_str.append(std::bitset<8>(c).to_string());
    }

    std::cout << binary_str << std::endl;

    srand(time(0));
    for(int i = 0; i < binary_str.size(); ++i)
    {
        char c = binary_str.at(i);
        if(c == '0')
            std::cout << (rand() % 2 ? "T" : "A");
        else
            std::cout << (rand() % 2 ? "C" : "G");
    }

    std::cout << std::endl;
}

如果您有任何疑问,请在评论中询问我。

编辑:OP要求我解释他的计划中的所有错误。

所有这些零都去了哪里?

要回答这个问题,我必须逐行解释你的程序所做的所有事情。

在此处将符号转换为位集:

std::bitset<8> y(myString[k])

例如:如果k是&#39; a&#39;,那么y将是01100001。

这里将bitset转换为字符串:

std::string dna = y.to_string();

在我们的例子中,dna将是&#34; 01100001&#34;。

这里将字符串转换为整数:

binary = atoi(dna.c_str());

atoi所做的非常简化的版本:

binary = 0;
for(int i = 0; i < dna.size(); ++i)
    binary = binary * 10 + (dna.at(i) - '0')

在我们的例子中,binary将是1100001。

注意:那不是你丢失零的地方。此时您仍然可以提取它们,因为您知道需要提取8位数。所以你可以将前导零加上它的长度为8。

下一行是您第一次实际丢失零的地方,因为cout并不知道您要打印8位数字。

cout << binary;

在我们的示例中,它将打印1100001。

在这里你再次松开零,因为即使你提取的数字少于8位,你也会在二进制== 0时立即停止提取数字。另请注意,您实际上是在颠倒函数atoi刚刚执行的操作,唯一的区别是您没有获得前导零和相反的位数(请参阅下一段):

while (binary != 0)
{
    a[i] = binary % 10;
    binary = binary / 10;
    i++;
}

为什么输出是&#34;随机&#34;?

在这里,您将按标准顺序迭代myString

for (std::size_t k=0; k < myString.size(); ++k)

e.g。如果myString是&#34; abc&#34;比
在第一次迭代中,myString [k]将是&#39; a&#39;
在第二次迭代中,myString [k]将是&#39; b&#39;
在第三次迭代中,myString [k]将是&#39; c&#39;:

但是在这个循环中,你以相反的顺序提取数字:

while (binary != 0)
{
    a[i] = binary % 10;
    binary = binary / 10;
    i++;
}

例如,如果binary是1100001 在第一次迭代中,您提取1并且binary变为110000
在第二次迭代中,您提取0并且binary变为11000
在第3次迭代中,您提取0并且binary变为1100 在第4次迭代中,您提取0并且binary变为110
在第5次迭代中,您提取0,binary变为11
在第6次迭代中,您提取1,binary变为1 在第7次迭代中,您提取1并且binary变为0

现在你最终得到一个数组,其中字符代码中的位被反转,但不同的字符按正常顺序存储在数组中。

e.g。如果输入字符串是&#34; abc&#34;,则a将成为:

1,0,0,0,0,1,1,  0,1,0,0,0,1,1,  1,1,0,0,0,1,1
 reversed 'a'    reversed 'b'    reversed 'c'

如果按正常顺序迭代a,则字符代码内的位顺序将反转。如果以相反的顺序迭代a,则会得到相反的字符顺序。

根据经验,不要通过猜测来编程,通过思考来编程。

进一步阅读

The Zen of Python。除了Brainfuck

之外,大多数这些格言都适用于每种编程语言

Raw C arrays are evil