c ++ 11 — проблема с программой кодирования длин серий Stack Overflow

Я пытаюсь сделать код, который действительно работает = длина кодировки на основе значения, введенного пользователем. Принимает только строчные буквы. Используя два вектора.
Проблема не во всех примерах:
Пример: zzzzzzzz
вывод: (завершить вызов после выброса экземпляра ‘std :: out_of_range’
what (): basic_string :: at: __n (8)> = this-> size () (8)
статус выхода -1)

Как это можно решить?

    #include <iostream>
#include <string>
#include <vector>

using namespace std;

bool is_small_letter(char c){
return c >= 'a' && c <= 'z';
}

void runLength(string str, vector<char>& charachters, vector<int>& length) {
int count;
int i;

for (i = 0; i < str.size(); i++) {
if (!is_small_letter(str.at(i))) {
throw runtime_error("invalid input");
}

**count = 1;
if (i == str.size() -1) {
// do nothing
} else {
while (str.at(i) == str.at(i + 1)) {
count++, i++;
}**  //changed following one answer advice.
}
charachters.push_back(str.at(i));
length.push_back(count);
}
}

int main() {
string str;
vector<char>charachters;
vector<int>length;

cout << "Enter the data to be compressed: ";
cin >> str;
try {
runLength(str, charachters, length);

cout << "The compressed data is: ";
for (int i = 0; i <= length.size() - 1; i++){
cout << length.at(i) << charachters.at(i);
}

} catch (runtime_error &excpt) {
cout << endl << "error: " << excpt.what();
}

return 0;
}

-3

Решение

к сожалению, ответ mbonness только задержит вашу кончину.

Это происходит потому, что в нем не учитывалось, что произойдет, если хотя бы последние 2 символа в строке будут одинаковыми. например, что произойдет, если игрок введет abcdd? поскольку цикл while выполняет итерацию i, он выходит за рамки цикла while. следовательно, авария случится.

Однако есть еще одна проблема, о которой вы еще не думали. что произойдет, если в строке будет несколько символов, которые не находятся рядом друг с другом? например абабаб? текущий код не будет обрабатывать такой senario.

Вот почему, к сожалению, вам придется дважды зацикливать весь вектор str. и сохраняйте каждого персонажа по одному. и всякий раз, когда вы начинаете следующую итерацию, вы должны проверить, находится ли символ уже в векторе символов. если это так, вы игнорируете сканирование и переходите к следующему.

давайте посмотрим на тело функции;

  void runLength(string str, vector<char>& charachters, vector<int>& length) {
int count;
int i;

for (i = 0; i < str.size(); i++) {

так что происходит в этом цикле? мы продолжаем бежать, пока я меньше str.size(), обратите внимание, что хотя str.size() не основанный на нуле индекс, он будет работать нормально. Зачем? потому что мы не используем <= операторы. мы используем < оператор.

Далее нам понадобится переменная bool, чтобы проверить, является ли текущий str.at(i) уже добавлен в vector<char>charachters,

bool charAlreadyExist = false;

давайте сделаем наш второй внутренний цикл, чтобы проверить, содержат ли символы текущий элемент str.

 for(int l = 0; l < charachters.size(); l++)
{
if(charachters.at(l) == str.at(i))
{
charAlreadyExist = true;
break;
}
}

следующий цикл начинается только в том случае, если charAlreadyExist is false

 if (charAlreadyExist == false)
{
for(int j = 0; j < str.size(); j++)
{
if (str.at(i) == str.at(j))
{
count++;
}
}

Обратите внимание, что в приведенном выше утверждении мы больше не увеличиваем i. это было причиной, по которой ответ mmbonnes’а не удался

остальная часть кода функции будет похожа на то, что вы сделали.

Вот полный код функции. но попробуйте реализовать это, не смотря на это в первую очередь. это поможет вам лучше понять код

void runLength(string str, vector& charachters, vector& >!length)
{
int count;
int i;
for (i = 0; i < str.size(); i++)
{
count = 0;
bool charAlreadyExist = false;
for(int l = 0; l < charachters.size(); l++)
{
if(charachters.at(l) == str.at(i))
{
charAlreadyExist = true;
break;
}
}
if (charAlreadyExist == false)
{
for(int j = 0; j < str.size(); j++)
{
if (str.at(i) == str.at(j))
{
count++;
}
}
charachters.push_back(str.at(i));
length.push_back(count);
if (!is_small_letter(str.at(i)))
{
throw runtime_error("invalid input");
}
}
}
}[/ NOEDIT]

так что теперь, когда вы вводите abababab, он напечатает правильное количество букв a и b, даже если они не расположены рядом друг с другом.

Следующее, что вы должны сделать, это сделать, если пользователь вводит «abab ababab». Я оставлю это вам, чтобы выяснить. подсказка<< не будет работать для получения нескольких слов в строке от пользователей.

1

Другие решения

Я думаю, что проблема в том, что ваш цикл for не взаимодействует по всей входной строке. Попробуй это:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

bool is_small_letter(char c){
return c >= 'a' && c <= 'z';
}

void runLength(string str, vector<char>& charachters, vector<int>& length) {
int count;
int i;

for (i = 0; i < str.size(); i++) {
if (!is_small_letter(str.at(i))) {
throw runtime_error("invalid input");
}

count = 1;
if (i == str.size() -1) {
// do nothing
} else {
while (i < str.size() - 1 && str.at(i) == str.at(i + 1)) {
count++, i++;
}
}
charachters.push_back(str.at(i));
length.push_back(count);
}
}

int main() {
string str;
vector<char>charachters;
vector<int>length;

cout << "Enter the data to be compressed: ";
cin >> str;
try {
runLength(str, charachters, length);

cout << "The compressed data is: ";
for (int i = 0; i <= length.size() - 1; i++){
cout << length.at(i) << charachters.at(i);
}

} catch (runtime_error &excpt) {
cout << endl << "error: " << excpt.what();
}

return 0;
}
-3

По вопросам рекламы [email protected]