counting how many time the order of two consecutive number in a file are reversed in a second file in BASH

前端 未结 2 353
予麋鹿
予麋鹿 2021-01-07 02:24

I got the following problem:

Given 2 files of N numbers like

file1.dat: 1,2,3,4,5,6,7,8,9,0

file2.dat: 2,5,4,7,6,9,8,1,0,3

The file2.dat is a

2条回答
  •  有刺的猬
    2021-01-07 03:08

    I hope your two files obey the certain rules:

    • same amount of distinct number,
    • both files have single line

    I didn't do those format checking. see my solution:

    awk -F, 'FNR==NR{n=NF;for(i=1;i<=NF;i++)o[i]=$i;next;}
            {for(i=1;i<=NF;i++)v[$i]=i}
            END{ for(i=1;i<=n-1;i++) t+=v[o[i]]>v[o[i+1]]?1:0;
                    print "inversions:",t;
            }' file1 file2
    

    test:

    kent$  head file1 file2
    ==> file1 <==
    1,2,3,4,5,6,7,8,9,0
    
    ==> file2 <==
    2,5,4,7,6,9,8,1,0,3
    
    
    kent$  awk -F, 'FNR==NR{n=NF;for(i=1;i<=NF;i++)o[i]=$i;next;}
            {for(i=1;i<=NF;i++)v[$i]=i}
            END{ for(i=1;i<=n-1;i++) t+=v[o[i]]>v[o[i+1]]?1:0;
                    print "inversions:",t;
            }' file1 file2
    inversions: 5
    

    If you want to print some debug info, say, print inversion pairs as well, see this:

    kent$  awk -F, 'FNR==NR{n=NF;for(i=1;i<=NF;i++)o[i]=$i;next;}
            {for(i=1;i<=NF;i++)v[$i]=i}
            END{ for(i=1;i<=n-1;i++) {
    
            if(v[o[i]]>v[o[i+1]]){
                    print "inversion pair foud:"o[i],o[i+1]
                    t++;
            }
            }
                    print "inversions:",t;
            }' file1 file2
    
    inversion pair foud:1 2
    inversion pair foud:3 4
    inversion pair foud:4 5
    inversion pair foud:6 7
    inversion pair foud:8 9
    inversions: 5
    

    if you want some other information e.g. original index/order, changed order, they are also easy to be added.

    hope it helps.

    EDIT

    if your data files are in single-column format. try this:

     awk -F, 'FNR==NR{o[NR]=$0;next;}{v[$0]=FNR;n=FNR}
            END{ for(i=1;i<=n-1;i++) t+=v[o[i]]>v[o[i+1]]?1:0;
                    print "invertions:",t;
            }' file1 file2
    

    test screencast. just for testing my just written recording script ;)

    enter image description here

提交回复
热议问题