在C中的数组中查找不规则重复的整数模式(无需多次遍历数组)

在C中的数组中查找不规则重复的整数模式(无需多次遍历数组),c,arrays,C,Arrays,整数2,1,4的模式在5000个元素的数组中不规则地重复,数组中的其余元素为0。但2总是跟在1后面,1总是跟在4后面,然后再跟2,依此类推 例如: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

整数2,1,4的模式在5000个元素的数组中不规则地重复,数组中的其余元素为0。但2总是跟在1后面,1总是跟在4后面,然后再跟2,依此类推

例如:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

我想检查这个2-1-4模式是否在数组中重复,而与元素之间的0数无关

如果这个模式,无论多么不规则,被重复,那么我有一个正确的数组。否则我会错过一些元素

我该怎么做


编辑:-这可以在不使用简单的C语言代码多次遍历数组的情况下完成。

遍历集合中累积整数的序列
(1,2,4)
,并跳过所有其他数字。每次累积三个数字时,检查是否有
(2,1,4)
序列。如果您这样做,请丢弃累积的数字,然后继续;否则,声明序列无效,并停止处理

到达序列末尾时,检查您是否没有累积的数字。如果是,请确保它是一个数字
2
,或者是两个数字
(2,1)
。否则,序列无效

这转化为一个非常简单的程序:

