寻找整数重复模式

时间:2019-02-13 15:34:34

标签: c++

我正在尝试寻找整数形式的重复图案。为此,我使用向量分别存储每个数字。我想把整个事情写成一个输出数字重复图案的函数。这些数字大多是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循环(该向量包含我要检查的整数)。

3 个答案:

答案 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

以及变化形式(所有/最长和最小尺寸): 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"));
     }
    }