LOFTER for ipad —— 让兴趣,更有趣

点击下载 关闭

LOFTER-网易轻博

sort

880浏览    217参与
柴犬大富

喜欢的风格,美腻的店,SORT,成都太古里负一楼,方所书店门口。

喜欢的风格,美腻的店,SORT,成都太古里负一楼,方所书店门口。

livet8

8种主要排序算法的C#实现 (二)

归并排序


归并排序也是采用“分而治之”的方式。刚发现分治法是一种算法范式,我还一直以为是一种需要意会的思想呢。


不好意思了,孤陋寡闻了,哈哈!


原理:将两个有序的数列,通过比较,合并为一个有序数列。 维基入口


为方便理解,此处实现用了List<int>的一些方法,随后有IList<int>版本。


实现如下:


public static List<int> MergeSortOnlyList(List<int> data, int low, int high)...



 



归并排序


归并排序也是采用“分而治之”的方式。刚发现分治法是一种算法范式,我还一直以为是一种需要意会的思想呢。


不好意思了,孤陋寡闻了,哈哈!


原理:将两个有序的数列,通过比较,合并为一个有序数列。 维基入口


为方便理解,此处实现用了List<int>的一些方法,随后有IList<int>版本。


实现如下:


public static List<int> MergeSortOnlyList(List<int> data, int low, int high)

        {

            if (low == high)

                return new List<int> { data[low] };

            List<int> mergeData = new List<int>();

            int mid = (low + high) / 2;

            List<int> leftData = MergeSortOnlyList(data, low, mid);

            List<int> rightData = MergeSortOnlyList(data, mid + 1, high);

            int i = 0, j = 0;

            while (true)

            {

                if (leftData[i] < rightData[j])

                {

                    mergeData.Add(leftData[i]);

                    if (++i == leftData.Count)

                    {

                        mergeData.AddRange(rightData.GetRange(j, rightData.Count - j));

                        break;

                    }

                }

                else

                {

                    mergeData.Add(rightData[j]);

                    if (++j == rightData.Count)

                    {

                        mergeData.AddRange(leftData.GetRange(i, leftData.Count - i));

                        break;

                    }

                }

            }

            return mergeData;

        }


        public static List<int> MergeSortOnlyList(List<int> data)

        {

            data = MergeSortOnlyList(data, 0, data.Count - 1);  //不会改变外部引用 参照C#参数传递

            return data;

        }

过程解析:将数列分为两部分,分别得到两部分数列的有序版本,然后逐个比较,将比较出的小数逐个放进


新的空数列中。当一个数列放完后,将另一个数列剩余数全部放进去。


IList<int>版本


实现如下:


public static IList<int> MergeSort(IList<int> data)

        {

            data = MergeSort(data, 0, data.Count - 1);

            return data;

        }


        public static IList<int> MergeSort(IList<int> data, int low, int high)

        {

            int length = high - low + 1;

            IList<int> mergeData = NewInstance(data, length);

            if (low == high)

            {

                mergeData[0] = data[low];

                return mergeData;

            }

            int mid = (low + high) / 2;

            IList<int> leftData = MergeSort(data, low, mid);

            IList<int> rightData = MergeSort(data, mid + 1, high);

            int i = 0, j = 0;

            while (true)

            {

                if (leftData[i] < rightData[j])

                {

                    mergeData[i + j] = leftData[i++]; //不能使用Add,Array Length不可变

                    if (i == leftData.Count)

                    {

                        int rightLeft = rightData.Count - j;

                        for (int m = 0; m < rightLeft; m++)

                        {

                            mergeData[i + j] = rightData[j++];

                        }

                        break;

                    }

                }

                else

                {

                    mergeData[i + j] = rightData[j++];

                    if (j == rightData.Count)

                    {

                        int leftleft = leftData.Count - i;

                        for (int n = 0; n < leftleft; n++)

                        {

                            mergeData[i + j] = leftData[i++];

                        }

                        break;

                    }

                }

            }

            return mergeData;


        }

