运行 长度编码程序 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<< 无法从用户那里获取一行中的多个单词。
我正在尝试制作一个代码,根据用户输入的值进行 运行=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<< 无法从用户那里获取一行中的多个单词。