这是我的程序的代码。它应该从用户那里获得两个数字,然后使用rand函数生成随机数。 但是当我编译它时,数字不是随机的。
我也在java中写过这个,并且那个完美无缺。
C版:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int cmpfunc();
int main()
{
puts("How many numbers do you want to generate?");
int n;
scanf("%d", &n);
int numbers[n];
puts("What should be the largest number possible?");
int m, i;
scanf("%d", &m);
int result[m];
for(i=0;i<m;i++)
numbers[i] = i + 1;
srand(time(NULL));
for(i=0;i<n;i++)
{
int r = rand() % m;
result[i] = numbers[r];
numbers[r] = numbers[m - 1];
m--;
}
qsort(result, n, sizeof(int), cmpfunc); //sorting the result array
for(i=0;i<n;i++)
{
printf("%d\n", result[i]);
}
getch();
return 0;
}
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
编辑:srand在循环中,人们说它不应该被多次调用。所以我把它拿出来但是没有帮助。
Java版:
import java.util.*;
public class RandomNumberGenerator {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("How many numbers do you want to generate?");
int n = in.nextInt();
System.out.println("What should be the largest number possible?");
int m = in.nextInt();
int numbers[] = new int[m];
for(int i=0;i<numbers.length;i++)
numbers[i] = i + 1;
int result[] = new int[n];
for(int i=0;i<result.length;i++)
{
// make a random index between 0 and n - 1
int r = (int) (Math.random() * m );
result[i] = numbers[r];
// move the last element into the random location
numbers[r] = numbers[m - 1];
m--;
}
System.out.println("Do you want the result to be sorted? (1 for Yes, others for No)");
int ans = in.nextInt();
if(ans==1)
Arrays.sort(result);
System.out.println("Result:");
for (int r : result)
System.out.println(r);
pressAnyKeyToContinue();
}
private static void pressAnyKeyToContinue()
{
System.out.println("Press Enter to continue.");
try
{
System.in.read();
}
catch(Exception e)
{}
}
}
编辑2:
c输出:(不是随机的,已排序的)
java输出:(随机,排序)
编辑3:
正如我在评论中所说,价值观是: n = 55 m = 9808
我也在使用代码块,因此头文件并不是真正的问题。它们由代码块自动加载。
编辑4:
我对人们的建议印象深刻。 qsort在生成随机数时没有改变。它只是排序数组。所以即使我删除它,它也不会改变任何东西。
在一组随机数中,我们预计任何两个相邻元素之间的差异也是随机的。此属性在排序下保留。我对C和Java中的随机数进行排序可以检查这个属性。如您所见,在C代码中,相邻元素之间的差异都是相同的。这让我相信C代码不是生成随机数,而是Java代码。
编辑5:
并且我确定java和c之间的算法应该没有区别。
编辑6:
对不起,我不是专业人士。我只想尝试制作我所拥有的Java程序的C版本。我们非常感谢固定代码。
****编辑决赛:** 终于搞定了。数组&#34;数字&#34;和&#34;结果&#34;分别存储n和m应该存储m和n。这就是全部。除此之外我改变了他们的名字与人们的建议。有些人告诉我用数组dims切换变量m和n。事实并非如此。 这是任何感兴趣的人的固定代码:**
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int cmpfunc();
int main()
{
puts("How many numbers do you want to generate?");
int num_numbers;
scanf("%d", &num_numbers);
puts("What should be the largest number possible?");
int num_maximum, i;
scanf("%d", & num_maximum);
int numbers[num_maximum];
int result[num_numbers];
for(i=0;i<num_maximum;i++) // making
numbers[i] = i + 1;
srand(time(NULL)); // seeding rand
for(i=0;i<num_numbers;i++)
{
int r = rand() % num_maximum; // generates random number between 0 and m-1
result[i] = numbers[r]; //
numbers[r] = numbers[ num_maximum - 1];
num_maximum--;
}
puts("Do you want the result to be sorted?");
int ans;
scanf("%d", &ans);
if (ans==1)
qsort(result, num_numbers, sizeof(int), cmpfunc); //sorting the result array
for(i=0;i< num_numbers;i++)
{
printf("%d\n", result[i]);
}
getch();
return 0;
}
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
答案 0 :(得分:3)
srand(time(NULL));
用于种子随机数生成器。它只需要调用一次。你需要将它移出for循环。
如果您每次都播种,那么您最终会得到rand()
生成的相同号码。
此外,time()
是time.h
中的原型。
接下来,如 @Blastfurnace 所述,您应该将m
而不是n
作为qsort()
的第二个参数传递。
然后,
for(i=0;i<m;i++)
numbers[i] = i + 1;
可以(将)通过为numbers
数组生成越界访问来导致UB。
答案 1 :(得分:2)
在您的Java代码中:
int numbers[] = new int[m];
int result[] = new int[n];
在您的C代码中:
int numbers[n];
int result[m];
阵列的大小相反。当我将C代码的定义与Java代码的定义相匹配时,代码似乎有效。
答案 2 :(得分:1)
问题说:
n= 55 m= 9808
但是代码包括:
int numbers[n];
for(i=0;i<m;i++)
numbers[i] = i + 1;
i
通过55
后,这是一个缓冲区溢出,导致未定义的行为。
第二个循环有相同的错误(n
和m
交换);另一个错误是将错误的维度传递给qsort
。
要修复这些错误,请在声明数组的位置后停止在代码中使用m
和n
。而是使用数组的维度。一种方法是写:
#define dimof(ARR) ( sizeof(ARR) / sizeof (ARR)[0] )
然后你可以使用它:
for (int i = 0; i < dimof(numbers); ++i)
numbers[i] = i + 1;
这样就没有机会混淆哪个变量与哪个数组相关。
你必须为第二个循环和qsort维度做同样的事情。
答案 3 :(得分:0)
因为它比指向每个错误更容易,所以这里将Java代码音译成C,带有一些更有意义的变量名(Horstmann应该知道更好),但是没有排序代码(它正在成为一个分心):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int main( void )
{
int sampleSize, valueRange;
printf( "How many samples do you want to take: " );
fflush( stdout );
scanf( "%d", &sampleSize );
printf( "What is the range of values, starting from 1: " );
fflush( stdout );
scanf( "%d", &valueRange );
/**
* The numbers array contains your source values, ranging
* from 1 to valueRange. The result array contains a random,
* non-repeating sample of the numbers array.
*/
int numbers[valueRange];
int result[sampleSize];
for ( int i = 0; i < valueRange; i++ )
numbers[i] = i + 1;
srand( time( NULL ));
for ( int i = 0; i < sampleSize; i++ )
{
int sampleIndex = rand() % valueRange;
result[i] = numbers[sampleIndex];
numbers[sampleIndex] = numbers[ valueRange - 1 ];
valueRange--;
}
for ( int i = 0; i < sampleSize; i++ )
printf( "result[%4d] = %d\n", i, result[i] );
return 0;
}
示例会话:
[fbgo448@n9dvap997]~/prototypes/rand: ./stackrand
How many samples do you want to take: 10
What is the range of values, starting from 1: 10
result[ 0] = 5
result[ 1] = 6
result[ 2] = 7
result[ 3] = 4
result[ 4] = 10
result[ 5] = 3
result[ 6] = 2
result[ 7] = 8
result[ 8] = 1
result[ 9] = 9
[fbgo448@n9dvap997]~/prototypes/rand: ./stackrand
How many samples do you want to take: 10
What is the range of values, starting from 1: 10
result[ 0] = 9
result[ 1] = 3
result[ 2] = 7
result[ 3] = 1
result[ 4] = 4
result[ 5] = 8
result[ 6] = 2
result[ 7] = 5
result[ 8] = 6
result[ 9] = 10
[fbgo448@n9dvap997]~/prototypes/rand: ./stackrand
How many samples do you want to take: 10
What is the range of values, starting from 1: 100
result[ 0] = 28
result[ 1] = 90
result[ 2] = 100
result[ 3] = 4
result[ 4] = 15
result[ 5] = 76
result[ 6] = 3
result[ 7] = 60
result[ 8] = 65
result[ 9] = 21
使用像这样的可变长度数组时要小心;如果为您的范围或样本大小输入足够大的值,则会超出堆栈空间并出现运行时错误。使用malloc
或calloc
分配空间会更安全,但对于小范围和样本大小,这肯定更容易,更轻松。
此外,您应添加一些代码以确保您的样本量始终小于您的值范围。或者Bad Things™会发生。
答案 4 :(得分:-1)
the following code may be what your looking for:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int cmpfunc (const void * a, const void * b);
int main()
{
puts("How many numbers do you want to generate?");
int n;
scanf("%d", &n);
puts("What should be the largest number possible?");
int m;
scanf("%d", &m);
int result[n];
int i;
srand(time(NULL));
for(i=0;i<n;i++)
{
result[i] = rand() % m;
}
qsort(result, n, sizeof(int), cmpfunc); //sorting the result array
for(i=0;i<n;i++)
{
printf("%d\n", result[i]);
}
getchar();
return 0;
} // end function: main
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
} // end function: cmpfunc