我正在尝试根据用户输入的值制作一个可以运行=长度编码的代码。仅接受小写字母。使用两个向量。 问题在于,并非所有示例都如此: 示例: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;
}
答案 0 :(得分:1)
不幸的是,mbonness的回答只会延迟您的死亡。
之所以会发生这种情况,是因为它没有考虑如果字符串中至少最后两个字符相同会发生什么情况。例如,如果玩家输入abcdd会发生什么?由于while循环正在迭代i,因此它将超出while循环的范围。因此崩溃将会发生。
但是,您还没有想到另一个问题。如果字符串中有多个不相邻的字符会怎样?例如ababab?当前的代码将无法处理此类问题。
这就是为什么不幸的是您必须将整个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 <<不能从用户行中获取多个单词。
答案 1 :(得分:-3)
我认为问题是您的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;
}