运行长度编码程序 c++ 的问题

Problem with a run-length encoding program c++

本文关键字:c++ 问题 程序 编码 运行      更新时间:2023-10-16

我正在尝试根据用户输入的值制作一个代码,该代码进行run=length编码。仅接受小写字母。使用两个向量。 问题是并非所有示例都如此: 示例: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;
}

不幸的是,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++) {

那么这个 for 循环发生了什么? 只要我不到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");
}
}
}
}

所以现在当你输入abababab时,它会打印正确数量的A和B,即使它们不相邻。

接下来要做的是如果用户输入"abab ababab"该怎么办。 我会把它留给你弄清楚. 提示.. cin<<不适用于从用户那里获取一行中的多个单词。

我认为问题是您的 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;
}