过程原理与上个一样,此处就不赘述了。


堆排序


堆排序是根据堆这种数据结构设计的一种算法。堆的特性:父节点的值总是小于(或大于)它的子节点。近似二叉树。


原理:将数列构建为最大堆数列(即父节点总是最大值),将最大值(即根节点)交换到数列末尾。这样要排序的数列数总和减少,


同时根节点不再是最大值,调整最大堆数列。如此重复,最后得到有序数列。 维基入口   有趣的演示


实现准备:如何将数列构造为堆——父节点i的左子节点为2i+1,右子节点为2i+2。节点i的父节点为floor((i-1)/2)。


实现如下(这个实现判断和临时变量使用太多,导致效率低,评论中@小城故事提出了更好的实现):


public static void HeapSort(IList<int> data)

        {

            BuildMaxHeapify(data);

            int j = data.Count;

            for (int i = 0; i < j; )

            {

                Swap(data, i, --j);

                if (j - 2 < 0)  //只剩下1个数 j代表余下要排列的数的个数

                    break;

                int k = 0;

                while (true)

                {

                    if (k > (j - 2) / 2) break;  //即:k > ((j-1)-1)/2 超出最后一个父节点的位置  

                    else

                    {

                        int temp = k;

                        k = ReSortMaxBranch(data, k, 2 * k + 1, 2 * k + 2, j - 1);

                        if (temp == k) break;

                    }

                }

            }

        }


        public static void BuildMaxHeapify(IList<int> data)

        {

            for (int i = data.Count / 2 - 1; i >= 0; i--)  //(data.Count-1)-1)/2为数列最大父节点索引

            {

                int temp = i;

                temp = ReSortMaxBranch(data, i, 2 * i + 1, 2 * i + 2, data.Count - 1);

                if (temp != i)

                {

                    int k = i;

                    while (k != temp && temp <= data.Count / 2 - 1)

                    {

                        k = temp;

                        temp = ReSortMaxBranch(data, temp, 2 * temp + 1, 2 * temp + 2, data.Count - 1);

                    }

                }

            }

        }


        public static int ReSortMaxBranch(IList<int> data, int maxIndex, int left, int right, int lastIndex)

        {

            int temp;

            if (right > lastIndex)  //父节点只有一个子节点

                temp = left;

            else

            {

                if (data[left] > data[right])

                    temp = left;

                else temp = right;

            }


            if (data[maxIndex] < data[temp])

                Swap(data, maxIndex, temp);

            else temp = maxIndex;

            return temp;

        }

过程解析:BuildMaxHeapify为排序前构建的最大堆数列方法,主要内容为从最后一个父节点开始往前将每个三角组合


(即父节点与它的两个子节点)符合父节点值最大的规则。ReSortMaxBranch为将三角调整为父节点值最大,


并返回该值之前的索引,用来判断是否进行了交换,以及原来的父节点值交换到了什么位置。在HeapSort里首先


构建了最大堆数列,然后将根节点交换到末尾,根节点不是最大值了,在while语句中对最大堆数列进行调整。


插曲:自从看了Martin Fowler大师《重构》第三版,我发现我更不喜欢写注释了。每次都想着尽量让方法的名字更贴切,


即使会造成方法的名字很长很丑。这算不算曲解了大师的意思啊!?上面的代码注释都是写博客的时候现加的(源代码很干净的。汗!)。


希尔排序


希尔排序是插入排序的一种更高效的改进版本。


在前面介绍的插入排序,我们知道1.它对有序数列排序的效率是非常高的 2.要排序的数向前移动是一步步进行的导致插入排序效率低。


希尔排序正是利用第一点,改善第二点,达到更理想的效果。


原理:通过奇妙的步长,插入排序间隔步长的元素,随后逐渐缩短步长至1,实现数列的插入排序。 维基入口


疑问:可以想象到排序间隔步长的数,会逐渐让数列变得有序,提升最后步长为1时标准插入排序的效率。在维基上看到这么


