xml地图|网站地图|网站标签 [设为首页] [加入收藏]
获取某一路径下的所有文件名信息
分类:编程

贴代码了,这里使用的是C#控制台输出文件名到记事本中,文件名使用逗号隔开:

图片 1

写在前面

整个项目都托管在了 Github 上:

查找更为方便的版本见:https://alg4.ikesnowy.com

这一节内容可能会用到的库文件有 Merge,同样在 Github 上可以找到。

善用 Ctrl + F 查找题目。

using System;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        public static string FileName = "";

        public static void Main(string[] args)
        {
            bool isContinute = true;
            WriteMessage("结束程序请输入1");
            WriteMessage("请输入要获取文件名的路径:");
            string path = Console.ReadLine();
            do
            {
                if (string.IsNullOrEmpty(path))
                {
                    WriteMessage("路径不存在!请重新输入");
                }
                else
                {
                    DirectoryInfo dir = new DirectoryInfo(path);
                    if (dir.Exists == false)
                    {
                        WriteMessage("路径不存在!请重新输入");
                    }
                    else
                    {
                        FileName = "";
                        GetChildDicsName(dir);
                        WriteMessage(FileName);
                        Console.WriteLine("获取该路径下文件名成功!你可以继续输入新的路径");
                    }
                }
                path = Console.ReadLine();
                isContinute = path != "1";
            } while (isContinute);
        }

        public static DirectoryInfo[] GetChildDicsName(DirectoryInfo dir)
        {
            FileInfo[] fileArray = dir.GetFiles();
            DirectoryInfo[] childDirs = dir.GetDirectories();

            foreach (FileInfo file in fileArray)
            {
                FileName += file.Name + ",";
            }
            if (childDirs.Length > 0)
            {
                foreach (DirectoryInfo dirChild in childDirs)
                {
                    GetChildDicsName(dirChild);
                }
            }
            return childDirs;
        }

        public static void WriteMessage(string message)
        {
            Console.WriteLine(message);
            //File.Create(@"C:UsersPublicDesktoptest.txt");
            FileStream fs = File.Open(@"C:UsersPublicDesktoptest.txt", FileMode.Append);
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(message);  //这里是写入的内容
            sw.Close();
            fs.Close();
        }
    }
}

习题&题解

 

2.2.1

控制台信息截图:

题目

按照本书开头所示轨迹的格式给出原地归并排序的抽象 merge() 方法是如何将数组 A E Q S U Y E I N O S T 排序的。

图片 2

解答

图片 3

 

 

2.2.2

题目

按照算法 2.4 所示轨迹的格式给出自顶向下的归并排序是如何将数组 E A S Y Q U E S T I O N 排序的。

解答

图片 4

 

2.2.3

题目

用自底向上的归并排序解答练习 2.2.2

解答

图片 5

 

2.2.4

题目

是否当且仅当两个输入的子数组都有序时原地归并的抽象方法才能得到正确的结果?
证明你的结论,或者给出一个反例。

解答

是的,必须要两个子数组都有序时归并才能得到正确结果。
如果说数组不有序的话,那么最后只能得到两个数组的混合。
合并后的数组中,属于原有数组的元素的相对顺序不会被改变。
例如子数组 1 3 1 和 2 8 5 原地归并。
结果是 1 2 3 1 8 5,其中 1 3 1 和 2 8 5 的相对顺序不变。

 

2.2.5

题目

当输入数组的大小 N=39 时,给出自顶向下和自底向上的归并排序中各次归并子数组的大小及顺序。

解答

每次归并子数组的大小和顺序如下:

自顶向下

2, 3, 2, 5, 2, 3, 2, 5, 10, 2, 3, 2, 5, 2, 3, 2, 5, 10, 20, 2, 3, 2, 5, 2, 3, 2, 5, 10, 2, 3, 2, 5, 2, 2, 4, 9, 19, 39

自底向上

2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 8, 8, 8, 8, 7, 16, 16, 32, 39

 

2.2.6

题目

编写一个程序来计算自顶向下和自底向上的归并排序访问数组的准确次数。
使用这个程序将 N=1 至 512 的结果绘成曲线图,并将其和上限 6NlgN 相比较。

解答

图片 6

灰色是上限,蓝点是自顶向下,红点是自底向上。
由于两种排序访问数组的次数是一样的,因此蓝点和红点重合。

