Home > Mobile >  Find three or more consecutive characters in the same struct in C
Find three or more consecutive characters in the same struct in C

Time:02-24

I define a struct.

struct test
{
    char name[10];
    int num;
}temp[20];

I want to only output the data with the same name and three consecutive num or more in temp[20]. for example,the data of the temp[20] are as follows:

    temp[0] = { "a",0 };
    temp[1] = { "b",1 };
    temp[2] = { "a",2 };
    temp[3] = { "b",2 };
    temp[4] = { "a",3 };
    temp[5] = { "b",3 };
    temp[6] = { "a",4 };
    temp[7] = { "c",1 };
    temp[8] = { "c",2 };
    temp[9] = { "a",5 };
    ........

the output is

    temp[2] = { "a",2 };
    temp[4] = { "a",3 };
    temp[6] = { "a",4 };
    temp[9] = { "a",5 };
    temp[1] = { "b",1 };
    temp[3] = { "b",2 };
    temp[5] = { "b",3 };

I can only use a triple for loop to output data with the same name and three consecutive num,but four consecutive num can`t output.My code are as follows:

for (int i = 0; i < 20; i  )
    {
        for (int j = i   1;j < 20;j  ) {
            if ((strcmp(temp[i].name, temp[j].name) == 0) && (temp[j].num - temp[i].num == 1))
            {
                for (int k = 0; k < 20; k  )
                {
                    if ((strcmp(temp[k].name, temp[j].name) == 0) && (temp[k].num - temp[j].num == 1)) {
                        printf("%s,%d", temp[i].name, temp[i].num);
                        printf("%s,%d", temp[j].name, temp[j].num);
                        printf("%s,%d", temp[k].name, temp[k].num);
                    }
                }
            }
        }
    }

what could I do?

CodePudding user response:

Since you haven't specified anything particular about the data's ordering, I assume that it's fine to sort it. Sorting by the name, then number allows you to find consecutive runs of values in linear time. And a typically sorting algorithm can be achieved in N.log(N) time.

Let's assume that N represents the number of elements in your array. You can sort it simply like this:

std::sort(temp, temp   N,
    [](const test& a, const test& b) {
        int result = strcmp(a.name, b.name);
        return result < 0 || result == 0 && a.num < b.num;
    });

Using a couple of simple helpers to display the data...

void Show(const test& t)
{
    std::cout << t.name << "," << t.num << "\n";
}

void Show(const test* t, int N)
{
    for (int i = 0; i < N;   i)
        Show(t[i]);
}

Now, after sorting, a call to Show(temp, N); gives this:

a,0
a,2
a,3
a,4
a,5
b,1
b,2
b,3
c,1
c,2

Now it's quite trivial to walk through the array and find runs of some minimum number. You requested 3, but we can choose any number.

const int minRunLength = 3;
std::cout << "Consecutive runs with matching name (minimum " << minRunLength << "):\n";

for (int i = 0, runLength = 0; i < N;   i)
{
    // Update run length
    if (i > 0 &&
        strcmp(temp[i-1].name, temp[i].name) == 0 &&
        temp[i-1].num   1 == temp[i].num)
    {
          runLength;
    }
    else
    {
        runLength = 1;
    }

    // Show items meeting run length criteria
    if (runLength == minRunLength)
    {
        for (int p = runLength-1; p >= 0; --p)
            Show(temp[i - p]);
    }
    else if (runLength > minRunLength)
    {
        Show(temp[i]);
    }
}

Running this with a minimum length of 3 gives:

Consecutive runs with matching name (minimum 3):
a,2
a,3
a,4
a,5
b,1
b,2
b,3

A minimum of 4 is:

Consecutive runs with matching name (minimum 4):
a,2
a,3
a,4
a,5

Here is a Live Demo that you can play with.

  • Related