一句话“可能希尔排序最重要的地方在于当用较小步长排序后,以前用的较大步长仍然是有序的”注意用词是‘可能’。我的疑问是


这是个正确的命题吗?如何证明呢?看维基上也是由果推因,说是如果不是这样,就不会排序那么快了。可这我感觉还是太牵强了,


哪位大哥发现相关资料,希望能分享出来,不胜感激。


实现如下:


public static void ShellSortCorrect(IList<int> data)

        {

            int temp;

            for (int gap = data.Count / 2; gap > 0; gap /= 2)

            {

                for (int i = gap; i < data.Count; i++)      // i+ = gap 改为了 i++

                {

                    temp = data[i];

                    for (int j = i - gap; j >= 0; j -= gap)

                    {

                        if (data[j] > temp)

                        {

                            data[j + gap] = data[j];

                            if (j == 0)

                            {

                                data[j] = temp;

                                break;

                            }

                        }

                        else

                        {

                            data[j + gap] = temp;

                            break;

                        }

                    }

                }

            }

        }

基数排序


基数排序是一种非比较型整数排序。


“非比较型”是什么意思呢?因为它内部使用的是桶排序,而桶排序是非比较型排序。


这里就要说说桶排序了。一个非常有意思的排序。


桶排序


原理:取一定数量(数列中的最大值)的编好序号的桶,将数列每个数放进编号为它的桶里,然后将不是空的桶依次倒出来,


就组成有序数列了。  维基入口


好吧!聪明的人一眼就看出桶排序的破绽了。假设只有两个数1,10000,岂不是要一万个桶!?这确实是个问题啊!我也


没想出解决办法。我起初也以为桶排序就是一个通过牺牲空间来换取时间的排序算法,它不需要比较,所以是非比较型算法。


但看了有趣的演示的桶排序后,发现世界之大,你没有解决,不代表别人没解决,睿智的人总是很多。


1,9999的桶排序实现:new Int[2];总共有两个数,得出最大数9999的位数4,取10的4次幂即10000作为分母,


要排序的数(1或9999)作为分子,并乘以数列总数2,即1*2/10000,9999*2/10000得到各自的位置0,1,完成排序。


如果是1,10000进行排序的话,上面的做法就需要稍微加一些处理——发现最大数是10的n次幂,就将它作为分母,并


放在数列末尾就好了。


如果是9999,10000进行排序的话,那就需要二维数组了,两个都在位置1,位置0没数。这个时候就需要在放


入每个位置时采用其它排序(比如插入排序)办法对这个位置的多个数排序了。


为基数排序做个过渡,我这里实现了一个个位数桶排序


涉及到了当重复的数出现的处理。


实现如下:


public static void BucketSortOnlyUnitDigit(IList<int> data)

        {

            int[] indexCounter = new int[10];

            for (int i = 0; i < data.Count; i++)

            {

                indexCounter[data[i]]++;

            }

            int[] indexBegin = new int[10];

            for (int i = 1; i < 10; i++)

            {

                indexBegin[i] = indexBegin[i-1]+ indexCounter[i-1];

            }

            IList<int> tempList = NewInstance(data, data.Count);

            for (int i = 0; i < data.Count; i++)

            {

                int number = data[i];

                tempList[indexBegin[number]++] = data[i];

            }

            data = tempList;

        }

过程解析:indexCounter进行对每个数出现的频率的统计。indexBegin存储每个数的起始索引。


比如 1 1 2,indexCounter统计到0个0,2个1,1个2。indexBegin计算出0,1,2的起始索引分别为


0,0,2。当1个1已取出排序,那索引将+1,变为0,1,2。这样就通过提前给重复的数空出位置,解决了


重复的数出现的问题。当然,你也可以考虑用二维数组来解决重复。


下面继续基数排序。


基数排序原理:将整数按位数切割成不同的数字,然后按每个位数分别比较。


取得最大数的位数,从低位开始,每个位上进行桶排序。


实现如下:


public static IList<int> RadixSort(IList<int> data)

        {

            int max = data[0];

            for (int i = 1; i < data.Count; i++)

            {

                if (data[i] > max)

                    max = data[i];

            }

            int digit = 1;

            while (max / 10 != 0)

            {

                digit++;

                max /= 10;

            }

            for (int i = 0; i < digit; i++)

            {

                int[] indexCounter = new int[10];

                IList<int> tempList = NewInstance(data, data.Count);

                for (int j = 0; j < data.Count; j++)

                {

                    int number = (data[j] % Convert.ToInt32(Math.Pow(10, i + 1))) / Convert.ToInt32(Math.Pow(10, i));  //得出i+1位上的数

                    indexCounter[number]++;

                }

                int[] indexBegin = new int[10];

                for (int k = 1; k < 10; k++)

                {

                    indexBegin[k] = indexBegin[k - 1] + indexCounter[k - 1];

                }

                for (int k = 0; k < data.Count; k++)

                {

                    int number = (data[k] % Convert.ToInt32(Math.Pow(10, i + 1))) / Convert.ToInt32(Math.Pow(10, i));

                    tempList[indexBegin[number]++] = data[k];

                }

                data = tempList;

            }

            return data;

        }

过程解析:得出最大数的位数,从低位开始桶排序。我写的这个实现代码并不简洁,但逻辑更清晰。


后面测试的时候我们就会发现,按理来说这个实现也还行吧! 但并不如想象的那么快!


循环的次数太多?(统计频率n次+9次计算+n次放到新的数组)*位数。


创建的新实例太多?(new int[10]两次+NewInstance is反射判断创建实例+new int[n])*位数


测试比较


添加随机数组,数组有序校验,微软Linq排序


代码如下:


public static int[] RandomSet(int length, int max)

        {

            int[] result = new int[length];

            Random rand = new Random();

            for (int i = 0; i < result.Length; i++)

            {

                result[i] = rand.Next(max);

            }

            return result;

        }


        public static bool IsAscOrdered(IList<int> data)

        {

            bool flag = true;

            for (int i = 0; i < data.Count - 1; i++)

            {

                if (data[i] > data[i + 1])

                    flag = false;

            }

            return flag;

        }


        public static void TestMicrosoft(IList<int> data)

        {

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            List<int> result = data.OrderBy(a => a).ToList();

            stopwatch.Stop();

            string methodName = "TestMicrosoft";

            int length = methodName.Length;

            for (int i = 0; i < 40 - length; i++)

            {

                methodName += " ";

            }

            Console.WriteLine(methodName +

                "  IsAscOrdered:" + IsAscOrdered(result) + "  Time:" + stopwatch.Elapsed.TotalSeconds);


        }

测试主体如下:


static void Main(string[] args)

        {

            int[] aa = RandomSet(50000, 99999);

            //int[] aa = OrderedSet(5000);

            Console.WriteLine("Array Length:" + aa.Length);

            RunTheMethod((Action<IList<int>>)SelectSort, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)BubbleSort, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)BubbleSortImprovedWithFlag, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)BubbleCocktailSort, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)InsertSort, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)InsertSortImprovedWithBinarySearch, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)QuickSortStrict, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)QuickSortRelax, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)QuickSortRelaxImproved, aa.Clone() as int[]);

            RunTheMethod((Func<IList<int>, IList<int>>)MergeSort, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)ShellSort, aa.Clone() as int[]);

            RunTheMethod((Func<IList<int>, IList<int>>)RadixSort, aa.Clone() as int[]);

            RunTheMethod((Action<IList<int>>)HeapSort, aa.Clone() as int[]);

            TestMicrosoft(aa.Clone() as int[]);

            Console.Read();

        }


        public static void RunTheMethod(Func<IList<int>, IList<int>> method, IList<int> data)

        {

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            IList<int> result = method(data);

            stopwatch.Stop();

            string methodName = method.Method.Name;

            int length = methodName.Length;

            for (int i = 0; i < 40 - length; i++)

            {

                methodName += " ";

            }

            Console.WriteLine(methodName +

                "  IsAscOrdered:" + IsAscOrdered(result) + "  Time:" + stopwatch.Elapsed.TotalSeconds);

        }


        public static void RunTheMethod(Action<IList<int>> method, IList<int> data)

        {

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            method(data);

            stopwatch.Stop();

            string methodName = method.Method.Name;

            int length = methodName.Length;

            for (int i = 0; i < 40 - length; i++)

            {

                methodName += " ";

            }

            Console.WriteLine(methodName +

                "  IsAscOrdered:" + IsAscOrdered(data) + "  Time:" + stopwatch.Elapsed.TotalSeconds);

        }