代码

给出绘图部分的代码:

using System;
using System.Windows.Forms;
using System.Drawing;
using Merge;

namespace _2._2._6
{
    /*
     * 2.2.6
     * 
     * 编写一个程序来计算自顶向下和自底向上的归并排序访问数组的准确次数。
     * 使用这个程序将 N=1 至 512 的结果绘成曲线图,
     * 并将其和上限 6NlgN 相比较。
     * 
     */
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Compute();
            Application.Run(new Form1());
        }

        static void Compute()
        {
            MergeSort mergeSort = new MergeSort();
            MergeSortBU mergeSortBU = new MergeSortBU();
            int[] mergeResult = new int[10];
            int[] mergeResultBU = new int[10];
            int[] upperBound = new int[10];

            // 进行计算
            int dataSize = 1;
            for (int i = 0; i < 10; i++)
            {
                int[] dataMerge = SortCompare.GetRandomArrayInt(dataSize);
                int[] dataMergeBU = new int[dataSize];
                dataMerge.CopyTo(dataMergeBU, 0);

                mergeSort.ClearArrayVisitCount();
                mergeSortBU.ClearArrayVisitCount();
                mergeSort.Sort(dataMerge);
                mergeSortBU.Sort(dataMergeBU);

                mergeResult[i] = mergeSort.GetArrayVisitCount();
                mergeResultBU[i] = mergeSortBU.GetArrayVisitCount();
                upperBound[i] = (int)(6 * dataSize * Math.Log(dataSize, 2));

                dataSize *= 2;
            }

            // 绘图
            Form2 plot = new Form2();
            plot.Show();
            Graphics graphics = plot.CreateGraphics();

            // 获得绘图区矩形。
            RectangleF rect = plot.ClientRectangle;
            float unitX = rect.Width / 10;
            float unitY = rect.Width / 10;

            // 添加 10% 边距作为文字区域。
            RectangleF center = new RectangleF
                (rect.X + unitX, rect.Y + unitY,
                rect.Width - 2 * unitX, rect.Height - 2 * unitY);

            // 绘制坐标系。
            graphics.DrawLine(Pens.Black, center.Left, center.Top, center.Left, center.Bottom);
            graphics.DrawLine(Pens.Black, center.Left, center.Bottom, center.Right, center.Bottom);
            graphics.DrawString("28000", plot.Font, Brushes.Black, rect.Location);
            graphics.DrawString("1024", plot.Font, Brushes.Black, center.Right, center.Bottom);
            graphics.DrawString("0", plot.Font, Brushes.Black, rect.Left, center.Bottom);

            // 初始化点。
            PointF[] grayPoints = new PointF[10]; // 上限
            PointF[] redPoints = new PointF[10];  // 自顶向下
            PointF[] bluePoints = new PointF[10]; // 自底向上
            unitX = center.Width / 11.0f;
            unitY = center.Height / 28000.0f;

            for (int i = 0; i < 10; i++)
            {
                grayPoints[i] = new PointF(center.Left + unitX * (i + 1), center.Bottom - (upperBound[i] * unitY) - 10);
                redPoints[i] = new PointF(center.Left + unitX * (i + 1), center.Bottom - (mergeResult[i] * unitY) - 10);
                bluePoints[i] = new PointF(center.Left + unitX * (i + 1), center.Bottom - (mergeResultBU[i] * unitY) - 10);
            }

            // 绘制点。
            for (int i = 0; i < 10; i++)
            {
                graphics.FillEllipse(Brushes.Gray, new RectangleF(grayPoints[i], new SizeF(10, 10)));
                graphics.FillEllipse(Brushes.Red, new RectangleF(redPoints[i], new SizeF(10, 10)));
                graphics.FillEllipse(Brushes.Blue, new RectangleF(bluePoints[i], new Size(10, 10)));
            }

            graphics.Dispose();
        }
    }
}

 

2.2.7

题目

证明归并排序的比较次数是单调递增的(即对于 N>0,C(N+1)>C(N))。

解答

根据书本给出的命题 G 和命题 H(中文版 P173/176,英文版 P275/279),
比较次数的下限 C(N) = 1/2 * NlgN
N 和 lgN 都是单调递增且大于零的(N>1),因此 C(N) 也是单调递增的

 

2.2.8

题目

