Мне нужна помощь для домашней работы в университете. Я все еще новичок в этом.
По сути, я делаю кодирование длины строки и не знаю, как добавить букву после счетчика:
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
void error(std::string str)
{
throw std::runtime_error(str);
}
int main()
{ int counter = 1;
std::string id;
std::vector<int> v;
std::cout << "Enter the data to be compressed: ";
std::cin >> id;
try
{ for(int i = 0; i < id.size(); i++)
{
if(std::isdigit(id[i]))
error("invalid input");
}
std::cout << "The compressed data is: ";
for(int i = 0; i < id.size(); i++)
{
if(id[i] == id[i+1])
{
counter++;
}
else if(id[i]!= id[i+1])
{
v.push_back(counter);
v.push_back(id[i]);
counter=1;
}
}
for(int j = 0; j < v.size(); j++)
std::cout << v[j];
}
catch(std::runtime_error& str)
{
std::cerr << "error: " << str.what() << std::endl;
return 1;
}
return 0;
}
Например, если я введу aaabbb, пробрам должен вывести 3a3b. Проблема в том, что он выдает 397398 97 и 98, являющиеся кодом ascii для a и b.
я не знаю, как поставить букву после счетчика и чтобы они были в одном векторе.
Если вы хотите сериализовать как строку, попробуйте это:
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <sstream>
void error(std::string str) {
throw std::runtime_error(str);
}
int main() {std::ostringstream stream;
int counter = 1;
std::string id;
std::cout << "Enter the data to be compressed: ";
std::cin >> id;
try {
for (int i = 0; i < id.size(); i++) {
if (std::isdigit(id[i]))
error("invalid input");
}
std::cout << "The compressed data is: ";
for (int i = 0; i < id.size(); i++) {
if (id[i] == id[i + 1]) {
counter++;
} else if (id[i] != id[i + 1]) {
stream << counter;
stream << (char) id[i];
counter = 1;
}
}std::cout << stream.str() << std::endl;
} catch (std::runtime_error& str) {
std::cerr << "error: " << str.what() << std::endl;
return 1;
}
}
v[j]
от std::cout << v[j]
имеет тип int
и вот почему std::cout
пишет номер. Чтобы написать это как персонаж, вы должны сыграть v[j]
в char
следующее: std::cout << (char)v[j]
, В этом случае, std::cout
будет использовать char
специализация, а не int
один.
В то время как другие ответы могут дать вам нужный результат, я считаю, что идиоматический способ решить эту проблему — использовать класс для хранения как символа, так и его количества. Есть два очевидных варианта.
Также может быть std::tuple
если вы предпочитаете это для последовательности или по любой другой причине. Сохраните свои результаты в std::vector<std::pair<char, int>
, Это сохраняет информацию, но для ее распечатки вам необходимо определить соответствующую функцию. Добавить элементы через
v.emplace_back(character, count);
Если вы хотите предложить некоторую функциональность без внешних вспомогательных классов, определите пользовательский класс-оболочку, например, следующий.
class CharacterCount {
private:
char character;
int count;
public:
CharacterCount(char character, int count):
character(character), count(count) {}
explicit operator std::string() const { return std::to_string(count) + character;
// Other helper functions or constructors you require
}
Это упрощает печать
for (auto& character_count : v)
std::cout << static_cast<std::string>(character_count);
Я верю, потому что std::ostream::operator<<
шаблон, вы не можете получить неявное преобразование в std::string
работать. Я бы посоветовал против неявного преобразования в любом случае.
Вы можете использовать то же самое emplace_back
синтаксис, как и раньше, потому что мы предлагаем соответствующий конструктор.
Таким образом, вы берете свой вклад в string
и, в конечном счете, просто необходимо передать эту информацию, что в конечном итоге означает, что нет никакой причины хранить информацию в vector
, просто выведите его! Ты можешь использовать find_if
с лямбдой, чтобы найти непоследовательный символ (или find_if_not
Если вы предпочитаете.)
for(string::const_iterator finish, start = cbegin(id); start != cend(id); start = finish) {
finish = find_if(start, cend(id), [value = *start](const auto i) { return i != value; } );
cout << distance(start, finish) << *start;
}