剩余代码折叠在此处


public static void Swap(IList<int> data, int a, int b)

        {

            int temp = data[a];

            data[a] = data[b];

            data[b] = temp;

        }


        public static int[] OrderedSet(int length)

        {

            int[] result = new int[length];

            for (int i = 0; i < length; i++)

            {

                result[i] = i;

            }

            return result;

        }

 

        public static IList<int> NewInstance(IList<int> data, int length)

        {

            IList<int> instance;

            if (data is Array)

            {

                instance = new int[length];

            }

            else

            {

                instance = new List<int>(length);

                for (int n = 0; n < length; n++)

                {

                    instance.Add(0);  // 初始添加

                }

            }

            return instance;

        }

 

以上动图由“图斗罗”提供


ねーあんた何にをしたいの?

【Java算法】Selection選擇排序String

import java.util.*;

public class SelectionSortStr {

public static void main(String[] args){

/**Both descending and ascending orders are also going

 * to be case sensitive. * */

Scanner input=new Scanner(System.in);

//Use comparable data type to compare strings easily

Comparable...

import java.util.*;

public class SelectionSortStr {

public static void main(String[] args){

/**Both descending and ascending orders are also going

 * to be case sensitive. * */

Scanner input=new Scanner(System.in);

//Use comparable data type to compare strings easily

Comparable[] arr=new Comparable[5];

for(int i=0;i<arr.length;i++){

System.out.println("Please enter the word No."+(i+1)+": ");

arr[i]=input.nextLine();

}

selectionSort(arr);//Calling selectionSort();

System.out.println("\nIn ascending Order:");

for(int i=arr.length-1;i>=0;i--){

//Output in descending Order

System.out.println(arr[i]);

}

System.out.println("\nIn decending Order:");

for(int i=0;i<arr.length;i++){

System.out.println(arr[i]+"");

    //Output in ascending order

    }

}

//Selection sort algorithm

public static void selectionSort(Comparable[] arr){

int i; int j;

for(i=0; i<arr.length-1;i++){

for(j=i+1; j<arr.length;j++){

//i+1=j because j is greater than i then they swap

if(arr[i].compareTo(arr[j])<0){//Swapping string values

Comparable temp=arr[i];

arr[i]=arr[j];

arr[j]=temp;

}

}

}

}

}


WinExec

sort uniq

cat index.html | grep -i "href"  |  cut -d "/" -f3  | sort  | uniq  -c   | sort  -n

cat ~/.bash_history | sort | uniq -c | sort -nr | head

---------------------------------

sort  ...

cat index.html | grep -i "href"  |  cut -d "/" -f3  | sort  | uniq  -c   | sort  -n

cat ~/.bash_history | sort | uniq -c | sort -nr | head

---------------------------------

sort  排序

uniq -c  去重并计数

sort -nr  (n按照计数排序。r倒序)

-----------------------------

用uniq命令可以删除相邻的重复行:

  uniq [file]


  但如果一文本中有重复却不相邻的行则无法删除,需要结合sort命令:

  sort [file]|uniq


  等效的sort命令是:

  sort -u [file]


  另外uniq命令有4个有用的选项:

  $uniq -d file 只输出file中的重复行,且只输出一次,但不输出唯一的行

  $uniq -u file 只输出file中的唯一行(当然是一次啦)

  $uniq -c file 在每行前显示重复次数,可与其他选项结合,例如-cu或-cd或-c

  $uniq -i file 比较时忽略大小写


Home Deco
很丰富 但很整齐!

很丰富  但很整齐! 

很丰富  但很整齐! 

Home Deco
很实用的书桌

很实用的书桌

很实用的书桌

Home Deco
很有设计感的收纳设计

很有设计感的收纳设计

很有设计感的收纳设计

Home Deco
五味杂陈,瓶瓶罐罐才是生活

五味杂陈,瓶瓶罐罐才是生活

五味杂陈,瓶瓶罐罐才是生活

日落之城

管道命令

      有时候,输出的数据太过繁杂,我们需要进行一些处理才能得到我们需要,这时候需要用到linux的管道命令。管道命令使用的是"|"这个界定符号。

      管道命令不是"连续执行命令",实际上"|"仅仅只能处理经由前面的命令传来的正确信息(stdout),对于stderr没有直接的处理能力,直接忽略。

      每个管道"|"...

      有时候,输出的数据太过繁杂,我们需要进行一些处理才能得到我们需要,这时候需要用到linux的管道命令。管道命令使用的是"|"这个界定符号。

      管道命令不是"连续执行命令",实际上"|"仅仅只能处理经由前面的命令传来的正确信息(stdout),对于stderr没有直接的处理能力,直接忽略。

      每个管道"|"后面接的第一个数据必须是命令,而且此命令必须能够接收stdin的数据(接收前一个命令传来的数据转为stdin),这样的命令才可以称之为管道命令,比如less,more,head,grep等。而 ls,mv等就不是管道命令了。

选取命令cut, grep

      选取命令的作用:将一段数据经过分析后,取出我们想要的。通常分析选取数据是针对行来分析的,而不是整篇进行分析。

cut

      功能:取出某段信息,其处理是以行为单位。

1、通过分隔字符来取出某一段

cut -d '分隔字符' -f [取出第几段]

      举个例子

echo $PATH | cut -d ':' -f 3,5

      意思就是,以":"为分隔符,然后列出第三个和第五个(第一个":"前面的数据算第一个)

2、取出某一段字符范围

cut -c [字符范围]

      这个适合于输出数据是整齐的格式,比如说:export的输出数据是:

declare -x ****AAIIOA

declare -x ****A)A)

