例如我有一个数组:
arr[9] = {1, 3, 4, 9, 2, 9, 2, 9, 7}
然后对数组进行排序得到
arr[9] = {1, 2, 2, 3, 4, 7, 9, 9, 9}
然后使用两个for循环计算每个值的重复数。我想要的输出是:
2 instances of 2
3 instances of 9
相反,我得到:
2 instances of 2
3 instances of 9
2 instances of 9
我知道循环进行一次后,当arr[6],外循环计算还有两个。但在此之后,循环进入arr[7],外循环仍然计数另一个9即arr[8]. 所以我的问题是,当它对数组中的每个数字重复计数一次时,我如何停止代码?. 谢谢!
示例代码:
#define NUM = 9
int main() {
arr[NUM] = {1, 3, 4, 9, 2, 9, 2, 9, 7};
sort_int_array(arr, NUM); //insertion sort function
int i, j, count=1;
for (i=0; i<NUM; i++) {
for (j=i+1;j<NUM; j++) {
if (arr[i] == arr[j]) {
count++;
}
if (arr[i] != arr[j] && count>1) {
printf("%d instances of %dn", count, arr[i]);
count=1;
}
}
}
}
我找到了答案,谢谢大家的帮助。我只需要删除第二个for循环。
#define NUM = 9
int main() {
arr[NUM] = {1, 3, 4, 9, 2, 9, 2, 9, 7};
sort_int_array(arr, NUM); //insertion sort function
int i, count=1;
for (i=0; i<NUM; i++) {
if (arr[i] == arr[i+1]) {
count++;
}
if (arr[i] != arr[i+1] && count>1) {
printf("%d instances of %dn", count, arr[i]);
count=1;
}
}
}
我认为问题是你先看前九个,然后再数后面两个。然后,它将转到副本,并将副本与其他副本进行比较。我假设你能做的是检查arr[I]是否不等于arr[I - 1]这样你就不会比较重复项
下面是一个演示程序,演示如何计算数组中元素出现的次数。
#include <stdio.h>
#include <stdlib.h>
int cmp( const void *a, const void *b )
{
int x = *( const int * )a;
int y = *( const int * )b;
return ( y < x ) - ( x < y );
}
int main(void)
{
int arr[] = {1, 3, 4, 9, 2, 9, 2, 9, 7};
const size_t N = sizeof( arr ) / sizeof( *arr );
qsort( arr, N, sizeof( int ), cmp );
for ( size_t i = 0; i != N; )
{
size_t j = i;
size_t count = 1;
while ( ++i != N && arr[i] == arr[j] ) ++count;
printf( "%zu instances of %dn", count, arr[j] );
}
return 0;
}
程序输出为
1 instances of 1
2 instances of 2
1 instances of 3
1 instances of 4
1 instances of 7
3 instances of 9
如果您愿意,您可以替换printf
的调用
printf( "%zu instances of %dn", count, arr[j] );
if ( count != 1 ) printf( "%zu instances of %dn", count, arr[j] );
在这种情况下,输出将是
2 instances of 2
3 instances of 9
编辑:至于你的解决方案作为你自己的问题的答案,然后代码调用未定义的行为,由于访问内存超出这个表达式arr[i+1]
当i
等于NUM - 1
for (i=0; i<NUM; i++) {
if (arr[i] == arr[i+1]) {
^^^^^^^^
count++;
}
if (arr[i] != arr[i+1] && count>1) {
^^^^^^^^
printf("%d instances of %dn", count, arr[i]);
count=1;
}
}
您不需要为此使用两个for循环,因为这会降低效率并增加代码的复杂性。
如果你用手做,你会
- 再拿一张纸来。
- 用于数组中的每个数字:
- 如果这是你第一次看到这个数字:
记下来并记录它的计数为1 - else:
然后增加1
- 如果这是你第一次看到这个数字:
如果你只需要出现至少两次的元素,你可以过滤掉count = 1的元素。
对于代码:
// this is called frequency array, which we will use to store the
// number of occurrences (frequency) of a given number.
// The size of the array must be larger than the largest number in the array
int sz = 10 // sz = largest expected element + 1 (this only works for array of integers).
int freq[sz];
memset(freq, 0, sz * sizeof(int)); // reset all values in the array to 0
int arr[9] = {1, 2, 2, 3, 4, 7, 9, 9, 9};
int i;
for (i = 0;i < 9;i++){
cur = arr[i]; // read the current element
freq[cur] += 1; // increment its count by 1
}
for (i = 0;i < sz;i++) {
count = freq[i]; // read the count of the number i
if(count != 0) {
// a count of 0 means that the number didn't occur in the array
// you can also exclude numbers occurring only once by count > 1
printf("%d instances of %dn", count, i);
}
}
我没有测试这段代码,但这是一个概念,你可以在这里找到更多。
这个实现使用了比需要的更多的空间,但是它有快速的访问时间,如果您移动到cpp,您可以使用stlmap
或unordered_map
来获得更节省空间的解决方案。