bool checkValid(std::vector<int> &data) {
    int acc = 0;
    bool res = false;
    for (auto &n : data) {
        // Skip numbers other than 1, 2, 4
        if (n != 1 && n != 2 && n != 4) {
            continue;
        }
        // Do accumulation in an int
        acc = 10*acc + n;
        // If we reach the target, zero out and continue
        if (acc == 214) {
            acc = 0;
            // Now that we found 2, ... , 1, ..., 4,
            // the sequence may be considered valid,
            // unless we find an error later on.
            res = true;
            continue;
        }
        // Check if the partial accumulation is valid
        if (acc != 2 && acc != 21) {
            return false;
        }
    }
    return res;
}
bool checkValid(标准::向量和数据){
int acc=0;
bool res=假;
用于(自动编号:数据(&n){
//跳过1、2、4以外的数字
如果(n!=1&&n!=2&&n!=4){
继续;
}
//以整数进行累加
acc=10*acc+n;
//如果我们达到了目标,就归零继续
如果(acc==214){
acc=0;
//现在我们发现了2,…,1,…,4,
//序列可能被认为是有效的,
//除非我们以后发现错误。
res=真;
继续;
}
//检查部分累加是否有效
如果(acc!=2&&acc!=21){
返回false;
}
}
返回res;
}

遍历集合
(1,2,4)
中累积整数的序列,并跳过所有其他数字。每次累积三个数字时,检查是否有
(2,1,4)
序列。如果您这样做,请丢弃累积的数字,然后继续;否则,声明序列无效,并停止处理

到达序列末尾时,检查您是否没有累积的数字。如果是,请确保它是一个数字
2
,或者是两个数字
(2,1)
。否则,序列无效

这转化为一个非常简单的程序:

bool checkValid(std::vector<int> &data) {
    int acc = 0;
    bool res = false;
    for (auto &n : data) {
        // Skip numbers other than 1, 2, 4
        if (n != 1 && n != 2 && n != 4) {
            continue;
        }
        // Do accumulation in an int
        acc = 10*acc + n;
        // If we reach the target, zero out and continue
        if (acc == 214) {
            acc = 0;
            // Now that we found 2, ... , 1, ..., 4,
            // the sequence may be considered valid,
            // unless we find an error later on.
            res = true;
            continue;
        }
        // Check if the partial accumulation is valid
        if (acc != 2 && acc != 21) {
            return false;
        }
    }
    return res;
}
bool checkValid(标准::向量和数据){
int acc=0;
bool res=假;
用于(自动编号:数据(&n){
//跳过1、2、4以外的数字
如果(n!=1&&n!=2&&n!=4){
继续;
}
//以整数进行累加
acc=10*acc+n;
//如果我们达到了目标,就归零继续
如果(acc==214){
acc=0;
//现在我们发现了2,…,1,…,4,
//序列可能被认为是有效的,
//除非我们以后发现错误。
res=真;
继续;
}
//检查部分累加是否有效
如果(acc!=2&&acc!=21){
返回false;
}
}
返回res;
}

您的数据位于
整数的
向量中。解决方案可能类似于(C++11):

std::矢量数据;
//在这里填写您的数据
data.erase(std::remove(data.begin(),data.end(),0),data.end());
auto是_ok=真;
for(auto it=data.begin();it!=data.end();it=std::advance(it,3)){
如果(*it!=2&&*(std::next(it))!=1&&*(std::advance(it,2))!=4){
is_ok=false;
打破
}
如果(std::next(it)==data.end()| std::advance(it,2)==data.end()){
//这是一种特殊情况,您应该根据需要自行完成
打破
}
}

您的数据位于
整数的
向量中。解决方案可能类似于(C++11):

std::矢量数据;
//在这里填写您的数据
data.erase(std::remove(data.begin(),data.end(),0),data.end());
auto是_ok=真;
for(auto it=data.begin();it!=data.end();it=std::advance(it,3)){
如果(*it!=2&&*(std::next(it))!=1&&*(std::advance(it,2))!=4){
is_ok=false;
打破
}
如果(std::next(it)==data.end()| std::advance(it,2)==data.end()){
//这是一种特殊情况,您应该根据需要自行完成
打破
}
}

简单的方法是读取循环中数组的每个元素,并将最后一个感兴趣的元素(2、1或4)存储在临时变量中。当另一个有趣的元素出现时,你检查这是你想要的,你继续,否则,你的数组就坏了

int isArrayBad(int * array, int arraySize)
{
int temp = 0;
for(int i = 0; i<arraySize; i++)
{
    if(!temp && array[i])
        temp = array[i];
    else if(array[i])
    {
        switch(temp)
        {
        case 2:
            if(array[i] != 1)
                return -1;
            break;
        case 1:
            if(array[i] != 4)
                return -1;
            break;
        case 4:
            if(array[i] != 2)
                return -1;
            break;
        }
        temp = array[i];
    }
}
return 0;
}
int-isArrayBad(int*array,int-arraySize)
{
内部温度=0;

对于(int i=0;i来说,最简单的方法是在循环中读取数组的每个元素,并将最后一个感兴趣的元素(2、1或4)存储在一个临时变量中。当另一个感兴趣的元素出现时,您检查这是您想要的元素,然后继续,否则,您的数组就坏了

int isArrayBad(int * array, int arraySize)
{
int temp = 0;
for(int i = 0; i<arraySize; i++)
{
    if(!temp && array[i])
        temp = array[i];
    else if(array[i])
    {
        switch(temp)
        {
        case 2:
            if(array[i] != 1)
                return -1;
            break;
        case 1:
            if(array[i] != 4)
                return -1;
            break;
        case 4:
            if(array[i] != 2)
                return -1;
            break;
        }
        temp = array[i];
    }
}
return 0;
}
int-isArrayBad(int*array,int-arraySize)
{
内部温度=0;

对于(int i=0;i我会选择一个函数,该函数会找到第一个不匹配的元素;如果它没有发现不匹配的元素,则返回一个输入结束指针

在C中:

int*不匹配(int*arr,size\t len)
{
int预期为2;
int*end=arr+len;
对于(;arrtemplate <typename Iterator>
Iterator mismatch(Iterator begin, Iterator end)
{
    typename Iterator::value_type expected = 2;
    for (; begin != end; ++begin) {
        if (*begin != 0 && *begin != expected) {
            return begin;
        }

        // dito
    }
}
// main.cc
#include <stdio.h>

class Checker {
private:
  static int pattern[];
  static int* const lastElem;
  static int ignore;
  int* next;
  int* advance(int*);
public:
  Checker();
  bool isCorrect(int* const, int* const);
};

int Checker::pattern[] = {2, 1, 4};
int* const Checker::lastElem = &pattern[2];
int Checker::ignore = 0;

Checker::Checker() {
  next = &pattern[0];
}

int* Checker::advance(int* cursor) {
  if(cursor != lastElem) {
    return ++cursor;
  }
  return &pattern[0];
}

bool Checker::isCorrect(int* const begin, int* const end) {
  for(int* pArr = begin; pArr != end; ++pArr) {
    if(*pArr == ignore) {
      continue;
    }

    if(*pArr != *next) {
      return false;
    }

    next = advance(next);
  }
  return true;
}

int main(int argc, char** argv) {
  int testArr[] = {0, 0, 0, 2, 0, 1, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 4};
  Checker test;
  bool res = test.isCorrect(testArr, &testArr[sizeof(testArr)/sizeof(testArr[0])]);
  printf("Test: %s\n", res ? "passed" : "failed");
  return 0;
}