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

前端 未结 2 354
予麋鹿
予麋鹿 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 02:54

    I know that you already have an accepted clean answer.

    Just sharing:

    sgeorge-mn:~ sgeorge$ cat stack.sh 
    VALUE1=$1
    VALUE2=$2
    for POS in `sed 's/,/ /g' file1.dat`
    do
    ((COUNT++))
    if [[ $VALUE1 == $POS ]] ; then
        VAL1_POS=$COUNT
    fi
    
    if [[ $VALUE2 == $POS ]] ; then
            VAL2_POS=$COUNT
    fi
    done
    
    
    for MATCH in `sed 's/,/ /g' file2.dat`
    do
    ((COUNT2++))
    if [[ $VALUE1 == $MATCH ]] ; then
            VAL1_POS2=$COUNT2
    fi
    if [[ $VALUE2 == $MATCH ]] ; then
            VAL2_POS2=$COUNT2
    fi
    done
    
    if [[ $VAL1_POS -gt $VAL2_POS ]] ; then
        P1=1
    fi
    if [[ $VAL1_POS2 -gt $VAL2_POS2 ]] ; then
        P2=1
    fi
    
    if [[ $VAL1_POS -lt $VAL2_POS ]] ; then
        P1=2
    fi
    if [[ $VAL1_POS2 -lt $VAL2_POS2 ]] ; then
        P2=2
    fi
    
    if [[ $VAL1_POS -eq $VAL2_POS ]] ; then
        P1=3
    fi
    if [[ $VAL1_POS2 -eq $VAL2_POS2 ]] ; then
        P2=3
    fi
    
    if [[ $P1 == $P2 ]]; then
        echo "No order change"
    else
        echo "Order changed"
    fi
    

    How to execute the script:

    I am assuming following:

    • Both file have exactly same numbers in same order.
    • You will not give non existing number (not existing in file*.dat) as input to the script
    sgeorge-mn:~ sgeorge$ bash stack.sh 5 7
    No order change
    sgeorge-mn:~ sgeorge$ bash stack.sh 4 5
    Order changed
    sgeorge-mn:~ sgeorge$ bash stack.sh 9 0
    No order change
    sgeorge-mn:~ sgeorge$ bash stack.sh 1 2
    Order changed
    
    0 讨论(0)
  • 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

    0 讨论(0)
提交回复
热议问题