假设将算法 2.4 修改为:
只要 a[mid] <= a[mid+1] 就不调用 merge() 方法,
请证明用归并排序处理一个已经有序的数组所需的比较次数是线性级别的。

解答

修改后的算法对已经有序的情况做了优化
数组对半切分并排序后,
如果 a[mid] < a[mid + 1](左半部分的最后一个元素小于右半部分的第一个元素)
那么我们可以直接合并数组,不需要再做多余的操作

现在的输入是一个已经排序的数组
算法唯一的比较发生在判断 a[mid] < a[mid + 1] 这个条件时
假定数组有 N 个元素
比较次数满足 T(N) = 2 * T(N / 2) + 1, T(1) = 0
转化为非递归形式即为:T(N) = cN / 2 + N - 1
其中 c 为任意正整数

 

2.2.9

题目

在库函数中使用 aux[] 这样的静态数组时不妥当的,
因为可能会有多个程序同时使用这个类。
实现一个不用静态数组的 Merge 类,
但也不要将 aux[] 变为 merge() 的局部变量(请见本书的答疑部分)。
提示:可以将辅助数组作为参数传递给递归的 sort() 方法。

解答

官方给出的归并排序实现中在 Sort 方法里初始化了 aux 数组。
源码见:

C#实现和官方的实现非常类似,

首先定义只接受一个参数的公开 Sort 方法,在这个方法里面初始化 aux 数组。

/// <summary>
/// 利用归并排序将数组按升序排序。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="a">待排序的数组。</param>
public override void Sort<T>(T[] a)
{
    T[] aux = new T[a.Length];
    Sort(a, aux, 0, a.Length - 1);
}

然后建立一个私有的递归 Sort 方法做实际的排序操作。

/// <summary>
/// 自顶向下地对数组指定范围内进行归并排序,需要辅助数组。
/// </summary>
/// <typeparam name="T">需要排序的元素类型。</typeparam>
/// <param name="a">原数组。</param>
/// <param name="aux">辅助数组。</param>
/// <param name="lo">排序范围起点。</param>
/// <param name="hi">排序范围终点。</param>
private void Sort<T>(T[] a, T[] aux, int lo, int hi) where T : IComparable<T>
{
    if (hi <= lo)
        return;
    int mid = lo + (hi - lo) / 2;
    Sort(a, aux, lo, mid);
    Sort(a, aux, mid + 1, hi);
    Merge(a, aux, lo, mid, hi);
}
代码
using System;

namespace Merge
{
    /// <summary>
    /// 归并排序类。
    /// </summary>
    public class MergeSort : BaseSort
    {
        /// <summary>
        /// 默认构造函数。
        /// </summary>
        public MergeSort() { }

        /// <summary>
        /// 利用归并排序将数组按升序排序。
        /// </summary>
        /// <typeparam name="T">数组元素类型。</typeparam>
        /// <param name="a">待排序的数组。</param>
        public override void Sort<T>(T[] a)
        {
            T[] aux = new T[a.Length];
            Sort(a, aux, 0, a.Length - 1);
        }

        /// <summary>
        /// 自顶向下地对数组指定范围内进行归并排序,需要辅助数组。
        /// </summary>
        /// <typeparam name="T">需要排序的元素类型。</typeparam>
        /// <param name="a">原数组。</param>
        /// <param name="aux">辅助数组。</param>
        /// <param name="lo">排序范围起点。</param>
        /// <param name="hi">排序范围终点。</param>
        private void Sort<T>(T[] a, T[] aux, int lo, int hi) where T : IComparable<T>
        {
            if (hi <= lo)
                return;
            int mid = lo + (hi - lo) / 2;
            Sort(a, aux, lo, mid);
            Sort(a, aux, mid + 1, hi);
            Merge(a, aux, lo, mid, hi);
        }

        /// <summary>
        /// 将指定范围内的元素归并。
        /// </summary>
        /// <typeparam name="T">数组元素类型。</typeparam>
        /// <param name="a">原数组。</param>
        /// <param name="aux">辅助数组。</param>
        /// <param name="lo">范围起点。</param>
        /// <param name="mid">范围中点。</param>
        /// <param name="hi">范围终点。</param>
        private void Merge<T>(T[] a, T[] aux, int lo, int mid, int hi) where T : IComparable<T>
        {
            for (int k = lo; k <= hi; k++)
            {
                aux[k] = a[k];
            }

            int i = lo, j = mid + 1;
            for (int k = lo; k <= hi; k++)
            {
                if (i > mid)
                {
                    a[k] = aux[j];
                    j++;
                }
                else if (j > hi)
                {
                    a[k] = aux[i];
                    i++;
                }
                else if (Less(aux[j], aux[i]))
                {
                    a[k] = aux[j];
                    j++;
                }
                else
                {
                    a[k] = aux[i];
                    i++;
                }
            }
        }
    }
}

 

