Top.Mail.Ru
Ответы

Задача на структуры данных, очереди и стек, не могу понять что делаю нет так?

Задача:
В программе нужно реализовать прием пакетов по UDP-протоколу в буфер приема, а затем сформировать выходное сообщение на основе принятых данных. Сам буфер было решено выполнить на основе очереди типа FIFO.
Вначале перед функцией main() нужно объявить следующую структуру:

1234
 typedef struct { 
	unsigned int num;	// порядковый номер пакета 
	char data[20];		// данные пакета (20 байт) 
} PACKAGE; 

Затем, в функции main() сформировать объект очереди с помощью команды:

1
 std::deque<PACKAGE> buff;  

Принятые пакеты следует добавлять в начало очереди (слева), а извлекать с ее конца (справа). Пакеты могут приходить в произвольном порядке. Добавьте последовательно в буфер buff информационные пакеты, прочитанные из входного потока с помощью следующего фрагмента программы:

123456789101112131415
     int x; 
    char s[20]; 
    PACKAGE p; 
 
    while (!feof(stdin)) { 
        cin >> x; 
        fgetc(stdin); 
        fgets(s, sizeof(s), stdin); 
        for (int i = 0; i < sizeof(s); ++i) 
            if (s[i] == '\n' || s[i] == '\r') s[i] = '\0'; 
 
        p.num = x; 
        strcpy(p.data, s); 
        buff.push_front(p); 
    } 

Извлеките эти пакеты из очереди и данные (поле data) занесите в следующий массив в соответствии с порядковыми номерами num:

1
 char data_str[100];  

То есть, в массиве data_str должен сначала идти фрагмент data с num = 1 (9 байт строки), сразу за ним второй фрагмент data с num = 2 (9 байт строки) и так до последнего принятого фрагмента (в последнем фрагменте число байт может быть меньше 9). Последним значением (сразу после всех записанных информационных символов) в data_str занесите символ конца строки '\0'.

Отобразите на экране сформированную строку data_str.

Код:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  
#include <iostream> 
#include <cstring> 
#include <vector> 
 
typedef struct { 
    unsigned int num;    // порядковый номер пакета 
    char data[20];       // данные пакета (20 байт) 
} PACKAGE; 
 
int main(void) 
{ 
    using namespace std; 
 
    vector<PACKAGE> buff; 
 
    int x; 
    char s[20]; 
    PACKAGE p; 
 
    while (!feof(stdin)) { 
        cin >> x; 
        fgetc(stdin); 
        fgets(s, sizeof(s), stdin); 
        for (int i = 0; i < sizeof(s); ++i) 
            if (s[i] == '\n' || s[i] == '\r') 
                s[i] = '\0'; 
 
        p.num = x; 
        strcpy(p.data, s); 
        buff.push_back(p); 
    } 
 
    char data_str[100]; 
    int offset = 0; 
 
    for (int i = buff.size() - 1; i >= 0; --i) { 
        PACKAGE packet = buff[i]; 
        int length = strlen(packet.data); 
        strncpy(data_str + offset, packet.data, length); 
        offset += length; 
    } 
 
    data_str[offset] = '\0'; 
 
    cout << data_str << endl; 
 
    return 0; 
} 

Пишет Failed. Wrong answer

Дополнен

Просто не могу понять что делаю не так... Непонятная какая-то задача, получаю Wrong answer, что/где не так - неясно. И как понять неясно...

Дополнен

Короче незнаю что делать так тоже не работает...

#include <iostream>
#include <vector>
#include <string>
class PACKAGE {
public:
int num;
std::string data;
PACKAGE(int num, std::string data) {
this->num = num;
this->data = data;
}
};

int main() {
using namespace std;
std::vector<PACKAGE> buff;
std::string data_str = "";
int offset = 0;
while (true) {
std::string line;
std::getline(std::cin, line);
if (line.empty()) {
break;
}
int x = std::stoi(line);
std::string s;
std::getline(std::cin, s);
PACKAGE p(x, s);
buff.push_back(p);
}
for (int i = buff.size() - 1; i >= 0; i--) {
PACKAGE packet = buff[i];
int length = packet.data.length();
data_str += packet.data.substr(0, length);
offset += length;
}
data_str += '\0';
std::cout << data_str << std::endl;
return 0;
}

По дате
По рейтингу
Аватар пользователя
Новичок

Ваш код не соответствует условиям задачи. В задаче указано, что буфер должен быть выполнен на основе очереди типа FIFO, а вы используете вектор. Кроме того, в задаче указано, что принятые пакеты следует добавлять в начало очереди (слева), а извлекать с ее конца (справа), но в вашем коде вы добавляете пакеты в конец вектора и извлекаете их с его конца.

Вот пример кода, который соответствует условиям задачи и должен работать правильно:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
 #include <iostream>  
#include <cstring>  
#include <deque> 
#include <vector> 
#include <algorithm> 
  
