在C中的数组中查找不规则重复的整数模式(无需多次遍历数组)
整数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中的数组中查找不规则重复的整数模式(无需多次遍历数组),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
编辑:-这可以在不使用简单的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;
}