获取向量中仅出现一次的值

获取向量中仅出现一次的值

我有一个按升序排列的数字向量(称为 t8_)

2 7 8 9 11 15 34 91 91 92 94

问题是有些数字出现两次。我不想删除它们,但它们必须成为两个不同的数字不是浮点。我首先想到的是遍历向量:

which(duplicated(t8)) - that would be 9 and then go on 

t8[which(duplicated(t8))]<-t8[which(duplicated(t8))]+1

下一个向量将是

2 7 8 9 11 15 34 91 92 92 94

重复相同的过程:

which(duplicated(t8)) - that would be 10 and the go on 

t8[which(duplicated(t8))]<-t8[which(duplicated(t8))]+1

当向量是

 2 7 8 9 11 15 34 91 92 993 94

我尝试过sort -usort -nu它们不起作用)。

有没有一种 perl 或 python 方法可以交互地执行此操作...直到不存在重复的数字?

我想用一个文件来执行此操作以放入该函数...编辑...

答案不适用于我的矢量文件: https://www.dropbox.com/s/vp67eiw4ns9rr07/num?dl=0

答案1

以下脚本从标准输入的每一行读取一个整数向量。

#!/bin/bash

while read -a vec; do
        # INT_MIN for bash: 32-bit bash also supports 64-bit integers.
        min=$((-1<<63)) 
        for ((i = 0; i < ${#vec[@]}; i++)); do
                (( min = vec[i] = vec[i] > min ? vec[i] : min + 1 ))
        done
        echo "${vec[@]}"
done

输入示例:

2 7 8 9 11 15 34 91 91 92 94
1 1 1 1 1 1 1 1 1 1
91 91 91
-1000 -900 -100 -100 -100 0 0 0
5 4 3 2 1 0
 1      1  1 1 1 

示例输出:

$ ./script.sh < input.txt 
2 7 8 9 11 15 34 91 92 93 94
1 2 3 4 5 6 7 8 9 10
91 92 93
-1000 -900 -100 -99 -98 0 1 2
5 6 7 8 9 10
1 2 3 4 5

如果输出不符合您的预期或想要的效果,请告诉我。


更新: 此版本会将来自 stdin 的所有行上的所有整数作为一个输入进行处理,而不是逐行处理。它将能够接受任意长度的行。

#!/bin/sh

min=$((-1<<63))

tr -s '[:space:]' '\n' |
while read val; do
        case ${val#[-+]} in
                ''|*[!0-9]*) continue ;;
        esac
        min=$((val > min ? val : min + 1))
        echo $min
done |
paste -s -d' ' -

会话示例:

$ echo -e '2 7 8 9 11 15 34 91 91 92 94' | ./script.sh
2 7 8 9 11 15 34 91 92 93 94
$ echo -e '91 91 91' | ./script.sh
91 92 93
$ echo -e '5 4 3 2 1 0' | ./script.sh
5 6 7 8 9 10
$ echo -e '-1000 -900 -100 -100 -100 0 0 0 +100 +100 +100' | ./script.sh
-1000 -900 -100 -99 -98 0 1 2 100 101 102
$ echo -e ' 1 1\n 1\n 1 \n1 \n1 ' | ./script.sh
1 2 3 4 5 6
$ echo -e 'a 1 b 2 3 c' | ./script.sh
1 2 3

答案2

也许这就是您所需要的:

#!usr/bin/perl                                                                                                                                                
use strict;
use warnings;

my@list=qw(2 7 8 9 11 15 34 91 91 92 94);
my%hash;


print "Input:\n@list\n";

foreach(@list)
{
    #count occurences for each element                                                                                                                        
    $hash{$_}++;
}

foreach my$key (keys %hash)
{
    TURN: while($hash{$key}>1)
    {
    #add a number between 1 and 10 to the duplicated value if                                                                                             
    #this value does not already exist                                                                                                                    
        for(my$i=1;$i<=10;$i++)
        {
            if(exists $hash{$key+$i})
            {
                next;
            }
            else
            {
                $hash{$key}--;
                $hash{$key+$i}=1;
                next TURN;
            }
        }
    }
}

my@result=sort{$a<=>$b}(keys %hash);

print "Result:\n@result\n";

此代码计算每个元素的出现次数,并将 1 到 10 之间的数字添加到该值中以获取尚不存在的元素。

相关内容