如何计算一系列数字中的谷数?

给定一系列数字,谷被定义为序列中由较高值围绕(向左和向右)的区域。 任务是找到序列中的谷数。 例如,

{9,8,7,7,8,9} has one valley at {7,7} {9,8,7,7,8,6,9} has two valleys at {7,7} and {6} {7,8,9,8,7} has no valleys 

我必须计算山谷数量的代码如下:

 #include  #define SIZE 40 int main() { int input; int store[SIZE]; int i = 0; int j; int valley = 0; int count = 0; printf("Enter sequence: "); scanf("%d", &input); while(input != -1) { store[i] = input; i++; scanf("%d", &input); } count = count + i; for(i = 1; i < count; i++) { for(j = i; j  store[j]) && (store[j] < store[j+1])) { valley = valley + 1; break; } } } printf("Number of valleys: %d", valley); return 0; } 

如果输入为“3 2 1 2 3”,我能够显示正确的答案。 但是,如果在数字之间等于另一个并且它们是并排的(例如,“3 1 1 2”),程序将计算错误的答案。 如何编写程序以便能够显示正确数量的山谷?

寻找从下到上的坡度变化。

而不是双嵌套for循环,沿着寻找从下到上的斜率变化。 考虑任何0的斜率与前一斜率相同。

 size_t Valley(const int *store, size_t count) { size_t valley = 0; int slope = -1; size_t i; // Find first down slope for (i = 1; i < count; i++) { if (store[i] < store[i - 1]) { break; } } for (; i < count; i++) { int newslope = (store[i] > store[i - 1]) - (store[i] < store[i - 1]); // Loop for slope changes if (newslope == -slope) { if (newslope > 0) valley++; slope = newslope; } } return valley; } 

测试代码。

 void Vtest(const int *store, size_t count) { size_t n = Valley(store, count); printf("%zu %zu\n", count, n); } void Vtests(void) { int a1[] = { 9, 8, 7, 7, 8, 9 }; Vtest(a1, sizeof a1 / sizeof a1[0]); int a2[] = { 9, 8, 7, 7, 8, 6, 9 }; Vtest(a2, sizeof a2 / sizeof a2[0]); int a3[] = { 7, 8, 9, 8, 7 }; Vtest(a3, sizeof a3 / sizeof a3[0]); int a4[] = { 3, 2, 1, 2, 3 }; Vtest(a4, sizeof a4 / sizeof a4[0]); int a5[] = { 8, 7, 7, 8, 6 }; Vtest(a5, sizeof a5 / sizeof a5[0]); } int main(void) { Vtests(); return 0; } Output 6 1 7 2 5 0 5 1 5 1 

问题出在这里:

 if((store[j-1] > store[j] )&&(store[j] < store[j+1])) 

在两个比较中,您使用索引j ,因此该程序仅查找长度为1的山谷。尝试此修改:

 if((store[i-1] > store[i] )&&(store[j] < store[j+1])) 

我也不确定, break;是对的break; 在这种情况下。 但现在还不清楚,在案例3 1 2 3 - 一( 1 )或两( 11 2 )中哪个答案是正确的。 从你的第一个例子我们可以看出,正确的答案是一个,但从定义来看并不明显。

根据您是否 定义给定点左/右的IMMEDIATE较高值,您可能需要调整chux提供的Valley函数,如下所示:

 size_t Valley (const int *store, size_t count) { ... i++; for (; i < count; i++) { int newslope = (store[i] > store[i - 1]) - (store[i] < store[i - 1]); if (newslope == -slope) { if (newslope > 0) valley++; } slope = newslope; } ... } 

输出:

 $ ./bin/valleyt 6 0 7 1 5 0 5 1 5 0 

这是chux提供的答案的补充,输入数据正如他在答案中提供的那样。 此代码仅将的定义限制为由3个相邻点创建。 (从负面到正斜率的变化的一般答案的特殊情况,其间插入等效点)