提高C程序的计算速度
我有以下问题: 给定2个N个数字的文件,如 file1.dat:1,2,3,4,5,6,7,8,9,0 file2.dat:2,5,4,7,6,9,8,1,0,3 我想知道第一个文件中两个连续数字的顺序在第二个文件(包含相同数字)中改变了多少次。例如,在文件1中,我们开始查找1和2,在第二个文件中,2位于1之前,因此顺序发生了变化;在第一个文件中是9,然后是0,在第二个文件中保持此顺序 我编写了以下程序:提高C程序的计算速度,c,C,我有以下问题: 给定2个N个数字的文件,如 file1.dat:1,2,3,4,5,6,7,8,9,0 file2.dat:2,5,4,7,6,9,8,1,0,3 我想知道第一个文件中两个连续数字的顺序在第二个文件(包含相同数字)中改变了多少次。例如,在文件1中,我们开始查找1和2,在第二个文件中,2位于1之前,因此顺序发生了变化;在第一个文件中是9,然后是0,在第二个文件中保持此顺序 我编写了以下程序: #include <stdio.h> #include <stdlib.
#include <stdio.h>
#include <stdlib.h>
#define N 32421
int main () {
int A[N], B[N];
int i,j,k=0,count=0;
FILE *fp;
if ((fp = fopen ("file1.dat", "r")) == NULL) {
printf ("Error opening file 1\n");
exit (EXIT_FAILURE);
}
for (i = 0; i < N; i++)
fscanf (fp, "%d", &A[i]);
fclose (fp);
if ((fp = fopen ("file2.dat", "r")) == NULL) {
printf ("Error opening file 2\n");
exit (EXIT_FAILURE);
}
for (i = 0; i < N; i++)
fscanf (fp, "%d", &B[i]);
fclose (fp);
for(i=0; i<N-1; i++)
for(j=0; j<N; j++)
for(k=0 ; k<N; k++)
if(B[j]==A[i] && B[k]==A[i+1] && k < j )
count++;
printf("The number of inversion is: %d\n",count);
return 0;
}
#包括
#包括
#定义N 32421
int main(){
int A[N],B[N];
int i,j,k=0,count=0;
文件*fp;
if((fp=fopen(“file1.dat”,“r”))==NULL){
printf(“打开文件1时出错”);
退出(退出失败);
}
对于(i=0;ifor(i=0;ifor(i=0;i),这里的关键是“第一个文件中的两个连续数字”
不需要执行O(N^2)循环。事实上,您可以使用动态规划方法,利用以下条件:
- 数字是不同的
- 对于任何一组
N
数字,数字值为0..N-1
(这是我的假设)
- 对于第一个文件中的任意两个连续数字
A
和B
,如果您在遇到B
时已经遇到A
,则顺序将保留在第二个文件中
请注意我关于值的假设。如果该假设是错误的,那么您可以使用当前接受的O(N^2)-ish答案(尽管您可以构建一个树来索引值,最坏的情况是O(N.log(N))
如果您可以直接索引这些值,那么这个问题就成了线性问题。这里的关键是“第一个文件中有两个连续的数字”
不需要执行O(N^2)循环。事实上,您可以使用动态规划方法,利用以下条件:
- 数字是不同的
- 对于任何一组
N
数字,数字值为0..N-1
(这是我的假设)
- 对于第一个文件中的任意两个连续数字
A
和B
,如果您在遇到B
时已经遇到A
,则顺序将保留在第二个文件中
请注意我关于值的假设。如果该假设是错误的,那么您可以使用当前接受的O(N^2)-ish答案(尽管您可以构建一个树来索引值,最坏的情况是O(N.log(N))
如果你能直接索引这些值,那么这个问题就成了线性问题。两个长度为N的数组之间的倒数是
如果N为1,则反转数为0
否则,它是第一个数组的最后N-1个元素与第二个数组(不包括第一个数组的第一个元素)之间的倒数加上第一个数组的第一个元素在第二个数组中的位置
递归万岁:)
#包括
#包括
静态整数查找(整数a、整数*b、大小\u t n){
尺寸k=0;
而(k
长度为N的两个数组之间的反转数为
如果N为1,则反转数为0
否则,它是第一个数组的最后N-1个元素与第二个数组(不包括第一个数组的第一个元素)之间的倒数加上第一个数组的第一个元素在第二个数组中的位置
递归万岁:)
#包括
#包括
静态整数查找(整数a、整数*b、大小\u t n){
尺寸k=0;
而(k
所有的数字都是不同的吗?您可能可以在loops@pmg,中断可能是一个解决方案,但我不知道如何在程序中写入它们。这些数字都是不同的,我对C很生疏……但是,fscanf
如何忽略,
。它会自动这样做吗?所有的数字都是不同的吗你可能可以在你的电脑里做一些break
ingloops@pmg,中断可能是一个解决方案,但我不知道如何在程序中编写它们。这些数字都是不同的,我对C很生疏……但是fscanf
如何忽略,
。它会自动完成吗?很好。你还可以查找(B[I+1]==a[k])k从N开始,当j接近N时停在k>j。@pfnuesel是的,这确实是一种改进方法:)第二个脚本不起作用。j循环不会开始,因为pos2从-1开始。我一直在测试第一个脚本,不幸的是它不起作用(昨天晚上我试过了,但我使用的数据集不正确,今天我使用了正确的数据集,但它仍然需要1个多小时才能给出结果。):SNice。你也可以查找(B[I+1]==A[k]),其中k从N开始,在N停止
int a;
for(i=0;i<N-1;i++){
a=0;
for(j=0;j<N;j++){
for(k=0;k<N;k++){
if(A[i]==B[j] && A[i+1]==B[k] && k<j) {
count++;
break;
a=1;
} if(A[i]==B[j] && A[i+1]==B[k] && j<k){
break;
a=1;
}
}
if(a==1){
break;
}
}
}
for(i=0; i<N-1; i++) {
//looking for the position of B[i] in A
j=-1;
while ( A[++j] != B[i] ) {}
//now A[j] is B[i]
for (k= 0 ; k < j; k++) {
//is the next in B in a previous position in A ?
if (B[i+1] == A[k]) {
count++;
break;
}
}
}
int pos1, pos2;
for(i=0; i<N-1; i++) {
pos2=-1;
for(j=-1; j<N && pos1 != -1 && pos2 != -1; j++) { //will stop if both are found
if (pos1 == -1 && B[i]==A[j]) pos1 = j; //found the position of a num
if (B[i+1]==A[j]) pos2 = j; //found the position of the next num
if (pos2 < pos1) {
count++;
}
}
pos1 = pos2; //useful for next loop..
}
#include <stdlib.h>
#include <string.h>
static int find(int a, int *b, size_t n) {
size_t k = 0;
while (k < n) {
if (b[k] == a) return k;
k++;
}
return -1;
}
int ninversions(int *a, int *b, size_t n) {
if (n == 1) return 0;
size_t pos = find(*a, b, n);
if (pos == (size_t)-1) exit(EXIT_FAILURE);
int *newb = malloc((n - 1) * sizeof *newb);
memcpy(newb, b, pos * sizeof *b);
memcpy(newb + pos, b + pos + 1, (n - pos - 1) * sizeof *b);
int retval = pos + ninversions(a + 1, newb, n - 1);
free(newb);
return retval;
}