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

Problem with a run-length encoding program c++

我正在尝试制作一个代码,根据用户输入的值进行 运行=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;
    }

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

不幸的是,mbonness 的回答只会延迟你的死亡。

发生这种情况是因为它没有考虑如果字符串中至少最后 2 个字符相同会发生什么情况。例如,如果玩家输入 abcdd 会发生什么?由于 while 循环正在迭代 i,它会超出 while 循环的范围。因此会发生崩溃。

不过,还有一个问题你还没有想到。如果字符串中有多个字符彼此不相邻会怎样?例如ababab?当前代码不会处理这样的 senario。

这就是为什么不幸的是你必须将整个 str 向量循环两次。并一次存储每个字符。每当你开始下一次迭代时,你必须检查字符是否已经在字符向量中。如果是这样,您将忽略扫描并继续进行下一个。

我们来看函数体;

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

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

那么这个 for 循环中发生了什么?只要 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;
    <code>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<< 无法从用户那里获取一行中的多个单词。