2.2.10

题目

快速归并。
实现一个 merge() 方法,按降序将 a[] 的后半部分复制到 aux[],
然后将其归并回 a[] 中。这样就可以去掉内循环中检测某半边是否用尽的代码。
注意:这样的排序产生的结果是不稳定的(请见 2.5.1.8 节)。

解答

官方同样给出了 java 实现,如下:

private static void merge(Comparable[] a, int lo, int mid, int hi) { 
   for (int i = lo; i <= mid; i++)
      aux[i] = a[i]; 

   for (int j = mid+1; j <= hi; j++)
      aux[j] = a[hi-j+mid+1];

   int i = lo, j = hi; 
   for (int k = lo; k <= hi; k++) 
      if (less(aux[j], aux[i])) a[k] = aux[j--];
      else                      a[k] = aux[i++];
}

C# 实现见代码部分。

代码
using System;
using Merge;

namespace _2._2._10
{
    /// <summary>
    /// 归并排序类。
    /// </summary>
    public class MergeSort : BaseSort
    {
        /// <summary>
        /// 默认构造函数。
        /// </summary>
        public MergeSort() { }

        /// <summary>
        /// 利用归并排序将数组按升序排序。
        /// </summary>
        /// <typeparam name="T">数组元素类型。</typeparam>
        /// <param name="a">待排序的数组。</param>
        public override void Sort<T>(T[] a)
        {
            T[] aux = new T[a.Length];
            Sort(a, aux, 0, a.Length - 1);
        }

        /// <summary>
        /// 自顶向下地对数组指定范围内进行归并排序,需要辅助数组。
        /// </summary>
        /// <typeparam name="T">需要排序的元素类型。</typeparam>
        /// <param name="a">原数组。</param>
        /// <param name="aux">辅助数组。</param>
        /// <param name="lo">排序范围起点。</param>
        /// <param name="hi">排序范围终点。</param>
        private void Sort<T>(T[] a, T[] aux, int lo, int hi) where T : IComparable<T>
        {
            if (hi <= lo)
                return;
            int mid = lo + (hi - lo) / 2;
            Sort(a, aux, lo, mid);
            Sort(a, aux, mid + 1, hi);
            Merge(a, aux, lo, mid, hi);
        }

        /// <summary>
        /// 将指定范围内的元素归并。
        /// </summary>
        /// <typeparam name="T">数组元素类型。</typeparam>
        /// <param name="a">原数组。</param>
        /// <param name="aux">辅助数组。</param>
        /// <param name="lo">范围起点。</param>
        /// <param name="mid">范围中点。</param>
        /// <param name="hi">范围终点。</param>
        private void Merge<T>(T[] a, T[] aux, int lo, int mid, int hi) where T : IComparable<T>
        {
            // 前半部分升序复制
            for (int k = lo; k <= mid; k++)
            {
                aux[k] = a[k];
            }
            // 后半部分降序复制
            for (int k = mid + 1; k <= hi; k++)
            {
                aux[k] = a[hi - k + mid + 1];
            }

            // i 指向最左端,j 指向最右端
            int i = lo, j = hi;
            for (int k = lo; k <= hi; k++)
            {
                if (Less(aux[j], aux[i]))
                {
                    a[k] = aux[j];
                    j--;
                }
                else
                {
                    a[k] = aux[i];
                    i++;
                }
            }
        }
    }
}

 

2.2.11

题目

改进。
实现 2.2.2 节所述的对归并排序的三项改进:
加快小数组的排序速度,
检测数组是否已经有序以及通过在递归中交换参数来避免复制。

本文由澳门新葡亰手机版发布于编程,转载请注明出处:获取某一路径下的所有文件名信息

上一篇:找出总分最高的学生,字符串和列表 下一篇:元素等待机制,odoo权限小谈
猜你喜欢
热门排行
精彩图文