typedef struct {  
    unsigned int num;    // порядковый номер пакета  
    char data[20];       // данные пакета  
} PACKAGE;  
  
int main(void)  
{  
    using namespace std;  
  
    deque<PACKAGE> buff; 
  
    int x;  
    char s[20];  
    PACKAGE p;  
  
    while (!feof(stdin)) {  
        cin >> x;  
        fgetc(stdin);  
        fgets(s, sizeof(s), stdin);  
        for (int i = 0; i < sizeof(s); ++i)  
            if (s[i] == '\n' || s[i] == '\r')  
                s[i] = '\0'; 
  
        p.num = x; 
        strcpy(p.data, s);  
        buff.push_front(p);  
    }  
 
    char data_str[100];  
    int offset = 0;  
 
    std::vector<PACKAGE> vect(buff.begin(), buff.end()); 
 
    std::sort(vect.begin(), vect.end(), [](PACKAGE a, PACKAGE b) { 
        return a.num < b.num; 
    }); 
 
    for (PACKAGE& packet : vect) { 
        int length = strlen(packet.data);  
        strncpy(data_str + offset, packet.data, length);  
        offset += length;  
    } 
 
    data_str[offset] = '\0'; 
 
    cout << data_str << endl;  
 
    return 0;  
} 
 
Аватар пользователя
Мудрец

Привет! После изучения кода, выявлены некоторые ошибки и проблемы в вашей программе. Давайте рассмотрим возможные причины и предложим исправления:

1. Ошибка в объявлении структуры: в задаче требуется объявить структуру с именем PACKAGE, а в вашем коде используется типизированный define. Изменим объявление следующим образом:

12345
 struct PACKAGE { 
    unsigned int num;    // порядковый номер пакета 
    char data[20];       // данные пакета (20 байт) 
}; 
 



2. Неправильная инициализация вектора: вместо std::deque используется std::vector. Вам нужно заменить вектор на deque, чтобы выполнить требования задачи. Исправление:

12
 std::deque<PACKAGE> buff; 
 



3. Ошибка в цикле извлечения пакетов: вместо `while (!feof(stdin))` вы должны проверить успешность операции чтения со стандартного ввода. Исправление:

123456
 while (cin >> x) { 
    fgetc(stdin); 
    fgets(s, sizeof(s), stdin); 
    ... 
} 
 



4. Изменение порядка добавления пакетов в буфер: Задача требует добавления пакетов в начало очереди, но в вашем коде они добавляются в конец вектора. Исправление:

12
 buff.push_front(p); 
 



5. Заполнение массива data_str: Вам нужно обратиться к элементам буфера в порядке, обратном сохраненному порядку. В вашем коде вы проходите по вектору buff в прямом порядке. Исправление:

1234
 for (int i = buff.size() - 1; i >= 0; --i) { 
    ... 
} 
 



6. Использование strncpy: strncpy не гарантирует, что последний символ массива будет нулевым, если исходная строка превышает заданную длину. Вам следует использовать strncpy_s или другие безопасные альтернативы для копирования строк. Исправление:

12
 strncpy_s(data_str + offset, sizeof(data_str) - offset, packet.data, length); 
 


Итак, вот исправленный код:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
 #include <iostream> 
#include <cstring> 
#include <deque> 
 
typedef struct { 
    unsigned int num;    // порядковый номер пакета 
    char data[20];       // данные пакета (20 байт) 
} PACKAGE; 
 
int main(void) 
{ 
    using namespace std; 
 
    deque<PACKAGE> buff; 
 
    int x; 
    char s[20]; 
    PACKAGE p; 
 
    while (cin >> x) { 
        fgetc(stdin); 
        fgets(s, sizeof(s), stdin); 
        for (int i = 0; i < sizeof(s); ++i) 
            if (s[i] == '\n' || s[i] == '\r') 
                s[i] = '\0'; 
 
        p.num = x; 
        strcpy(p.data, s); 
        buff.push_front(p); 
    } 
 
    char data_str[100]; 
    int offset = 0; 
 
    for (int i = buff.size() - 1; i >= 0; --i) { 
        PACKAGE packet = buff[i]; 
        int length = strlen(packet.data); 
        strncpy(data_str + offset, packet.data, length); 
        data_str[offset + length] = '\0'; 
        offset += length; 
    } 
 
    cout << data_str << endl; 
 
    return 0; 
} 

 



Попробуйте выполнить эти исправления, и ваша программа должна дать правильный результат. Если у вас возникнут дополнительные вопросы, пожалуйста, дайте мне знать!

Аватар пользователя
Просветленный
12345
 char *ptr = data_str;
std::sort(begin(buff),end(buff), [] (PACKAGE &l, PACKAGE &r) { return l.num< r.num;} ); 
for (auto &b: buff) { 
  ptr = stpcpy(ptr, b.data); 
}