declare -x ****A)A)

declare -x *****(*(

      若是我们不想要前面的那些共同信息,可以这样做

export | cut -c 12-

      就是所有的行都是取出从第12个字符开始以后的数据。字符范围也可以是12-20这样的具体范围。

      不过cut在处理多空格相连的情况时,会不太方便。

grep

      功能:grep的作用是对数据进行一行行的分析,若是当中有我们需要的信息,就将该行整个都拿出来。

grep [-acinv] [--color=auto] '查找的字符串' [file or stdin]

      -a:将binary文件以text文件的方式来查找数据;

      -c:计算找到'查找的字符串'的次数;

      -i:忽略大小写的不同;

      -n:顺便输出行号;

      -v:反向选择,显示不含有"查找的字符串"的那些行;

      --color=auto:将找到的关键字部分加以颜色显示。

      举例说明如下:

ls -al | grep 'root'

grep --color=auto 'openvswitch' /home/gavinzh/openwrt/Makefile

      第一行是用作管道命令;第二行是直接作用于文件来寻找关键字。

排序命令sort、uniq、wc

      排序命令可以对数据进行排序,统计。

sort

      功能:可以排序,而且可以根据不同的数据类型来进行排序(比如说按照数字来排、按照文字来排)。

sort [-fbMnrtuk] [file or stdin]

      -f:忽略大小写不同;

      -b:忽略最前面的空格部分;

      -M:以月份的名字来排序(DEC,JAN等);

      -n:使用“纯数字”来排序(默认是文字类型来排序);

      -r:反向排序;

      -u:就是uniq,相同的数据中仅出现一行;

      -t:分隔符,默认是以tab来分隔

      -k:与-t搭配使用,分隔完后以"第几个区间"来进行排序。

      举个例子:

cat /etc/passwd | sort

cat /etc/passwd | sort -t ':' -k 3 -n

      第一行默认就是以第一个数据来排序,而且是以文字的方式来排序。

      第二行中以":"分隔后,以第三区间来排序,由于默认是以文字类型来排序,所以加个 -n 参数来实现以数字方式来排序。

uniq

      功能:其作用和sort的-c参数相同,是要将重复的数据仅列出一个来显示。

uniq [-ic]

      -i:忽略大小写的不同。

      -c:进行计数。

      举个例子:

last | cut -d ' ' -f 1 | sort | uniq -c

      last来查看这个月登陆主机的用户,经过cut后只显示用户名,然后sort进行排序,最后uniq去掉重复的数据(连续的几个重复的,而不是所有的里面所有的重复的),并对每个登录用户的次数进行统计。

      由于uniq只是对连续的几个重复的才可以进行删除重复,所以我们要做的一般是先排序,再进行uniq。

wc

      功能:统计文件或者输入流有多少字,多少行,多少字符。

wc [-lwm] [file or stdin]

      -l:统计多少行;

      -w:统计多少字(英文单字);

      -m:统计多少字符。

      举个例子:

cat /etc/config network | wc

last | grep [a-zA-Z] | grep -v 'wtmp' | wc -l

      第一行默认是输出行数、字数、字符数。

      第二行由于last会输出空白行和wtmp行,所以用grep依次过滤,最后统计一下行数,就可以知道这一个月内登陆这个系统的总人数。

双向重定向tee

      不同于之前的重定向,tee命令可以实现在数据流输向屏幕的同时,也输出到文件或设备中。

 

tee [-a] filename

      -a:以追加的方式,将数据写入filename中。

      举个例子:

last | tee last.list | cut -d " " -f 1

     将last的输出先存到last.list中一份,然后再做处理后在屏幕显示。

切割命令split

      split命令可以将一个大文件依据大小或者行数来进行切割,弄成小文件;

split [-bl] file PREFIX

      -b:按照大小来切割时,就接个b参数,后面跟b, k, m等;

      -l:以行数来进行切割;

      PREFIX:代表前导符,可作为切割文件的前导文字。

      举个例子:

split -b 300k /etc/passwd passwd

      切完之后,目录下就有几个passwdaa、passwdbb、passwdcc。前导是我们加的,aa、bb、cc是系统加的。

cat passwd* >> passwdback

      利用数据流重定向就可以实现将几个文件来合成为一个文件。

ls -al / |split -l 10 - gavinzh

      后边的那个"-"就是代表stdin,若是需要stdout /stdin时,但偏偏没有文件,就可以用"-"来代表stdin或stdout。之前的grep中可以省略"-",原因是其[file]是作为最后一个参数,默认都是前面的stdout作为stdin来进行处理。

      关于这个"-"符号,再来看一个例子:

tar -cvf - /home | tar -xvf -

      前一个命令的stdout作为下一个命令的stdin,而且这些命令需要用到文件名的时候,stdin和stdout可以用"-"来替代。

      -cvf后面的那个 "-" 就代表压缩的输出流stdout(没有记录到文件,但是理解的时候可以视作把/home压缩后的一个压缩包文件名),后面的-xvf之后的 "-" 就代表前面的输出流作为这次的输入流stdin(理解的时候可以视作之前的压缩包文件名)。这样就不需要使用文件(文件名)了。

参数代换xargs

      xargs可以读入stdin的数据,以空格或者断行符来进行分辨,最终将stdin数据分隔成arguments,传给某个命令。

xargs [-epn] cmd

      -e:就是eof(end of file)的意思,后边可以接一个字符串,当xargs分析到这个字符串就会不会往下工作;

      -p:执行每个命令时,询问用户的意思;

      -n:接次数,每次cmd执行的时候,使用几个参数。

      举个例子:

cd /home/gavinzh; ls | sort | head -n 3 | xargs ls -al 

      首先ls一下并进行排序,取出前三行,然后把这前三个作为参数传入ls -al命令。

cd /home/gavinzh; ls | sort | xargs -n 3 -p ls -al 

      这行命令中,我们每次传入ls -al 3个参数,并询问用户是否确定操作。

      若是用到-e 参数,我们需要的是-e紧接着字符串,中间不能有空格。

      xargs的一个作用就是,有许多命令并不是管道命令(不能接收stdin的数据直接处理),所以通过xargs可以提取stdin中的关键信息作为参数,传入这些非管道命令中。例如上面的 ls 本身就不是管道命令,通过xargs就可以传入参数。









Web开发中的那些事儿

将一个文件排序

想将一个文件排序,即将文件中的多行排序

如a.txt

1、需要需要需要工

3、大规模需要

2、城

可以排序成

1、需要需要需要工

2、城

3、大规模需要

使用方法是:

sort a.txt>b.txt

将文件a.txt排序后导入b.txt


想将一个文件排序,即将文件中的多行排序

如a.txt

1、需要需要需要工

3、大规模需要

2、城

可以排序成

1、需要需要需要工

2、城

3、大规模需要

使用方法是:

sort a.txt>b.txt

将文件a.txt排序后导入b.txt


zhanggc

groovy grails List 集合 排序方法

转:http://stackoverflow.com/questions/17223851/sort-list-by-date-in-descending-order-groovy-madness  

List list = new ArrayList()

//按照createDate升序排序

list .sort({it?.createDate}) 

//按照createDate降序排序

ist .reverse()


转:http://stackoverflow.com/questions/17223851/sort-list-by-date-in-descending-order-groovy-madness  

List list = new ArrayList()

//按照createDate升序排序

list .sort({it?.createDate}) 

//按照createDate降序排序

ist .reverse()


Home Deco
拥有属于自己的手工制作区,也就...

拥有属于自己的手工制作区,也就拥有了一堆大大小小的工具和材料。如何让这些工具和材料不会占据你的空间,同时在需要的时候又你来说,会做,当然也会收。

拥有属于自己的手工制作区,也就拥有了一堆大大小小的工具和材料。如何让这些工具和材料不会占据你的空间,同时在需要的时候又你来说,会做,当然也会收。

Web开发中的那些事儿

python list sort方法使用

对一个list或者tunple根据参数来排序

L = [(1,1,2,3),(5,3,6,2),(2,2,1,2),(4,2,1,3),(1,2,1,2)]

L.sort(key=lambda x:(x[0],x[2]))

>>输出L:[(1, 2, 1, 2), (1, 1, 2, 3), (2, 2, 1, 2), (4, 2, 1, 3), (5, 3, 6, 2)]

 L.sort(key=lambda x:(x[0],x[2]),reverse=True)逆序排列

[(5, 3, 6, 2), (4, 2, 1, 3), (2, 2, 1, 2)...

对一个list或者tunple根据参数来排序

L = [(1,1,2,3),(5,3,6,2),(2,2,1,2),(4,2,1,3),(1,2,1,2)]

L.sort(key=lambda x:(x[0],x[2]))

>>输出L:[(1, 2, 1, 2), (1, 1, 2, 3), (2, 2, 1, 2), (4, 2, 1, 3), (5, 3, 6, 2)]

 L.sort(key=lambda x:(x[0],x[2]),reverse=True)逆序排列

[(5, 3, 6, 2), (4, 2, 1, 3), (2, 2, 1, 2), (1, 1, 2, 3), (1, 2, 1, 2)]

对于数据排序,可以直接加负号

L.sort(key=lambda x:(x[0],-x[2]))

[(1, 1, 2, 3), (1, 2, 1, 2), (2, 2, 1, 2), (4, 2, 1, 3), (5, 3, 6, 2)]

LOFTER

让兴趣,更有趣

简单随性的记录
丰富多彩的内容
让生活更加充实

下载移动端
关注最新消息