【问题标题】:Permutation columns without repetition无重复的排列列
【发布时间】:2012-01-23 22:38:40
【问题描述】:

谁能给我一些代码或算法或其他东西来解决以下问题? 我有几个文件,每个文件都有不同的列数,例如:

$> cat file-1   
1 2
$> cat file-2
1 2 3
$> cat file-3
1 2 3 4

我想减去列的绝对值并除以每个不同列的一行中所有的总和一次(没有重复列对的组合):

in file-1 case I need to get:

0.3333                    # because |1-2/(1+2)|

in file-2 case I need to get:

0.1666 0.1666 0.3333      # because |1-2/(1+2+3)| and |2-3/(1+2+3)| and |1-3/(1+2+3)|

in file-3 case I need to get:

0.1 0.2 0.3 0.1 0.2 0.1   # because |1-2/(1+2+3+4)| and |1-3/(1+2+3+4)| and |1-4/(1+2+3+4)| and |2-3/(1+2+3+4)| and |2-4/(1+2+3+4)| and |3-4/(1+2+3+4)|

【问题讨论】:

    标签: linux bash shell sed awk


    【解决方案1】:

    虽然我猜你在输入数据中犯了一个小错误,但这应该可以工作。根据您的第三个模式,以下数据应该是 -

    代替:

    in file-2 case I need to get:
    
    0.1666 0.1666 0.3333      # because |1-2/(1+2+3)| and |2-3/(1+2+3)| and |1-3/(1+2+3)|
    

    应该是:

    in file-2 case I need to get:
    
    0.1666 0.3333 0.1666     # because |1-2/(1+2+3)| and |1-3/(1+2+3)| and |2-3/(1+2+3)|
    

    这里是awk 一个班轮:

    awk '
    NF{
        a=0;
        for(i=1;i<=NF;i++)
        a+=$i;
        for(j=1;j<=NF;j++)
        {
            for(k=j;k<NF;k++)
            printf("%s ",-($j-$(k+1))/a)
            }
        print "";
        next;
        }1' file
    

    短版:

    awk '
    NF{for (i=1;i<=NF;i++) a+=$i; 
    for (j=1;j<=NF;j++){for (k=j;k<NF;k++) printf("%2.4f ",-($j-$(k+1))/a)}
    print "";a=0;next;}1' file
    

    输入文件:

    [jaypal:~/Temp] cat file
    1 2
    
    1 2 3
    
    1 2 3 4
    

    测试:

    [jaypal:~/Temp] awk '
    NF{
        a=0;
        for(i=1;i<=NF;i++)
        a+=$i;
        for(j=1;j<=NF;j++)
        {
            for(k=j;k<NF;k++)
            printf("%s ",-($j-$(k+1))/a)
            }
        print "";
        next;
        }1' file
    0.333333 
    
    0.166667 0.333333 0.166667 
    
    0.1 0.2 0.3 0.1 0.2 0.1 
    

    从较短的版本测试:

    [jaypal:~/Temp] awk '
    NF{for (i=1;i<=NF;i++) a+=$i; 
    for (j=1;j<=NF;j++){for (k=j;k<NF;k++) printf("%2.4f ",-($j-$(k+1))/a)}
    print "";a=0;next;}1' file 
    0.3333 
    
    0.1667 0.3333 0.1667 
    
    0.1000 0.2000 0.3000 0.1000 0.2000 0.1000
    

    【讨论】:

      【解决方案2】:

      @Jaypal 也打败了我!这是我所拥有的:

      awk '{for (x=1;x<=NF;x++) sum += $x; for (i=1;i<=NF;i++) for (j=2;j<=NF;j++) if (i < j) printf ("%.1f ",-($i-$j)/sum)} END {print ""}' file.txt
      

      输出:

      0.1 0.2 0.3 0.1 0.2 0.1
      

      打印到小数点后一位。

      @Jaypal,有没有快速打印绝对值的方法?也许喜欢:abs(value)

      编辑:

      @Jaypal,是的,我也尝试过搜索,但找不到简单的东西 :-( 似乎 if ($i &lt; 0) $i = -$i 是要走的路。我想你可以使用 sed 删除任何减号:

      awk '{for (x=1;x<=NF;x++) sum += $x; for (i=1;i<=NF;i++) for (j=2;j<=NF;j++) if (i < j) printf ("%.1f ", ($i-$j)/sum)} {print ""}' file.txt | sed "s%-%%g"
      

      干杯!

      【讨论】:

        【解决方案3】:

        因为看起来像作业,我会照办的。

        要查找文件中存在的总数,您可以使用

        cat filename | wc -w
        

        通过以下方式查找 first_number:

        cat filename | cut -d " " -f 1
        

        在文件中求和:

        cat filename | tr " " "+" | bc
        

        现在,你有 total_nos,使用类似:

        for i in {seq 1 1 $total_nos}
        do
            #Find the numerator by first_number - $i
            #Use the sum you got from above to get the desired value.
        done
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-18
          • 2020-02-02
          • 2012-09-21
          相关资源
          最近更新 更多