我正在尝试寻找整数形式的重复图案。为此,我使用向量分别存储每个数字。我想把整个事情写成一个输出数字重复图案的函数。这些数字大多是12位数字。
一个例子:
号码是057 987 051 2057
我要打印该功能:
057
05
它也应该只打印出最长的重复模式。我目前停留在如何在C ++中实现整个过程上。我还想知道是否有任何库支持我要寻找的功能。
谢谢!
编辑:
for (vector<int>::iterator it = m_number.begin(); it != m_number.end(); ++it) {
int follower = *(it + 1);
for (vector<int>::iterator jt = it + 1; jt != m_number.end(); ++jt) {
if (*jt == *it) {
if (*(jt + 1) == follower)
cout << *jt;
}
}
cout << endl;
}
这是我到目前为止尝试过的。这显然在这里还行不通,但我希望它能使您对我希望函数执行的操作有所了解。我尝试使用两个在m_number向量上迭代的for循环(该向量包含我要检查的整数)。
答案 0 :(得分:2)
您可能会使用类似的内容:
std::set<std::vector<int>> GetRepetitingPatterns(const std::vector<int>& v)
{
std::set<std::vector<int>> res;
for (std::size_t size = v.size() - 1; size != 0; --size) {
std::set<std::vector<int>> s;
for (std::size_t i = 0; i + size != v.size() + 1; ++i) {
auto [it, inserted] = s.emplace(v.begin() + i, v.begin() + i + size);
if (!inserted) {
res.insert(*it);
}
}
#if 1 // Longest only
if (!res.empty()) {
return res;
}
#endif
}
return {};
}
以及变化形式(所有/最长和最小尺寸): Demo
答案 1 :(得分:1)
这是第一种方法:
for (size_t i = 0; i < m_numbers.size(); i++) {
// Look for patterns starting everywhere in the following numbers
for (size_t j = i+1; j < m_numbers.size(); j++) {
// Pattern storing
std::vector<int> pattern;
// Condition to stop the search
bool valid_pattern = true;
// Variable for the while loop
int offset = 0;
while (valid_pattern && j+offset < m_numbers.size()) {
// If the numbers are equal, continue the pattern, else, stop the search
if(m_numbers[i+offset] == m_numbers[j+offset]){
pattern.push_back(m_numbers[i+offset]);
} else {
valid_pattern = false;
}
offset++;
}
// If the pattern has at least two numbers, output it to the console
if(pattern.size() > 1){
for (size_t idx = 0; idx < pattern.size(); idx++) {
std::cout << pattern[idx];
}
std::cout << std::endl;
}
}
}
答案 2 :(得分:1)
您可以使用unordered_map开头。
#include <iostream>
#include <iomanip>
#include <unordered_map>
int main() {
std::string str = "0579870512057";
// a map of substrings and the number of times they appear
std::unordered_map<std::string, size_t> pm;
for(auto a=str.begin(); a!=str.end()-1; ++a) {
for(auto b=a+1; b!=str.end(); ++b) {
// std::string(a, b+1) creates the substring from your iterators
// the unordered_map::operator[] creates a key, value pair
// if the key doesn't exist (value is default constructed)
// ++ increases the value by 1
++pm[ std::string(a, b+1) ];
}
}
// display the number of times each substring appears (if it appeared more than once)
// and display the length (size) of each
for(auto& p : pm) {
if(p.second>1)
std::cout << std::setw(3) << p.second << " "
<< std::setw(12) << p.first.size() << " " << p.first << "\n";
}
}
稍微复杂一点的方法是创建一个自定义set
,该自定义#include <iostream>
#include <set>
struct comp { // a custom comparison class to sort the result
bool operator()(const std::string& a, const std::string& b) const {
if(b.size()==a.size()) return a < b; // lowest "value" when length is equal
else return b.size() < a.size(); // but longest pattern goes first
} // note b before a when comparing sizes
};
using string_pattern_set = std::set<std::string, comp>; // custom set type using "comp"
string_pattern_set get_recurring_patterns(const std::string& str) {
string_pattern_set sorted_result;
for(size_t len=str.size()-1; len>0; --len) {
auto end = str.end()-len;
for(auto pos=str.begin(); pos<end; ++pos) {
for(auto check=pos+1; check<=end; ++check) {
if(std::equal(pos, pos+len, check)) {
sorted_result.emplace(pos, pos+len);
break;
}
}
}
}
return sorted_result;
}
int main() {
string_pattern_set res = get_recurring_patterns("0579870512057");
if(res.size())
std::cout << "the longest recurring pattern is "
<< res.begin()->size() << " char(s)\n";
// display all patterns from longest to shortest
for(auto& str : res) std::cout << str << "\n";
}
将重复出现的模式从最长到最短排序,但是它的好处是您将知道结果中的第一个模式将是最长的。除了找到的模式以外,它也不会复制原始输入。
begin
如果您真的担心内存消耗,那么第三种选择是根本不存储重复出现的字符串,而是为匹配的子字符串存储end
和#include <iostream>
#include <set>
#include <algorithm>
#include <iterator>
// type to store begin and end iterators for matching patterns
using strits = std::pair<std::string::const_iterator, std::string::const_iterator>;
struct comp { // a custom comparison class to sort the result
bool operator()(const strits& a, const strits& b) const {
if((b.second-b.first)==(a.second-a.first)) // lowest "value" when length is equal
return std::lexicographical_compare(a.first, a.second, b.first, b.second);
else // but longest pattern goes first
return (b.second-b.first) < (a.second-a.first);
} // note b before a when comparing sizes
};
using string_pattern_set = std::set<strits, comp>; // custom set type using "comp"
template<bool LONGEST_ONLY = false, bool BIG_STRING = false>
string_pattern_set get_recurring_patterns(const std::string& str) {
string_pattern_set sorted_result;
for(size_t len=str.size()-1; len>0; --len) {
auto end = str.end()-len;
for(auto begin=str.begin(); begin<end; ++begin) {
if constexpr (BIG_STRING) {
// skip patterns already found to be recurring.
// in C++20, use set::contains instead
if(sorted_result.find(strits(begin, begin+len))!=sorted_result.end())
continue;
}
for(auto check=begin+1; check<=end; ++check) {
if(std::equal(begin, begin+len, check)) {
sorted_result.emplace(begin, begin+len);
break;
}
}
}
if constexpr (LONGEST_ONLY)
if(!sorted_result.empty()) break;
}
return sorted_result;
}
int main() {
string_pattern_set res = get_recurring_patterns("0579870512057");
if(res.size()) {
const auto& [begin, end] = *res.begin();
std::cout << "the longest recurring pattern is "
<< (end - begin)<< " char(s)\n";
}
// display all patterns from longest to shortest
for(const auto& [begin, end] : res) {
std::copy(begin, end, std::ostream_iterator<char>(std::cout));
std::cout << "\n";
}
}
迭代器。当预计重复模式会很长很长时,这种方法很好用。
public function destroy($id, $message = '')
{
//Calling queue
Queue::push('InvoiceQueue@delete_invoice', [
'id' => $id,
'Class' => $this->Class,
]);
//continue the function after returned from the queue
//Do validation based on queue returned status
$instance = $this->Class;
$record = $instance::findOrFail($id);
//Restore the DB if queue returned an error
if ($record->restore()) {
}
//Delete the DB if queue process working fine
else {
return parent::destroy($id, trans("$this->class.invoice"));
}
}