数组的输出不符合预期

Output not as expected from the array

本文关键字:不符合 输出 数组      更新时间:2023-10-16

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

#include <iostream>
#include <cstdlib>
#include <bitset>
#include <string>
#include <ctime>
int main()
{
    using namespace std;
    int p, i=0, a[100000];
    int s;
    string myString;
    int binary;
    cout << "Type your text: ";
    std::getline (std::cin,myString);
    for (std::size_t k=0; k < myString.size(); ++k)
    {
        std::bitset<8> y(myString[k]);
        std::string dna = y.to_string();
        binary = atoi(dna.c_str());
        cout << binary;
        while (binary != 0)
        {
            a[i] = binary % 10;
            binary = binary / 10;
            i++;
        }
    } 
    std::cout << std::endl;
    srand(time(0));
    for (int j = (i-1); j>-1; j--)
    {
        if (a[j] == 0)
        {
            p = rand() %2;
            if (p==0)
                cout<< "A";
            else
                cout<< "T";
        }
        if (a[j] == 1)
        {
            s = rand() %2;
            if (s == 0)
                cout<< "G";
            else
                cout<< "C";
        }
        else
        {
            cout << "";
        }
    }
}

我不知道你为什么写了这么多错误的代码,但我已经设法提取(并更改)了真正完成任务的代码。

#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;
}

只要问一下你是否想要对某个特定部分进行解释。

我告诉过您不要将字符串转换为整数。你不听。这就是领先0消失的原因。

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

以下是我解决您问题的方法:运行在线

#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是"a",那么y将是01100001。

在这里,您可以将位集转换为字符串:

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

在我们的示例中,dna将是"01100001"。

在这里,您可以将字符串转换为整数:

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。

在这里,你又失去了零,因为一旦二进制==0,即使你提取的数字少于8,你也会停止提取数字。还要注意的是,你实际上是在颠倒函数atoi刚刚做的事情,唯一的区别是你没有得到前导零和比特的相反顺序(见下一段):

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

为什么输出是"随机"的

在这里,您正在以标准顺序迭代myString

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

例如,如果myString是"abc"而不是
在第一次迭代中,myString[k]将是"a"
在第二次迭代中,myString[k]将为'b'
在第三次迭代中,myString[k]将是"c":

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

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

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

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

例如,如果输入字符串是"abc",则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,则会得到相反的字符顺序。

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

进一步阅读

Python的禅宗。这句格言大多适用于除Brainfuck 之外的所有编程语言

原始C数组是邪恶的