我想對我使用的特殊協議的字符串執行運行長度壓縮。當運行大小或字符串中的特定字符> = 3時,運行被認爲是有效的。有人可以幫助我實現這一目標嗎?我有live demo on coliru。我非常肯定這可以用標準庫的std::adjacent_find
和std::not_equal_to<>
作爲搜索運行邊界的二元謂詞,並且一旦找到邊界可能使用std::equal_to<>
。以下是我有這麼遠,但我有結果麻煩:使用stl來運行長度使用std :: adjacent_find編碼一個字符串
給出一個包含運行或空格等字符下面輸入的文本字符串(在這種情況下運行的字母「S」的:
"---thisssss---is-a---tesst--"
我想上述文本字符串轉換成包含是純的> 2個字符或混合字符運行元件的載體。該結果幾乎是正確的,但並不完全,我無法當場錯誤。
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
expected the following
======================
---,thi,sssss,---,is-a,---,tesst--,
actual results
==============
---,thi,sssss,---,is-a,---,te,ss,--,
編輯:我修正了以前的代碼使這個版本更接近最終的解決方案。具體而言,我添加了運行大小的明確測試,將其包括在內。我似乎不過是具有邊界的情況下的問題 - 所有的空間情況與字符串末尾的幾個空格結束的情況下:
#include <iterator>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
int main()
{
// I want to convert this string containing adjacent runs of characters
std::string testString("---thisssss---is-a---tesst--");
// to the following
std::vector<std::string> idealResults = {
"---", "thi", "sssss",
"---", "is-a",
"---", "tesst--"
};
std::vector<std::string> tokenizedStrings;
auto adjIter = testString.begin();
auto lastIter = adjIter;
// temporary string used to accumulate characters that
// are not part of a run.
std::unique_ptr<std::string> stringWithoutRun;
while ((adjIter = std::adjacent_find(
adjIter, testString.end(), std::not_equal_to<>())) !=
testString.end()) {
auto next = std::string(lastIter, adjIter + 1);
// append to foo if < run threshold
if (next.length() < 2) {
if (!stringWithoutRun) {
stringWithoutRun = std::make_unique<std::string>();
}
*stringWithoutRun += next;
} else {
// if we have encountered non run characters, save them first
if (stringWithoutRun) {
tokenizedStrings.push_back(*stringWithoutRun);
stringWithoutRun.reset();
}
tokenizedStrings.push_back(next);
}
lastIter = adjIter + 1;
adjIter = adjIter + 1;
}
tokenizedStrings.push_back(std::string(lastIter, adjIter));
std::cout << "expected the following" << std::endl;
std::cout << "======================" << std::endl;
std::copy(idealResults.begin(), idealResults.end(), std::ostream_iterator<std::string>(std::cout, ","));
std::cout << std::endl;
std::cout << "actual results" << std::endl;
std::cout << "==============" << std::endl;
std::copy(tokenizedStrings.begin(), tokenizedStrings.end(), std::ostream_iterator<std::string>(std::cout, ","));
std::cout << std::endl;
}
why not_equal_to <>()(* adjIter,* next)而不是* adjIter!= * next? –
我沒有什麼區別,它與解決我的算法缺點無關。 – johnco3