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.