个人写表格辅助软件

发布于:2024-05-16 ⋅ 阅读:(58) ⋅ 点赞:(0)

 该软件作用 Excel 的辅助,可以执行excel不方便的操作,从excel复制数据到软件进行操作又复制回Excel。

下载软件地址 ,大小:65kb 

        点击下载

完整UI

列操作   右键单击列名弹出菜单

单元格操作  右键单击单元格弹出菜单

 

导航模式 每个操作都可以返回后退

 

 代码

采用c#  winform 写的

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Collections;
using System.Globalization;
using System.Collections.Concurrent;
using System.Diagnostics;

namespace Form_Dev
{
    public partial class Form1 : Form
    {

        string exePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        string fileName { get { return exePath + "myDataTable.csv"; } }



        DataTable _dataTable = new DataTable { };

        int curr_history_index = 0;
        List<DataTable> dataTable_history = new List<DataTable>();
        /// <summary>
        /// 撤销和恢复 模式,不记录表格数据了
        /// </summary>
        bool Undo_Redo_Mode = false;


        DataTable dataTable_0000
        {
            get { return _dataTable; }
            set
            {


                // 追加数据到历史记录
                if (Undo_Redo_Mode == false)
                {
                    //克隆的 DataTable 中的数据
                    DataTable clonedDataTable = value.Clone();
                    foreach (DataRow row in value.Rows)
                    {
                        clonedDataTable.ImportRow(row); // 导入原始 DataTable 中的每一行数据到克隆的 DataTable
                    }

                    // Clone一个新的DataTable加入列表,而非只是对DataTable对象的引用
                    dataTable_history.Add(clonedDataTable);
                    curr_history_index = dataTable_history.Count - 1;
                }



                //克隆的 DataTable 中的数据
                DataTable clonedDataTable2 = value.Clone();
                foreach (DataRow row in value.Rows)
                {
                    clonedDataTable2.ImportRow(row); // 导入原始 DataTable 中的每一行数据到克隆的 DataTable
                }

                DataTable clonedDataTable3 = value.Clone();
                foreach (DataRow row in value.Rows)
                {
                    clonedDataTable3.ImportRow(row); // 导入原始 DataTable 中的每一行数据到克隆的 DataTable
                }

                //清空表格数据
                _dataTable.Reset();
                _dataTable = clonedDataTable3;


                //显示表格
                _dataTable.Locale = new CultureInfo("zh-CN");


                //关闭自动计算列宽度,改为手动计算,当列数自动计算就报错了,默认列宽100,最大值65535,当超过600列就报错了。所以手动计算
                dataGridView1.AutoGenerateColumns = false;
                //清除上次显示结构
                dataGridView1.Columns.Clear();

                // 手动为DataGridView添加列并设置FillWeight
                int totalFillWeight = 65535;
                int reservedWidth = 100; // 预留宽度,用于标题和边框
                int columnCount = _dataTable.Columns.Count;

                if (columnCount > 0)
                {
                    // 计算每列的平均填充宽度
                    int averageFillWeight = (totalFillWeight - reservedWidth) / columnCount;
                    if (averageFillWeight > 200)//防止列少时 ,超过200
                    {
                        averageFillWeight = 200;
                    }

                    foreach (DataColumn column in _dataTable.Columns)
                    {
                        DataGridViewTextBoxColumn gridColumn = new DataGridViewTextBoxColumn();
                        gridColumn.DataPropertyName = column.ColumnName;
                        gridColumn.HeaderText = column.ColumnName;
                        gridColumn.Name = column.ColumnName;
                        gridColumn.FillWeight = averageFillWeight; // 使用计算出的平均宽度
                        dataGridView1.Columns.Add(gridColumn);
                    }
                }
       


                dataGridView1.DataSource = _dataTable;
                

                // 设置所有列的单元格内容居中显示
                foreach (DataGridViewColumn column in dataGridView1.Columns)
                {
                    column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                }

                // 设置列名居中显示
                dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;


        

                // 刷新 DataGridView 显示
                dataGridView1.Refresh();



                // 更新显示
                textBox1.AppendText(GetTableSchema(value) + Environment.NewLine);
                this.textBox2.Text = "行row : " + _dataTable.Rows.Count + " ,列col : " + _dataTable.Columns.Count;
                textBox3.Text = dataTable_history.Count + "";
                textBox5.Text = curr_history_index + 1 + "";

                //保存到文件
                SaveDataTableToFile(_dataTable);

                if (Undo_Redo_Mode)//恢复 清空表格数据 操作的数据
                {
                    dataTable_history[curr_history_index] = clonedDataTable2;
                }

            }
        }

        public DataTable dataTable
        {
            get { return _dataTable; }
            set
            {


                // 追加数据到历史记录
                if (Undo_Redo_Mode == false)
                {
                    //克隆的 DataTable 中的数据
                    DataTable clonedDataTable = value.Clone();
                    foreach (DataRow row in value.Rows)
                    {
                        clonedDataTable.ImportRow(row); // 导入原始 DataTable 中的每一行数据到克隆的 DataTable
                    }

                    // Clone一个新的DataTable加入列表,而非只是对DataTable对象的引用
                    dataTable_history.Add(clonedDataTable);
                    curr_history_index = dataTable_history.Count - 1;
                }



                //克隆的 DataTable 中的数据
                DataTable clonedDataTable2 = value.Clone();
                foreach (DataRow row in value.Rows)
                {
                    clonedDataTable2.ImportRow(row); // 导入原始 DataTable 中的每一行数据到克隆的 DataTable
                }

                DataTable clonedDataTable3 = value.Clone();
                foreach (DataRow row in value.Rows)
                {
                    clonedDataTable3.ImportRow(row); // 导入原始 DataTable 中的每一行数据到克隆的 DataTable
                }

                //清空表格数据
                _dataTable.Reset();
                _dataTable = clonedDataTable3;


                //显示表格
                _dataTable.Locale = new CultureInfo("zh-CN");


                //关闭自动计算列宽度,改为手动计算,当列数自动计算就报错了,默认列宽100,最大值65535,当超过600列就报错了。所以手动计算
                dataGridView1.AutoGenerateColumns = false;
                //清除上次显示结构
                dataGridView1.Columns.Clear();

                // 手动为DataGridView添加列并设置FillWeight
                int totalFillWeight = 65535;
                int reservedWidth = 100; // 预留宽度,用于标题和边框
                int columnCount = value.Columns.Count;

                if (columnCount > 0)
                {
                    // 计算每列的平均填充宽度
                    int averageFillWeight = (totalFillWeight - reservedWidth) / columnCount;
                    if (averageFillWeight > 200)//防止列少时 ,超过200
                    {
                        averageFillWeight = 200;
                    }

                    foreach (DataColumn column in value.Columns)
                    {
                        DataGridViewTextBoxColumn gridColumn = new DataGridViewTextBoxColumn();
                        gridColumn.DataPropertyName = column.ColumnName;
                        gridColumn.HeaderText = column.ColumnName;
                        gridColumn.Name = column.ColumnName;
                        gridColumn.FillWeight = averageFillWeight; // 使用计算出的平均宽度
                        dataGridView1.Columns.Add(gridColumn);
                    }
                }



                dataGridView1.DataSource = _dataTable;


                // 设置所有列的单元格内容居中显示
                foreach (DataGridViewColumn column in dataGridView1.Columns)
                {
                    column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                }

                // 设置列名居中显示
                dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;




                // 刷新 DataGridView 显示
                dataGridView1.Refresh();



                // 更新显示
                textBox1.AppendText(GetTableSchema(value) + Environment.NewLine);
                this.textBox2.Text = "行row : " + _dataTable.Rows.Count + " ,列col : " + _dataTable.Columns.Count;
                textBox3.Text = dataTable_history.Count + "";
                textBox5.Text = curr_history_index + 1 + "";

                //保存到文件
                SaveDataTableToFile(_dataTable);

                if (Undo_Redo_Mode)//恢复 清空表格数据 操作的数据
                {
                    dataTable_history[curr_history_index] = clonedDataTable2;
                }

            }
        }

        public DataTable dataTable_2
        {
            get { return _dataTable; }
            set
            {
                if (_dataTable == value) return;

                if (value == null || value.Rows.Count == 0 || value.Columns.Count == 0)
                    return;

                // 克隆 DataTable
                DataTable clonedDataTable = value.Copy();

                // 追加数据到历史记录
                if (!Undo_Redo_Mode)
                {
                    dataTable_history.Add(clonedDataTable);
                    curr_history_index = dataTable_history.Count - 1;
                }

                // 清空表格数据
                _dataTable.Clear();

                // 将克隆的数据表复制到实例的数据表中
                foreach (DataRow row in clonedDataTable.Rows)
                {
                    _dataTable.ImportRow(row);
                }

                // 设置显示语言
                _dataTable.Locale = new CultureInfo("zh-CN");

                // 重新绑定数据源
                dataGridView1.DataSource = _dataTable;

                // 设置列的样式和显示
                dataGridView1.AutoGenerateColumns = false;
                dataGridView1.Columns.Clear();

                int totalFillWeight = 65535;
                int reservedWidth = 100; // 预留宽度,用于标题和边框
                int columnCount = _dataTable.Columns.Count;

                if (columnCount > 0)
                {
                    int averageFillWeight = (totalFillWeight - reservedWidth) / columnCount;
                    if (averageFillWeight > 200)
                    {
                        averageFillWeight = 200;
                    }

                    foreach (DataColumn column in _dataTable.Columns)
                    {
                        DataGridViewTextBoxColumn gridColumn = new DataGridViewTextBoxColumn();
                        gridColumn.DataPropertyName = column.ColumnName;
                        gridColumn.HeaderText = column.ColumnName;
                        gridColumn.Name = column.ColumnName;
                        gridColumn.FillWeight = averageFillWeight;
                        dataGridView1.Columns.Add(gridColumn);
                    }
                }

                foreach (DataGridViewColumn column in dataGridView1.Columns)
                {
                    column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                }

                dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;

                // 刷新 DataGridView
                dataGridView1.Refresh();

                // 更新文本框显示
                textBox1.AppendText(GetTableSchema(value) + Environment.NewLine);
                textBox2.Text = "行row : " + value.Rows.Count + " ,列col : " + value.Columns.Count;
                textBox3.Text = dataTable_history.Count.ToString();
                textBox5.Text = (curr_history_index + 1).ToString();
                SaveDataTableToFile(value);

                if (Undo_Redo_Mode)
                {
                    dataTable_history[curr_history_index] = value.Copy();
                }
            }
        }


        /// <summary>
        /// 更新文本框显示
        /// </summary>
        /// <param name="value">数据表</param>
        private void UpdateTextBoxes(DataTable value)
        {
            textBox1.AppendText(GetTableSchema(value) + Environment.NewLine);
            textBox2.Text = "行row : " + value.Rows.Count + " ,列col : " + value.Columns.Count;
            textBox3.Text = dataTable_history.Count.ToString();
            textBox5.Text = (curr_history_index + 1).ToString();
            SaveDataTableToFile(value);

            if (Undo_Redo_Mode)
            {
                dataTable_history[curr_history_index] = value.Copy();
            }
        }



        public DataTable CountStrings(DataTable dataTable)
        {
            // 创建一个用于统计的DataTable
            DataTable stringCountTable = new DataTable();
            stringCountTable.Columns.Add("String", typeof(string));
            stringCountTable.Columns.Add("Count", typeof(int));

            // 使用Dictionary来存储字符串及其出现次数
            Dictionary<string, int> stringCounts = new Dictionary<string, int>();

            // 遍历dataTable中的每一行和每一列
            foreach (DataRow row in dataTable.Rows)
            {
                foreach (DataColumn col in dataTable.Columns)
                {
                    // 获取单元格的字符串值
                    string cellValue = row[col].ToString();

                    // 如果字符串已经在字典中,增加计数
                    if (stringCounts.ContainsKey(cellValue))
                    {
                        stringCounts[cellValue]++;
                    }
                    else
                    {
                        // 如果字符串不在字典中,添加到字典
                        stringCounts[cellValue] = 1;
                    }
                }
            }

            // 将字典中的数据添加到DataTable中
            foreach (var kvp in stringCounts)
            {
                DataRow newRow = stringCountTable.NewRow();
                newRow["String"] = kvp.Key;
                newRow["Count"] = kvp.Value;
                stringCountTable.Rows.Add(newRow);
            }

            // 对结果进行排序
            DataView dv = stringCountTable.DefaultView;
            dv.Sort = "Count DESC";
            DataTable sortedTable = dv.ToTable();

            return sortedTable;
        }


        public Form1()
        {
            InitializeComponent();
        }


        /// <summary>
        /// 从剪贴板读取数据并转换成DataTable
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            // 检查剪贴板是否包含文本数据
            if (Clipboard.ContainsText())
            {
                // 获取剪贴板文本数据,并移除末尾的换行符
                string clipboardData = Clipboard.GetText().TrimEnd('\r', '\n');

                // 获取换行符,用于可视化显示
                string lineSeparator = GetLineSeparator(clipboardData);

                // 可视化显示换行符
                textBox1.AppendText("换行符为:" + lineSeparator.Replace("\r", "\\r").Replace("\n", "\\n") + Environment.NewLine);

                // 将剪贴板数据按换行符分割成行数组
                string[] lines = clipboardData.Split(new[] { lineSeparator }, StringSplitOptions.None);
                string executionTime = stopwatch.Elapsed.ToString();
                textBox1.AppendText("将剪贴板数据按换行符分割成行数组,函数执行时间: " + executionTime + Environment.NewLine);

                // 计算最大制表符数量,确定列数
                int maxTabCount = lines.Select(line => line.Count(c => c == '\t')).Max();
                // 确保列数至少有1列
                int colCount = maxTabCount + 1;

                // 创建一个 DataTable 对象用于存储数据
                DataTable new_dt = new DataTable();

                // 获取第一行的列名,用于判断是否存在空值或重复值
                string[] columnNames = lines[0].Split('\t');
                bool firstLineHasEmpty = columnNames.Any(string.IsNullOrEmpty);
                bool firstLineHasDuplicates = columnNames.Length != columnNames.Distinct().Count();

                // 根据第一行的情况,确定是否添加默认列名
                if (firstLineHasEmpty || firstLineHasDuplicates)
                {
                    for (int i = 0; i < colCount; i++)
                    {
                        new_dt.Columns.Add($"列{i + 1}", typeof(string));
                    }
                    //在加载数据之前调用 BeginLoadData() 方法,在加载完成后调用 EndLoadData() 方法。这会暂时禁用表的约束和索引,从而提高性能。
                    new_dt.BeginLoadData();
                    textBox1.AppendText("开始添加行数据: " + lines + Environment.NewLine);
                    // 遍历剪贴板数据的每一行,并添加到 DataTable 中
                    foreach (var line in lines)
                    {
                        string[] cells = line.Split('\t');
                        //if (cells.Length < colCount)
                        //{
                        //    // 如果单元格数量小于列数,使用 Array.Resize 调整大小
                        //    Array.Resize(ref cells, colCount);
                        //}
                        textBox1.AppendText("添加行数据: " + lines + Environment.NewLine);
                        new_dt.Rows.Add(cells);
                    }
                    new_dt.EndLoadData();
                }
                else
                {
                    // 如果第一行没有空值或重复值,则使用第一行作为列名
                    foreach (var columnName in columnNames)
                    {
                        new_dt.Columns.Add(columnName, typeof(string));
                    }
                    //在加载数据之前调用 BeginLoadData() 方法,在加载完成后调用 EndLoadData() 方法。这会暂时禁用表的约束和索引,从而提高性能。
                    new_dt.BeginLoadData();

                    // 遍历剩余行的数据,并添加到 DataTable 中
                    for (int i = 1; i < lines.Length; i++)
                    {
                        string[] cells = lines[i].Split('\t');
                        //if (cells.Length < colCount)
                        //{
                        //    // 如果单元格数量小于列数,使用 Array.Resize 调整大小
                        //    Array.Resize(ref cells, colCount);
                        //}
                        textBox1.AppendText("添加行数据: " + lines + Environment.NewLine);
                        new_dt.Rows.Add(cells);
                    }
                    new_dt.EndLoadData();
                }
                textBox1.AppendText("结束添加行数据: " + lines + Environment.NewLine);

                executionTime = stopwatch.Elapsed.ToString();
                textBox1.AppendText("从剪贴板读取数据并转换成DataTable,函数执行时间: " + executionTime + Environment.NewLine);

                // 处理或显示dataTable
                // 例如:dataGridView.DataSource = dataTable;
                this.dataTable = new_dt;


            }
            else
            {
                MessageBox.Show("剪贴板中没有文本数据。");
            }
        }


        private void button1_Click_0(object sender, EventArgs e)
        {


            // 检查剪贴板是否含有文本数据
            if (Clipboard.ContainsText())
            {
                string clipboardData = Clipboard.GetText();

                // 判断并删除字符串末尾的换行符,最后一个字符是换行符,要删除,不然多了一个空行
                if (clipboardData.EndsWith("\r\n"))
                {
                    clipboardData = clipboardData.Remove(clipboardData.Length - 2); // 删除末尾的 "\r\n"
                }
                else if (clipboardData.EndsWith("\n"))
                {
                    clipboardData = clipboardData.Remove(clipboardData.Length - 1); // 删除末尾的 "\n"
                }


                var line_split = GetLineSeparator(clipboardData);

                //可视化的字符串
                string visibleNewLine = line_split
                .Replace("\r", "\\r")
                .Replace("\n", "\\n");

                textBox1.AppendText("换行符为:"+ visibleNewLine + Environment.NewLine);

                string[] lines = clipboardData.Split(new[] { line_split }, StringSplitOptions.None);



                // 计算制表符数量,找出最多的制表符数量
                int maxTabCount = lines.Select(line => line.Count(c => c == '\t')).Max();

                // 确定列数,至少有1列
                int colCount = maxTabCount + 1;

                // 创建DataTable
                DataTable dataTable = new DataTable();

                var firstLineCells = lines[0].Split('\t');
                bool firstLineHasEmpty = firstLineCells.Any(cell => string.IsNullOrEmpty(cell));
                bool firstLineHasDuplicates = firstLineCells.Length != firstLineCells.Distinct().Count();


                // 检查第一行是否存在空值或重复的值,如果存在,则添加默认列名
                if (firstLineHasEmpty || firstLineHasDuplicates)
                {
                    for (int i = 0; i < colCount; i++)
                    {
                        dataTable.Columns.Add($"列{i + 1}", typeof(string));
                    }
                    // 添加所有数据行到DataTable,包括第一行
                    foreach (var line in lines)
                    {
                        var cells = line.Split('\t');
                        if (cells.Length < colCount)
                        {
                            cells = cells.Concat(new string[colCount - cells.Length]).ToArray();
                        }
                        dataTable.Rows.Add(cells);
                    }
                }
                else
                {
                    // 使用第一行作为列名
                    foreach (var columnName in firstLineCells)
                    {
                        dataTable.Columns.Add(columnName, typeof(string));
                    }
                    // 添加剩余的数据行到DataTable
                    for (int i = 1; i < lines.Length; i++)
                    {
                        var cells = lines[i].Split('\t');
                        if (cells.Length < colCount)
                        {
                            cells = cells.Concat(new string[colCount - cells.Length]).ToArray();
                        }
                        dataTable.Rows.Add(cells);
                    }
                }




                // 此处应有代码来处理或显示dataTable
                // 例如:dataGridView.DataSource = dataTable;
                //             // 显示数据
                this.dataTable = dataTable;

            }
           else
        {
            MessageBox.Show("剪贴板中没有文本数据。");
        }
    }



    /// <summary>
    /// 数组中是否有重复值
    /// </summary>
    /// <param name="columnNames"></param>
    /// <returns></returns>
    bool HasDuplicate(string[] columnNames)
        {
            bool hasDuplicate = false;

            for (int i = 0; i < columnNames.Length; i++)
            {
                for (int j = i + 1; j < columnNames.Length; j++)
                {
                    if (columnNames[i] == columnNames[j])
                    {
                        hasDuplicate = true;
                        break;
                    }
                }
            }

            return hasDuplicate;
        }


        /// <summary>
        /// 删除该列中值为 null 的行
        /// </summary>
        /// <param name="table">待处理的源DataTable</param>
        /// <param name="colName">要检查的列名</param>
        /// <returns>处理后的DataTable</returns>
        public DataTable RemoveRowsWithNull(DataTable table, string colName)
        {
            // 使用DataTable.Select方法筛选符合条件的行
            DataRow[] rowsToDelete = table.Select($"{colName} IS NULL");

            // 删除符合条件的行
            foreach (DataRow row in rowsToDelete)
            {
                table.Rows.Remove(row);
            }

            // 返回处理后的DataTable
            return table;
        }

        //删除该列中不是对子的行
        public DataTable RemoveNonTripletPairRows(DataTable dataTable, string columnName)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            if (dataTable == null || dataTable.Rows.Count == 0)
            {
                throw new ArgumentException("输入的DataTable不能为空或无数据行");
            }

            if (!dataTable.Columns.Contains(columnName))
            {
                throw new ArgumentException($"DataTable中不存在名为'{columnName}'的列");
            }

            // 获取列数据
            List<string> columnData = dataTable.AsEnumerable()
                                               .Select(row => row.Field<string>(columnName))
                                               .ToList();

            // 并行处理列数据
            Parallel.For(0, columnData.Count, i =>
            {
                string value = columnData[i];
                if (!string.IsNullOrEmpty(value) && value.Length == 3 && value.Distinct().Count() != 2)
                {
                    columnData[i] = null; // 标记要删除的数据
                }
            });

            // 重新构建DataTable
            DataTable newDataTable = new DataTable();
            newDataTable.Columns.Add(columnName);

            foreach (string value in columnData)
            {
                if (value != null)
                {
                    newDataTable.Rows.Add(value);
                }
            }

            stopwatch.Stop();


            string executionTime = stopwatch.Elapsed.ToString();
            textBox1.AppendText("函数执行时间: " + executionTime + Environment.NewLine);
            return newDataTable;
        }


        /// <summary>
        /// 从剪贴板 数据 分别统计 \r\n、\r、\n 这个三个换行符的数量,哪个高用哪个
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private string GetLineSeparator(string text)
        {
            int crlfCount = 0;
            int crCount = 0;
            int lfCount = 0;

            for (int i = 0; i < text.Length; i++)
            {
                if (text[i] == '\r' && i < text.Length - 1 && text[i + 1] == '\n')
                {
                    crlfCount++;
                    i++;
                }
                else if (text[i] == '\r')
                {
                    crCount++;
                }
                else if (text[i] == '\n')
                {
                    lfCount++;
                }

                // 如果某种换行符的数量已经大于其它两种的总和,就可以立即返回结果
                if (crlfCount > crCount + lfCount)
                {
                    return "\r\n";
                }
                else if (crCount > lfCount + crlfCount)
                {
                    return "\r";
                }
                else if (lfCount > crCount + crlfCount)
                {
                    return "\n";
                }
            }

            // 如果没有找到换行符,则默认使用 \r\n
            return "\r\n";
        }



        /// <summary>
        /// 把连续的一个空格 或者连续的空格替换为制表符
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        private string[] ReplaceSpacesWithTabs(string[] lines)
        {

            //每一行中的连续空白字符(两个或以上)替换为制表符,
            for (int i = 0; i < lines.Length; i++)
            {
                lines[i] = Regex.Replace(lines[i], @" {2,}", "\t");
            }

            //每个单独的空格也替换为制表符
            for (int i = 0; i < lines.Length; i++)
            {
                lines[i] = lines[i].Replace(" ", "\t");
            }


            return lines;
        }

        /// <summary>
        /// 返回两个结果 一个是所有行中制表符是否一致,第二个返回数组每行的数组制表符数量
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public static (bool, int[]) CheckTabCounts(string[] lines)
        {
            int[] tabCounts = new int[lines.Length];
            bool consistent = true;
            int prevTabCount = -1;
            for (int i = 0; i < lines.Length; i++)
            {
                // 统计每行中制表符的数量
                tabCounts[i] = Regex.Matches(lines[i], "\t").Count;

                // 判断每行中制表符的数量是否一致
                if (prevTabCount != -1 && prevTabCount != tabCounts[i])
                {
                    consistent = false;
                }
                prevTabCount = tabCounts[i];
            }
            return (consistent, tabCounts);
        }

        /// <summary>
        /// 去除 纯空行 和 只包含空格的空行
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public string[] TrimLines(string[] lines)
        {

            List<string> newLine = new List<string>();
            // 循环遍历每行数据,去除首尾空白字符,并将结果存储到新的字符串数组中
            for (int i = 0; i < lines.Length; i++)
            {
                var line = lines[i];
                if(IsBlankLine(line))
                {//空行

                }
                else
                { //非空行
                    newLine.Add(line);
                }
              
            }

            return newLine.ToArray();
        }


        /// <summary>
        ///检测 纯空行 和 只包含空格的空行
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        bool IsBlankLine(string line)
        {
            for (int i = 0; i < line.Length; i++)
            {
                if (line[i] != ' ' || line != "\r" || line != "\n")
                    return false;
            }
            return true;
        }

        /// <summary>
        /// 删除最后面连续空行
        /// </summary>
        /// <param name="lines"></param>
        /// <returns></returns>
        public  string[] RemoveTrailingEmptyLines(string[] lines)
        {
            int lastNonEmptyLineIndex = -1;

            for (int i = lines.Length - 1; i >= 0; i--)
            {
                if (!string.IsNullOrWhiteSpace(lines[i]))
                {
                    lastNonEmptyLineIndex = i;
                    break;
                }
            }

            if (lastNonEmptyLineIndex == -1)
            {
                return new string[0];
            }

            string[] result = new string[lastNonEmptyLineIndex + 1];
            Array.Copy(lines, result, lastNonEmptyLineIndex + 1);

            return result;
        }


        /// <summary>
        /// 右键单击表 列名行 事件  弹出菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right) // 只处理右键单击事件
            {
                // 获取点击的列的信息

                DataGridViewColumn clickedColumn = dataGridView1.Columns[e.ColumnIndex];
                string columnName = clickedColumn.Name;
                int columnIndex = clickedColumn.Index;
                textBox1.AppendText("右键单击 列名标题栏 事件, 列名称: " + columnName + Environment.NewLine);

                // 弹出菜单
                ContextMenuStrip menu = new ContextMenuStrip();
                menu.Items.Add("删除重复行").Click += (s, args) =>
                {
                    // 删除重复行的逻辑
                    textBox1.AppendText("执行 删除重复行 列名称:" + columnName + Environment.NewLine);
                    var newDataTable = RemoveDuplicateRows(columnName);
                    dataTable = newDataTable;

                };
                menu.Items.Add("统计次数").Click += (s, args) =>
                {
                    // 统计次数的逻辑
                    // ...
                    textBox1.AppendText("统计次数:" + columnName + Environment.NewLine);
                    var newDataTable = CountColumnValues(columnName);
                     dataTable = newDataTable;
                };

                menu.Items.Add("修改该列数据类型").Click += (s, args) =>
                {
                    // 统计次数的逻辑
                    // ...
                    // 创建一个新的SelectColumnTypeForm实例,并将其显示为模式对话框
                    SelectColumnTypeForm form = new SelectColumnTypeForm();
                    form.ShowDialog();

                    Type type=null;
                    // 检查用户是否选择了数据类型
                    if (!string.IsNullOrEmpty(form.SelectedColumnType))
                    {
                        // 用户选择了数据类型,将其显示在Label控件中
                        type = form.type;
                        var newDataTable = ChangeColumnType(dataTable, columnName, type);
                        dataTable = newDataTable;
                        textBox1.AppendText("修改该列数据类型:" + columnName + ":"+ type.ToString() + Environment.NewLine);
                    }
                    else
                    {

                    }
 
                };


                menu.Items.Add("删除该列").Click += (s, args) =>
                {
                    textBox1.AppendText("删除该列:"+ columnName + Environment.NewLine);
                    var newDataTable = RemoveColumn(dataTable, columnName);
                    dataTable = newDataTable;
                };

                menu.Items.Add("只保留该列").Click += (s, args) =>
                {
                    var newDataTable = KeepColumn(dataTable, columnName);
                    dataTable = newDataTable;
                    textBox1.AppendText("只保留该列:" + columnName + Environment.NewLine);
                };

                menu.Items.Add("排序从大到小").Click += (s, args) =>
                {
                    var newDataTable = SortDataTable(dataTable, columnName);
                    dataTable = newDataTable;
                    textBox1.AppendText("排序从大到小:"+ columnName + Environment.NewLine);
                };

                menu.Items.Add("排序从小到大").Click += (s, args) =>
                {
                    var newDataTable = SortColumnAscending(dataTable, columnName);
                    dataTable = newDataTable;
                    textBox1.AppendText("排序从小到大:" + columnName + Environment.NewLine);
                };

                menu.Items.Add("删除该列中不等于字符串的行").Click += (s, args) =>
                {
                    // 弹出输入框,让用户输入要删除的字符串
                    // 弹出一个对话框,让用户输入
                    string userInput = "";
                    using (var form = new Form())
                    {
                        form.Text = "请输入字符串";
                        var textBox = new TextBox { Left = 50, Top = 50, Width = 200 };
                        var buttonOk = new Button { Text = "确定", Left = 100, Top = 100, Width = 75, DialogResult = DialogResult.OK };
                        var buttonCancel = new Button { Text = "取消", Left = 200, Top = 100, Width = 75, DialogResult = DialogResult.Cancel };
                        form.AcceptButton = buttonOk;
                        form.CancelButton = buttonCancel;
                        form.ClientSize = new System.Drawing.Size(300, 150);
                        form.Controls.Add(textBox);
                        form.Controls.Add(buttonOk);
                        form.Controls.Add(buttonCancel);
                        if (form.ShowDialog() == DialogResult.OK)
                        {
                            userInput = textBox.Text;
                            
                            textBox1.AppendText("删除该列中不等于字符串的行:" + columnName + ",字符:" + userInput + Environment.NewLine);
                        }
                        else
                        {
                            // 用户取消输入,做一些处理
                            textBox1.AppendText("取消输入:" + columnName + Environment.NewLine);

                        }
                    }

                    var newDataTable = RemoveRowsNotEqual(dataTable, columnName, userInput);
                    dataTable = newDataTable;
                };

                menu.Items.Add("删除该列中等于字符串的行").Click += (s, args) =>
                {
                    // 弹出输入框,让用户输入要删除的字符串
                    // 弹出一个对话框,让用户输入
                    string userInput = "";
                    using (var form = new Form())
                    {
                        form.Text = "请输入字符串";
                        var textBox = new TextBox { Left = 50, Top = 50, Width = 200 };
                        var buttonOk = new Button { Text = "确定", Left = 100, Top = 100, Width = 75, DialogResult = DialogResult.OK };
                        var buttonCancel = new Button { Text = "取消", Left = 200, Top = 100, Width = 75, DialogResult = DialogResult.Cancel };
                        form.AcceptButton = buttonOk;
                        form.CancelButton = buttonCancel;
                        form.ClientSize = new System.Drawing.Size(300, 150);
                        form.Controls.Add(textBox);
                        form.Controls.Add(buttonOk);
                        form.Controls.Add(buttonCancel);

                        // 设置窗口启动位置为手动
                        form.StartPosition = FormStartPosition.Manual;

                        // 设置form的位置为父窗口的左中上位置
                        form.Location = new Point(this.Left, this.Top + (this.Height - form.Height) / 2);

                        if (form.ShowDialog() == DialogResult.OK)
                        {
                            userInput = textBox.Text;

                            textBox1.AppendText("删除该列中等于字符串的行:" + columnName + ",字符:" + userInput + Environment.NewLine);
                            var newDataTable = RemoveRowsEqual(dataTable, columnName, userInput);
                            dataTable = newDataTable;
                        }
                        else
                        {
                            // 用户取消输入,做一些处理
                            textBox1.AppendText("取消输入:" + columnName + Environment.NewLine);

                        }
                    }


                };

                menu.Items.Add("删除该列中不包含该字符串中任意字符的行").Click += (s, args) =>
                {
                    // 弹出输入框,让用户输入要删除的字符串
                    // 弹出一个对话框,让用户输入
                    string userInput = "";
                    using (var form = new Form())
                    {
                        form.Text = "请输入字符串";
                        var textBox = new TextBox { Left = 50, Top = 50, Width = 200 };
                        var buttonOk = new Button { Text = "确定", Left = 100, Top = 100, Width = 75, DialogResult = DialogResult.OK };
                        var buttonCancel = new Button { Text = "取消", Left = 200, Top = 100, Width = 75, DialogResult = DialogResult.Cancel };
                        form.AcceptButton = buttonOk;
                        form.CancelButton = buttonCancel;
                        form.ClientSize = new System.Drawing.Size(300, 150);
                        form.Controls.Add(textBox);
                        form.Controls.Add(buttonOk);
                        form.Controls.Add(buttonCancel);


                        // 设置窗口启动位置为手动
                        form.StartPosition = FormStartPosition.Manual;

                        // 设置form的位置为父窗口的左中上位置
                        form.Location = new Point(this.Left, this.Top + (this.Height - form.Height) / 2);

                        if (form.ShowDialog() == DialogResult.OK)
                        {
                            userInput = textBox.Text;

                            textBox1.AppendText("删除该列中不包含该字符串中任意字符的行:" + columnName + ",字符:" + userInput + Environment.NewLine);

                            var newDataTable = RemoveRowsNotContain(dataTable, columnName, userInput);
                            dataTable = newDataTable;
                        }
                        else
                        {
                            // 用户取消输入,做一些处理
                            textBox1.AppendText("取消输入:" + columnName + Environment.NewLine);

                        }
                    }
                };

                menu.Items.Add("删除该列中包含该字符串中任意字符的行").Click += (s, args) =>
                {
                    // 弹出输入框,让用户输入要删除的字符串
                    // 弹出一个对话框,让用户输入
                    string userInput = "";
                    using (var form = new Form())
                    {
                        form.Text = "请输入字符串";
                        var textBox = new TextBox { Left = 50, Top = 50, Width = 200 };
                        var buttonOk = new Button { Text = "确定", Left = 100, Top = 100, Width = 75, DialogResult = DialogResult.OK };
                        var buttonCancel = new Button { Text = "取消", Left = 200, Top = 100, Width = 75, DialogResult = DialogResult.Cancel };
                        form.AcceptButton = buttonOk;
                        form.CancelButton = buttonCancel;
                        form.ClientSize = new System.Drawing.Size(300, 150);
                        form.Controls.Add(textBox);
                        form.Controls.Add(buttonOk);
                        form.Controls.Add(buttonCancel);


                        // 设置窗口启动位置为手动
                        form.StartPosition = FormStartPosition.Manual;

                        // 设置form的位置为父窗口的左中上位置
                        form.Location = new Point(this.Left, this.Top + (this.Height - form.Height) / 2);

                        if (form.ShowDialog() == DialogResult.OK)
                        {
                            userInput = textBox.Text;

                            textBox1.AppendText("删除该列中包含该字符串中任意字符的行:" + columnName + ",字符:" + userInput + Environment.NewLine);

                            var newDataTable = RemoveRowsContainAnyCharacter(dataTable, columnName, userInput);
                            dataTable = newDataTable;
                        }
                        else
                        {
                            // 用户取消输入,做一些处理
                            textBox1.AppendText("取消输入:" + columnName + Environment.NewLine);

                        }
                    }
                };


                menu.Items.Add("删除该列中等于空字符串的行").Click += (s, args) =>
                {
                    // 列名行变成第一行数据,并增加默认的列名行
                    dataTable = RemoveRowsWithEmptyString(dataTable,columnName);
                    textBox1.AppendText("删除该列中等于空字符串的行:" + columnName + Environment.NewLine);
                };
                menu.Items.Add("删除该列中等于NULL的行").Click += (s, args) =>
                {
                    // 列名行变成第一行数据,并增加默认的列名行
                    dataTable = RemoveRowsWithNull(dataTable, columnName);
                    textBox1.AppendText("删除该列中等于NULL的行:" + columnName + Environment.NewLine);
                };


                menu.Items.Add("只保留整型数字的行").Click += (s, args) =>
                {
                    // 列名行变成第一行数据,并增加默认的列名行
                    dataTable = FilterNumericColumn(e.ColumnIndex,dataTable);
                    textBox1.AppendText("列名称:" + columnName  + ",执行操作\"只保留整型数字的行\""+ Environment.NewLine);

                };


                menu.Items.Add("只保留包含浮点数的行").Click += (s, args) =>
                {
                    // 列名行变成第一行数据,并增加默认的列名行
                    dataTable = FilterDecimalColumnRegex(e.ColumnIndex, dataTable);
                    textBox1.AppendText("只保留包含浮点数的行:" + columnName + Environment.NewLine);

                };


                menu.Items.Add("计算综合得分").Click += (s, args) =>
                {
                    // 列名行变成第一行数据,并增加默认的列名行
                    dataTable = GetScores(dataTable);
                    textBox1.AppendText("计算综合得分:" + columnName + Environment.NewLine);

                };


                menu.Items.Add("保留该列中 两相同的行").Click += (s, args) =>
                {
                    dataTable = RemoveNonTripletPairRows(dataTable, columnName);
                    textBox1.AppendText("保留该列中 两相同的行:" + columnName + Environment.NewLine);

                };

                menu.Items.Add("保留该列中 三不同的行").Click += (s, args) =>
                {
                    dataTable = RemoveStringPairRows(dataTable, columnName);
                    textBox1.AppendText("保留该列中 三不同的行:" + columnName + Environment.NewLine);

                };

                menu.Items.Add("输出该列中 该列每5个为一行的字符串").Click += (s, args) =>
                {
                    var restr = CombineEveryFiveCells(dataTable, columnName);
                    textBox1.AppendText("输出该列中 该列每5个为一行的字符串" + columnName + Environment.NewLine);
                    textBox1.AppendText(restr + Environment.NewLine);

                };


                menu.Items.Add("删除该列中长度小于3的所有行").Click += (s, args) =>
                {
                    dataTable = RemoveLengthThreeRows(dataTable, columnName);
                    textBox1.AppendText("删除该列中长度小于3的所有行" + columnName + Environment.NewLine);

                };

  

                menu.Items.Add("删除该列中含非数字字符的行").Click += (s, args) =>
                {
                    RemoveRowsWithNonNumericContent(dataTable, columnName);
                    textBox1.AppendText("删除该列中含非数字字符的行" + columnName + Environment.NewLine);

                };

    

                menu.Items.Add("单元格-去除空白字符").Click += (s, args) =>
                {
                    RemoveAllWhitespaceFromColumnContents(dataTable, columnName);
                    textBox1.AppendText("单元格-去除空白字符" + columnName + Environment.NewLine);

                };

                menu.Items.Add("单元格-排序").Click += (s, args) =>
                {
                    AllCellContents(dataTable, columnName);
                    textBox1.AppendText("单元格-排序" + columnName + Environment.NewLine);

                };

                menu.Items.Add("单元格-去重复").Click += (s, args) =>
                {
                    DeduplicateEachCellContentInColumn(dataTable, columnName);
                    textBox1.AppendText("单元格-去重复" + columnName + Environment.NewLine);

                };


                menu.Show(dataGridView1, dataGridView1.PointToClient(Cursor.Position));
            }
    }

        /// <summary>
        /// 对指定列的每个单元格内容进行内部去重,而不是比较不同单元格之间的内容,
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columnName"></param>
        public static void DeduplicateEachCellContentInColumn(DataTable table, string columnName)
        {
            // 检查是否存在该列
            if (!table.Columns.Contains(columnName))
            {
                throw new ArgumentException($"Column '{columnName}' does not exist in the DataTable.");
            }

            // 遍历 DataTable 的每一行
            foreach (DataRow row in table.Rows)
            {
                string originalContent = row[columnName].ToString();
                StringBuilder deduplicatedContent = new StringBuilder();
                HashSet<char> seenChars = new HashSet<char>();

                // 遍历单元格内容的每个字符
                foreach (char ch in originalContent)
                {
                    // 如果字符尚未出现过,添加到结果字符串中
                    if (seenChars.Add(ch))
                    {
                        deduplicatedContent.Append(ch);
                    }
                }

                // 更新单元格内容为去重后的字符串
                row[columnName] = deduplicatedContent.ToString();
            }
        }

        /// <summary>
        /// 删除该列中含非数字字符的行。
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columnName"></param>
        public static void RemoveRowsWithNonNumericContent(DataTable table, string columnName)
        {
            // 检查是否存在该列
            if (!table.Columns.Contains(columnName))
            {
                throw new ArgumentException($"Column '{columnName}' does not exist in the DataTable.");
            }

            // 从最后一行向前遍历,避免因删除行而改变索引
            for (int i = table.Rows.Count - 1; i >= 0; i--)
            {
                var row = table.Rows[i];
                var cellValue = row[columnName].ToString();

                // 检查字符串是否包含任何非数字字符
                if (cellValue.Any(ch => !char.IsDigit(ch)))
                {
                    // 如果包含非数字字符,则删除该行
                    table.Rows.Remove(row);
                }
            }
        }

        /// <summary>
        /// 去除该列单元格内容空白字符
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columnName"></param>
        public static void RemoveAllWhitespaceFromColumnContents(DataTable table, string columnName)
        {
            // 检查是否存在该列
            if (!table.Columns.Contains(columnName))
            {
                throw new ArgumentException($"Column '{columnName}' does not exist in the DataTable.");
            }

            foreach (DataRow row in table.Rows)
            {
                var cellValue = row[columnName].ToString();

                // 使用正则表达式移除所有类型的空白字符
                var cleanedValue = Regex.Replace(cellValue, @"\s+", "");

                // 更新单元格内容
                row[columnName] = cleanedValue;
            }
        }


        /// <summary>
        /// 该列单元格内容排序
        /// </summary>
        /// <param name="dataTable"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public void AllCellContents(DataTable table, string columnName)
        {
            // 检查是否存在该列
            if (!table.Columns.Contains(columnName))
            {
                throw new ArgumentException($"Column '{columnName}' does not exist in the DataTable.");
            }

            foreach (DataRow row in table.Rows)
            {
                var cellValue = row[columnName].ToString();

                // 将字符串转换为字符数组,并进行排序
                var charArray = cellValue.ToCharArray();
                Array.Sort(charArray);

                // 将排序后的字符数组转换回字符串,并更新单元格内容
                row[columnName] = new string(charArray);
            }
        }


        /// <summary>
        /// 删除该列中 长度为2的所有行
        /// </summary>
        /// <param name="dataTable"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public DataTable RemoveLengthThreeRows(DataTable dataTable, string columnName)
        {
            if (dataTable == null || dataTable.Rows.Count == 0)
            {
                throw new ArgumentException("输入的DataTable不能为空或无数据行");
            }

            if (!dataTable.Columns.Contains(columnName))
            {
                throw new ArgumentException($"DataTable中不存在名为'{columnName}'的列");
            }

            // 获取列数据
            List<string> columnData = dataTable.AsEnumerable()
                                               .Select(row => row.Field<string>(columnName))
                                               .ToList();

            // 并行处理列数据
            Parallel.For(0, columnData.Count, i =>
            {
                string value = columnData[i];
                if (!string.IsNullOrEmpty(value) && value.Length == 3 && value.Distinct().Count() != 3)
                {
                    columnData[i] = null; // 标记要删除的数据
                }
            });

            // 重新构建DataTable
            DataTable newDataTable = new DataTable();
            newDataTable.Columns.Add(columnName);

            foreach (string value in columnData)
            {
                if (value != null)
                {
                    newDataTable.Rows.Add(value);
                }
            }

            return newDataTable;
        }


        /// <summary>
        /// 该列每5个为一行的字符串
        /// </summary>
        /// <param name="dataTable"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public string CombineEveryFiveCells(DataTable dataTable, string columnName)
        {
            // 检查DataTable是否为空或无数据行
            if (dataTable == null || dataTable.Rows.Count == 0)
            {
                throw new ArgumentException("输入的DataTable不能为空或无数据行");
            }

            // 检查指定列是否存在
            if (!dataTable.Columns.Contains(columnName))
            {
                throw new ArgumentException($"DataTable中不存在名为'{columnName}'的列");
            }

            StringBuilder combinedString = new StringBuilder();
            combinedString.Append("共有" + dataTable.Rows.Count + "注," + dataTable.Rows.Count * 2 + "元");
            combinedString.AppendLine(); // 每5个单元格内容合并完成后换行

            int rowIndex = 0;
            while (rowIndex < dataTable.Rows.Count)
            {
                for (int i = 0; i < 5 && rowIndex < dataTable.Rows.Count; i++, rowIndex++)
                {
                    string cellValue = dataTable.Rows[rowIndex][columnName] as string;
                    if (i > 0)
                    {
                        combinedString.Append("\t"); // 添加制表符间隔
                    }
                    combinedString.Append(cellValue);
                }
                combinedString.AppendLine(); // 每5个单元格内容合并完成后换行
            }

            return combinedString.ToString();
        }



        /// <summary>
        /// 保留三不同的行
        /// </summary>
        /// <param name="dataTable"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public DataTable RemoveStringPairRows(DataTable dataTable, string columnName)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            if (dataTable == null || dataTable.Rows.Count == 0)
            {
                throw new ArgumentException("输入的DataTable不能为空或无数据行");
            }

            if (!dataTable.Columns.Contains(columnName))
            {
                throw new ArgumentException($"DataTable中不存在名为'{columnName}'的列");
            }

            // 获取列数据
            List<string> columnData = dataTable.AsEnumerable()
                                               .Select(row => row.Field<string>(columnName))
                                               .ToList();

            // 并行处理列数据
            Parallel.For(0, columnData.Count, i =>
            {
                string value = columnData[i];
                if (!string.IsNullOrEmpty(value) && value.Length == 3 && value.Distinct().Count() != 3)
                {
                    columnData[i] = null; // 标记要删除的数据
                }
            });

            // 重新构建DataTable
            DataTable newDataTable = new DataTable();
            newDataTable.Columns.Add(columnName);

            foreach (string value in columnData)
            {
                if (value != null)
                {
                    newDataTable.Rows.Add(value);
                }
            }

            stopwatch.Stop();


            string executionTime = stopwatch.Elapsed.ToString();
            textBox1.AppendText("函数执行时间: " + executionTime + Environment.NewLine);

            return newDataTable;
        }



        public DataTable GetScores(DataTable inputData)
        {
            DataTable scores = new DataTable();
            scores.Columns.Add("Rank");
            scores.Columns.Add("Number");
            scores.Columns.Add("PositionScore");
            scores.Columns.Add("TimesScore");
            scores.Columns.Add("TotalScore");

            Dictionary<int, Score> dict = new Dictionary<int, Score>();

            foreach (DataRow row in inputData.Rows)
            {
                int number = int.Parse(row[1].ToString());
                int times = int.Parse(row[2].ToString());

                if (!dict.ContainsKey(number))
                {
                    dict.Add(number, new Score() { Number = number });
                }

                dict[number].PositionScore += GetPositionScore(row.ItemArray.Length);
                dict[number].TimesScore += GetTimesScore(times);
            }

            int rank = 1;
            foreach (Score score in dict.Values)
            {
                score.Rank = rank++;
                score.TotalScore = score.PositionScore + score.TimesScore;
                scores.Rows.Add(score.Rank, score.Number, score.PositionScore, score.TimesScore, score.TotalScore);
            }

            return scores;
        }



        /// <summary>
        /// 过滤DataTable指定列,只保留包含浮点数的行
        /// </summary>    
        /// <param name="columnIndex">需要过滤的列索引</param>
        /// <param name="table">原始DataTable</param>  
        /// <returns>过滤后的DataTable</returns>
        public DataTable FilterDecimalColumnRegex(int columnIndex, DataTable table)
        {
            DataTable result = table.Clone();

            for (int rowIndex = 0; rowIndex < table.Rows.Count; rowIndex++)
            {
                DataRow row = table.Rows[rowIndex];
                string cellValue = row[columnIndex].ToString();

                // 使用正则判断是否包含小数
                Regex regex = new Regex(@"^[-+]?[0-9]*\.?[0-9]+$");
                if (regex.IsMatch(cellValue))
                {
                    result.ImportRow(row);
                }
            }
            return result;
        }

        /// <summary> 
        /// 过滤DataTable指定列,只保留整型数字的行
        /// </summary>   
        /// <param name="columnIndex">需要过滤的列索引</param>  
        /// <param name="table">原始DataTable</param>
        /// <returns>过滤后的DataTable</returns>
        public DataTable FilterNumericColumn(int columnIndex, DataTable table)
        {
            /// 克隆一个空的DataTable作为结果
            DataTable result = table.Clone();

            // 遍历原始table的所有行
            for (int rowIndex = 0; rowIndex < table.Rows.Count; rowIndex++)
            {
                // 获取当前行
                DataRow row = table.Rows[rowIndex];

                /// 直接将指定列的值转换为字符串
                string cellValue = row[columnIndex].ToString();

                /// 使用正则判断字符串是否全部由数字组成
                Regex regex = new Regex(@"^[0-9]+$");

                //如果字符串与正则匹配,说明是数字
                if (regex.IsMatch(cellValue))
                {
                    //将当前行加入结果DataTable
                    result.ImportRow(row);
                }
            }

            // 返回结果DataTable
            return result;
        }


        /// <summary>
        /// 将当前 DataTable 的列名行变成第一行数据,并增加默认的列名行,,列1 列2 ...
        /// </summary>
        /// <param name="inputTable"></param>
        /// <returns></returns>
        public DataTable TransformDataTable(DataTable inputTable)
        {
            DataTable outputTable = new DataTable();

            // 添加默认的列名行
            for (int i = 0; i < inputTable.Columns.Count; i++)
            {
                outputTable.Columns.Add("列" + (i + 1));
            }

            // 将当前 DataTable 的列名行转换为数据行
            DataRow columnNameRow = outputTable.NewRow();
            foreach (DataColumn column in inputTable.Columns)
            {
                columnNameRow[column.Ordinal] = column.ColumnName;
            }
            outputTable.Rows.Add(columnNameRow);

            // 将当前 DataTable 的数据复制到新的 DataTable
            foreach (DataRow row in inputTable.Rows)
            {
                DataRow newRow = outputTable.NewRow();
                foreach (DataColumn column in inputTable.Columns)
                {
                    newRow[column.Ordinal] = row[column.Ordinal];
                }
                outputTable.Rows.Add(newRow);
            }

            return outputTable;
        }



        /// <summary>
        /// 删除该列中不等于字符串的行
        /// </summary>
        /// <param name="colName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public DataTable RemoveRowsNotEqual(DataTable table, string colName, string value)
        {
            // 使用DataTable.Select方法筛选符合条件的行
            DataRow[] rowsToDelete = table.Select($"{colName} <> '{value}'");

            // 删除符合条件的行
            foreach (DataRow row in rowsToDelete)
            {
                table.Rows.Remove(row);
            }

            // 返回处理后的DataTable
            return dataTable;
        }

        /// <summary>
        /// 删除该列中等于字符串的行
        /// </summary>
        /// <param name="table">待处理的源DataTable</param>
        /// <param name="colName">要检查的列名</param>
        /// <param name="value">要匹配的字符串值</param>
        /// <returns>处理后的DataTable</returns>
        public DataTable RemoveRowsEqual(DataTable table, string colName, string value)
        {
            // 使用DataTable.Select方法筛选符合条件的行
            DataRow[] rowsToDelete = table.Select($"{colName} = '{value}'");

            // 删除符合条件的行
            foreach (DataRow row in rowsToDelete)
            {
                table.Rows.Remove(row);
            }

            // 返回处理后的DataTable
            return table;
        }

        /// <summary>
        /// 删除该列中不包含特定字符串中任意字符的行的功能
        /// </summary>
        /// <param name="table"></param>
        /// <param name="colName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public DataTable RemoveRowsNotContain(DataTable table, string colName, string value)
        {

            // 创建一个新的DataTable以存储满足条件的行
            DataTable filteredTable = table.Clone();

            foreach (DataRow row in table.Rows)
            {
                string cellValue = row[colName].ToString();
                bool containsAnyChar = value.Any(c => cellValue.Contains(c));
                if (containsAnyChar)
                {
                    // 如果行包含value中的任意字符,将其添加到新的DataTable中
                    filteredTable.ImportRow(row);
                }
            }

            // 返回处理后的DataTable,只包含符合条件的行
            return filteredTable;
        }

        /// <summary>
        /// 删除该列中包含特定字符串中任意字符的行的功能
        /// </summary>
        /// <param name="table"></param>
        /// <param name="colName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public DataTable RemoveRowsContainAnyCharacter(DataTable table, string colName, string value)
        {
            // 创建一个新的DataTable用于存储不需要删除的行
            DataTable filteredTable = table.Clone();

            foreach (DataRow row in table.Rows)
            {
                string cellValue = row[colName].ToString();
                // 检查cellValue是否包含value中的任意一个字符
                bool containsAnyChar = value.Any(c => cellValue.Contains(c));
                if (!containsAnyChar)
                {
                    // 如果cellValue不包含value中的任何字符,将行添加到新的DataTable
                    filteredTable.ImportRow(row);
                }
            }

            // 返回处理后的DataTable,已经删除了包含指定字符的行
            return filteredTable;
        }

        /// <summary>
        /// 删除该列中值为空字符串的行
        /// </summary>
        /// <param name="table">待处理的源DataTable</param>
        /// <param name="colName">要检查的列名</param>
        /// <returns>处理后的DataTable</returns>
        public DataTable RemoveRowsWithEmptyString(DataTable table, string colName)
        {
            // 使用DataTable.Select方法筛选符合条件的行
            DataRow[] rowsToDelete = table.Select($"{colName} = ''");

            // 删除符合条件的行
            foreach (DataRow row in rowsToDelete)
            {
                table.Rows.Remove(row);
            }

            // 返回处理后的DataTable
            return table;
        }



        /// <summary>
        /// 删除colName列中不等于该值的行
        /// </summary>
        /// <param name="colName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public DataTable RemoveRowsNotEqual(DataTable table, string colName, object value)
        {

            DataColumn column = table.Columns[colName];

            // 根据列的数据类型进行值的转换
            value = Convert.ChangeType(value, column.DataType);

            // 使用DataTable.Select方法筛选符合条件的行
            DataRow[] rowsToDelete = table.Select($"{colName} <> '{value}'");

            // 删除符合条件的行
            foreach (DataRow row in rowsToDelete)
            {
                table.Rows.Remove(row);
            }

            // 返回处理后的DataTable
            return table;
        }

        /// <summary>
        /// 删除colName列中等于该值的行   
        /// </summary>      
        /// <param name="colName"></param>      
        /// <param name="value"></param>
        /// <returns></returns>
        public DataTable RemoveRowsEqual(DataTable table, string colName, object value)
        {
            DataColumn column = table.Columns[colName];
            // 根据列的数据类型进行值的转换
            value = Convert.ChangeType(value, column.DataType);
            // 使用DataTable.Select方法筛选符合条件的行
            DataRow[] rowsToDelete = table.Select($"{colName} = '{value}'");
            // 删除符合条件的行     
            foreach (DataRow row in rowsToDelete)
            {
                table.Rows.Remove(row);
            }
            //返回处理后的DataTable    
            return table;
        }


        /// <summary>
        /// 排序从大到小
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public DataTable SortDataTable(DataTable table, string columnName)
        {
            // 使用Select方法按照指定列的值从大到小排序
            DataRow[] sortedRows = table.Select("", $"{columnName} DESC");

            // 创建新的DataTable用于存储排序后的数据
            DataTable sortedTable = table.Clone();

            // 复制排序后的数据到新的DataTable中
            foreach (DataRow row in sortedRows)
            {
                sortedTable.ImportRow(row);
            }

            return sortedTable;
        }
        /// <summary>
        /// 排序从小到大
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public DataTable SortColumnAscending(DataTable table, string columnName)
        {
            if (!table.Columns.Contains(columnName))
            {
                throw new ArgumentException($"Column '{columnName}' does not exist in the table.");
            }

            table.DefaultView.Sort = $"{columnName} ASC";
            return table.DefaultView.ToTable();
        }


        /// <summary>
        /// 删除指定列
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public DataTable RemoveColumn(DataTable table, string columnName)
        {
            // 检查表格中是否存在该列
            if (!table.Columns.Contains(columnName))
            {
                throw new ArgumentException($"Column '{columnName}' does not exist in the table.");
            }

            // 删除指定列
            table.Columns.Remove(columnName);

            return table;
        }

        /// <summary>
        /// 只保留该列
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columnName"></param>   
        /// <returns></returns>
        public static DataTable KeepColumn__0(DataTable table, string columnName)
        {
            // 获取指定列  
            DataColumn col = table.Columns[columnName];

            // 备份主键约束  
            DataColumn[] keyCols = table.PrimaryKey;

            // 使用for循环移除其他所有列  
            for (int i = table.Columns.Count - 1; i >= 0; i--)
            {
                DataColumn c = table.Columns[i];
                if (c != col)
                {
                    table.Columns.Remove(c);
                }
            }

            // 重新设置主键约束  
            if (keyCols != null)
            {
                table.PrimaryKey = keyCols;
            }

            return table;
        }
        /// <summary>
        /// 只保留指定列
        /// </summary>
        /// <param name="table">原始 DataTable</param>
        /// <param name="columnName">要保留的列名</param>   
        /// <returns>只包含指定列的新 DataTable</returns>
        public static DataTable KeepColumn(DataTable table, string columnName)
        {
            // 新建一个 DataTable 用于存储指定列
            DataTable newTable = new DataTable();

            // 获取指定列
            DataColumn col = table.Columns[columnName];

            // 将指定列添加到新 DataTable 中
            newTable.Columns.Add(col.ColumnName, col.DataType);

            // 复制原 DataTable 中的数据到新 DataTable
            foreach (DataRow row in table.Rows)
            {
                DataRow newRow = newTable.NewRow();
                newRow[col.ColumnName] = row[col.ColumnName];
                newTable.Rows.Add(newRow);
            }

            return newTable;
        }




        /// <summary>
        ///  统计该列的出现次数
        /// </summary>
        /// <param name="colName"></param>
        /// <returns></returns>
        public DataTable CountColumnValues( string colName)
        {
            // 创建一个新的DataTable来存储统计结果
            DataTable resultTable = new DataTable();
            resultTable.Columns.Add(colName, typeof(string));
            resultTable.Columns.Add("Count", typeof(int));

            // 创建一个哈希表来存储每个值出现的次数
            Hashtable valueCounts = new Hashtable();

            // 遍历每一行,将每个值出现的次数添加到哈希表中
            foreach (DataRow row in dataTable.Rows)
            {
                string value = row[colName].ToString();
                if (valueCounts.ContainsKey(value))
                {
                    valueCounts[value] = (int)valueCounts[value] + 1;
                }
                else
                {
                    valueCounts[value] = 1;
                }
            }

            // 将哈希表转换为列表,并根据次数进行降序排序
            var sortedValueCounts = from entry in valueCounts.Cast<DictionaryEntry>()
                                    orderby (int)entry.Value descending
                                    select entry;

            // 将每个值和它出现的次数添加到结果表中
            foreach (DictionaryEntry entry in sortedValueCounts)
            {
                DataRow resultRow = resultTable.NewRow();
                resultRow[colName] = entry.Key;
                resultRow["Count"] = entry.Value;
                resultTable.Rows.Add(resultRow);
            }

            // 返回包含统计结果的DataTable
            return resultTable;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columnName"></param>
        /// <param name="newType"></param>
        /// <returns></returns>
        public DataTable ChangeColumnType(DataTable table, string columnName, Type newType)
        {
            // 检查表格中是否存在该列
            if (!table.Columns.Contains(columnName))
            {
                throw new ArgumentException($"Column '{columnName}' does not exist in the table.");
            }

            // 创建新列
            DataColumn newColumn = new DataColumn(columnName + "_new", newType);

            // 将新列添加到旧列后面
            int columnIndex = table.Columns.IndexOf(columnName);
            table.Columns.Add(newColumn);
            newColumn.SetOrdinal(columnIndex + 1);

            // 复制数据到新列
            foreach (DataRow row in table.Rows)
            {
                object value = row[columnName];
                if (value != DBNull.Value)
                {
                    row[newColumn] = Convert.ChangeType(value, newType);
                }
            }

            // 删除旧列并将新列重命名为旧列名
            table.Columns.Remove(columnName);
            newColumn.ColumnName = columnName;

            return table;
        }


        /// <summary>
        /// 删除重复行
        /// </summary>
        /// <param name="colName"></param>
        /// <returns></returns>
        public DataTable RemoveDuplicateRows(string colName)
        {
            // 记录原始行数
            int originalRowCount = dataTable.Rows.Count;

            // 创建一个临时的DataTable来存储不重复的行
            DataTable tempTable = new DataTable();
            tempTable = dataTable.Clone();

            // 创建一个哈希集合来存储已经出现过的值
            HashSet<string> uniqueValues = new HashSet<string>();
            int rowCount = 0; // 定义计数器

            // 遍历每一行
            foreach (DataRow row in dataTable.Rows)
            {
                // 获取当前行的列值
                string value = row[colName].ToString();

                // 如果这个值没有出现过,将它添加到哈希集合和临时表中
                if (!uniqueValues.Contains(value))
                {
                    uniqueValues.Add(value);
                    tempTable.ImportRow(row);
                }
            }

            // 返回删除的行数
            rowCount = originalRowCount - tempTable.Rows.Count;
            textBox1.AppendText("删除重复行: "+rowCount+"行" + Environment.NewLine);

            // 返回新的不含重复行的DataTable
            return tempTable;
        }

        /// <summary>
        /// 从剪贴板中获取字符串,分析每个字符出现次数 除了换行符
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public DataTable AnalyzeCharacterFrequency()
        {
            string input = Clipboard.GetText();

            // 创建一个临时的DataTable来存储结果
            DataTable resultTable = new DataTable();
            resultTable.Columns.Add("Character", typeof(string));
            resultTable.Columns.Add("Frequency", typeof(int));

            // 创建一个哈希字典来记录每个字符串的出现次数
            Dictionary<string, int> frequencyDict = new Dictionary<string, int>();

            // 遍历每个字符并计数
            foreach (char c in input)
            {
                string key = ConvertSpecialCharacters(c.ToString());
                if (frequencyDict.ContainsKey(key))
                {
                    frequencyDict[key]++;
                }
                else
                {
                    frequencyDict[key] = 1;
                }
            }

            // 将哈希字典中的结果添加到DataTable中
            foreach (KeyValuePair<string, int> pair in frequencyDict)
            {
                if (pair.Key.Length == 1 && char.IsDigit(pair.Key[0]) && int.Parse(pair.Key) >= 0 && int.Parse(pair.Key) <= 9)
                {//仅当KeyValuePair<string, int>中的键("Character")是0-9之间的数字时才将行添加到DataTable中
                    DataRow row = resultTable.NewRow();
                    row["Character"] = pair.Key;
                    row["Frequency"] = pair.Value;

                    resultTable.Rows.Add(row);
                }
            }


            // 按照出现次数从大到小对结果进行排序
            DataView view = resultTable.DefaultView;
            view.Sort = "Frequency DESC";
            resultTable = view.ToTable();

            // 返回结果DataTable
            return resultTable;
        }


        /// <summary>
        /// 显示统计表格的窗口
        /// </summary>
        /// <param name="dataTable"></param>
        void new_Form_Show(DataTable dataTable)
        {
            var form = new Form();
            var dataGrid = new DataGridView { Dock = DockStyle.Fill, DataSource = dataTable };
            form.Controls.Add(dataGrid);
            form.Text = "row : " + dataTable.Rows.Count + " ,col : " + dataTable.Columns.Count;
            form.ShowDialog();

        }

        /// <summary>
        /// 将正确地将制表符 (\t)、空格 ( )、换行符 (\n) 和回车符 (\r) 转换为相应的可见字符。
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string ConvertSpecialCharacters(string input)
        {
            StringBuilder result = new StringBuilder();

            foreach (char c in input)
            {
                switch (c)
                {
                    case '\t':
                        result.Append("\\t"); // 转换制表符为"\t"
                        break;
                    case ' ':
                        result.Append(" "); // 转换空格为"\s"
                        break;
                    case '\n':
                        result.Append("\\n"); // 转换换行符为"\n"
                        break;
                    case '\r':
                        result.Append("\\r"); // 转换回车符为"\r"
                        break;
                    default:
                        result.Append(c); // 其他字符保持不变
                        break;
                }
            }

            return result.ToString();
        }



        public void SaveDataTableToFile(DataTable dataTable)
        {
            // 将 DataTable 写入到 CSV 文件中
            using (StreamWriter writer = new StreamWriter(fileName))
            {
                // 写入列名
                writer.WriteLine(string.Join(",", dataTable.Columns.Cast<DataColumn>().Select(column => column.ColumnName)));

                // 写入数据行
                foreach (DataRow row in dataTable.Rows)
                {
                    writer.WriteLine(string.Join(",", row.ItemArray));
                }
            }
        }

        public  string GetTableSchema(DataTable table)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("------------------------------------------"+"\r\n");
            sb.Append("当前表格列数据信息:\r\n");
            sb.Append("总共有多少列:" + table.Columns.Count+ "\r\n");
            foreach (DataColumn column in table.Columns)
            {
                sb.Append("列名称:");
                sb.Append(column.ColumnName);
                sb.Append("\t,数据类型:");
                sb.Append(column.DataType.Name);
                sb.Append("\r\n");
            }

            if (sb.Length > 2)
            {
                sb.Remove(sb.Length - 2, 2);
            }
            sb.Append( "\r\n"+ "------------------------------------------" + "\r\n");
            return sb.ToString();
        }


        private void button2_Click(object sender, EventArgs e)
        {
            // 显示数据
           dataTable = LoadDataTableFromFile();

        }

        public DataTable LoadDataTableFromFile()
        {
            DataTable dataTable = new DataTable();

            // 从 CSV 文件中读取 DataTable
            using (StreamReader reader = new StreamReader(fileName))
            {
                string line = reader.ReadLine();
                if (!string.IsNullOrEmpty(line))
                {
                    string[] headers = line.Split(',');
                    foreach (string header in headers)
                    {
                        dataTable.Columns.Add(header);
                    }
                }

                while ((line = reader.ReadLine()) != null)
                {
                    string[] fields = line.Split(',');
                    DataRow row = dataTable.NewRow();
                    for (int i = 0; i < fields.Length; i++)
                    {
                        row[i] = fields[i];
                    }
                    dataTable.Rows.Add(row);
                }
            }

            return dataTable;
        }

        private void button3_Click(object sender, EventArgs e)
        {

            Clipboard.SetText("0");
            Clipboard.SetText("1");
            Clipboard.SetText("2");
            Clipboard.SetText("3");
            StringBuilder sb = new StringBuilder();

            // 添加列名称
            foreach (DataColumn column in dataTable.Columns)
            {
                sb.Append(column.ColumnName);
                sb.Append('\t');
            }
            sb.Length--; // 删除最后一个制表符
            sb.AppendLine();

            // 添加行数据
            foreach (DataRow row in dataTable.Rows)
            {
                for (int i = 0; i < dataTable.Columns.Count; i++)
                {
                    sb.Append(row[i]);
                    sb.Append('\t');
                }
                sb.Length--; // 删除最后一个制表符

                // 如果不是最后一行,添加回车符
                if (row != dataTable.Rows[dataTable.Rows.Count - 1])
                {
                    sb.AppendLine();
                }
            }

            Clipboard.SetText(sb.ToString());
        }

        private void button4_Click(object sender, EventArgs e)
        {
            dataTable = AnalyzeCharacterFrequency();
        }

        private void textBox6_TextChanged(object sender, EventArgs e)
        {

        }

        /// <summary>
        ///  DataTable 中根据行索引删除行
        /// </summary>
        /// <param name="table"></param>
        /// <param name="rowIndex"></param>
        public DataTable DeleteRowByIndex(DataTable table, int rowIndex)
        {
            if (rowIndex >= 0 && rowIndex < table.Rows.Count)
            {
                table.Rows.RemoveAt(rowIndex);
            }
            return table;
        }

        /// <summary>
        /// 删除DataTable中指定行索引及其以上的所有行
        /// </summary>
        /// <param name="table">要操作的DataTable</param>
        /// <param name="rowIndex">起始行索引</param>
        public DataTable DeleteRowsAboveIndex(DataTable table, int rowIndex)
        {
            // 确保索引在有效范围内
            if (rowIndex >= 0 && rowIndex < table.Rows.Count)
            {
                // 从指定的行索引开始删除,直到表的第一行
                for (int i = rowIndex; i >= 0; i--)
                {
                    table.Rows.RemoveAt(i);
                }
            }
            return table;
        }



        /// <summary>  
        /// 从DataTable中删除指定行索引及其以下的所有行  
        /// </summary>  
        /// <param name="table">要操作的DataTable</param>  
        /// <param name="rowIndex">起始行索引</param>  
        /// <returns>返回修改后的DataTable</returns>  
        public DataTable DeleteRowsFromIndex(DataTable table, int rowIndex)
        {
            // 检查DataTable是否为null以及索引是否在有效范围内  
            // (索引不能小于0,也不能大于或等于表的行数)  
            if (table != null && rowIndex >= 0 && rowIndex < table.Rows.Count)
            {
                // 从指定的行索引开始,删除该行及其以下的所有行  
                // 由于每次删除一行后,下一行会自动成为当前索引的行,所以不需要手动增加索引  
                while (rowIndex < table.Rows.Count)
                {
                    // 删除当前索引处的行  
                    table.Rows.RemoveAt(rowIndex);
                    // 由于已删除一行,无需对rowIndex进行递增操作  
                }
            }
            // 返回修改后的DataTable(注意:DataTable是引用类型,所以直接返回table即可)  
            return table;
        }

        /// <summary> 
        /// 删除colName列中小于该值的行
        /// </summary>
        /// <param name="colName">列名</param>  
        /// <param name="value">比较的值</param>
        /// <returns>过滤后的DataTable</returns>
        public DataTable RemoveRowsLessThan(DataTable table, string colName, object value)
        {
            /// 获取指定列
            DataColumn column = table.Columns[colName];

            /// 将比较的值转换为列的数据类型
            value = Convert.ChangeType(value, column.DataType);

            /// 使用DataTable.Select选择colName列中小于value的行
            DataRow[] rowsToDelete = table.Select($"{colName} < '{value}'");

            /// 删除选择的行
            foreach (DataRow row in rowsToDelete)
            {
                table.Rows.Remove(row);
            }

            /// 返回处理后的DataTable
            return table;
        }

        /// <summary>
        /// 删除colName列中大于该值的行 
        /// </summary>
        /// <param name="colName">列名</param>   
        /// <param name="value">比较的值</param> 
        /// <returns>过滤后的DataTable</returns>
        public DataTable RemoveRowsGreaterThan(DataTable table, string colName, object value)
        {
            /// 获取指定列    
            DataColumn column = table.Columns[colName];

            /// 将比较的值转换为列的数据类型      
            value = Convert.ChangeType(value, column.DataType);

            /// 使用DataTable.Select选择colName列中大于value的行
            DataRow[] rowsToDelete = table.Select($"{colName} > '{value}'");

            /// 删除选择的行      
            foreach (DataRow row in rowsToDelete)
            {
                table.Rows.Remove(row);
            }

            /// 返回处理后的DataTable       
            return table;
        }


        /// <summary> 
        /// 单元格上右键点击时 创建上下文菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
                {
                    dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
                    DataGridViewColumn currentColumn = dataGridView1.Columns[e.ColumnIndex];
                    string columnName = currentColumn.Name;//获取列名称

                    textBox1.AppendText("右键单击 单元格 事件 :[" + e.RowIndex +","+ e.ColumnIndex+"] , 列名称:"+ columnName + Environment.NewLine);

                    // 获取当前单元格的值
                    object cellValue = dataGridView1.CurrentCell.Value;

                    // 创建上下文菜单
                    ContextMenuStrip contextMenuStrip = new ContextMenuStrip();

                    contextMenuStrip.Items.Add("删除->小于该值的行").Click += (s, args) =>
                    {
                        //检查 cellValue 是否为 null,以确保单元格中有值。
                        if (cellValue != null)
                        {
                            dataTable = RemoveRowsLessThan(dataTable, columnName, cellValue);
                            textBox1.AppendText("删除->小于该值的行,RowIndex:" + e.RowIndex + Environment.NewLine);
                        }

                    };


                    contextMenuStrip.Items.Add("删除->大于该值的行 ").Click += (s, args) =>
                    {
                        //检查 cellValue 是否为 null,以确保单元格中有值。
                        if (cellValue != null)
                        {
                            dataTable = RemoveRowsGreaterThan(dataTable, columnName, cellValue);
                            textBox1.AppendText("删除->大于该值的行,RowIndex:" + e.RowIndex + Environment.NewLine);
                        }

                    };

                    contextMenuStrip.Items.Add("删除该行").Click += (s, args) =>
                    {
                        //检查 cellValue 是否为 null,以确保单元格中有值。
                        if (cellValue != null)
                        {
                            dataTable = DeleteRowByIndex(dataTable, e.RowIndex);
                            textBox1.AppendText("删除该行,RowIndex:" + e.RowIndex + Environment.NewLine);
                        }
                    };


                    contextMenuStrip.Items.Add("删除->等于该值的行").Click += (s, args) =>
                    {
                        //检查 cellValue 是否为 null,以确保单元格中有值。
                        if (cellValue != null)
                        {
                            dataTable = RemoveRowsEqual(dataTable, columnName, cellValue);
                            textBox1.AppendText("删除->等于该值的行,RowIndex:" + e.RowIndex + Environment.NewLine);
                        }
                    };

                    contextMenuStrip.Items.Add("删除->不等于该值的行").Click += (s, args) =>
                    {
                        //检查 cellValue 是否为 null,以确保单元格中有值。
                        if (cellValue != null)
                        {
                            dataTable = RemoveRowsNotEqual(dataTable, columnName, cellValue);
                            textBox1.AppendText("删除->不等于该值的行,RowIndex:" + e.RowIndex + Environment.NewLine);
                        }
                    };



                    contextMenuStrip.Items.Add("删除该行及上面的所有行").Click += (s, args) =>
                    {
                        //检查 cellValue 是否为 null,以确保单元格中有值。
                        if (cellValue != null)
                        {
                            dataTable = DeleteRowsAboveIndex(dataTable, e.RowIndex);
                            textBox1.AppendText("删除该行,RowIndex:" + e.RowIndex + Environment.NewLine);
                        }
                    };

                    contextMenuStrip.Items.Add("删除该行及下面的所有行").Click += (s, args) =>
                    {
                        //检查 cellValue 是否为 null,以确保单元格中有值。
                        if (cellValue != null)
                        {
                            dataTable = DeleteRowsFromIndex(dataTable, e.RowIndex);
                            textBox1.AppendText("删除该行,RowIndex:" + e.RowIndex + Environment.NewLine);
                        }
                    };


                    // 显示上下文菜单
                    contextMenuStrip.Show(MousePosition);
                }
            }
        }


        /// <summary>
        /// 统计次数出现的数
        /// </summary>
        /// <param name="nums"></param>
        /// <returns></returns>
        int GetMajorityItem(int[] nums)
        {
            int count = 0;
            int majorityItem = 0;

            for (int i = 0; i < nums.Length; i++)
            {
                int item = nums[i];
                int sameCount = 1;

                for (int j = i + 1; j < nums.Length; j++)
                {
                    if (nums[j] == item)
                    {
                        sameCount++;
                    }
                }

                if (sameCount > count)
                {
                    count = sameCount;
                    majorityItem = item;
                }
            }

            return majorityItem;
        }

        public static string[] RemoveNonMatchingLengthElements(int length, string[] strArray, int[] lengthArray)
        {
            List<string> strList = new List<string>(strArray.Length); //指定容量为strArray.Length

            for (int i = 0; i < strArray.Length; i++)
            {
                if (lengthArray[i] == length)
                {
                    strList.Add(strArray[i]); //使用Add方法而不是Append
                }
            }
            return strList.ToArray();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            // 从剪贴板读取数据
            if (Clipboard.ContainsText())
            {
                string clipboardData = Clipboard.GetText();

                string lineSeparator = GetLineSeparator(clipboardData);
                textBox1.AppendText("分析换行符为: " + lineSeparator + Environment.NewLine);

                var lines = clipboardData.Split(new string[] { lineSeparator }, StringSplitOptions.None);



                textBox1.AppendText("读取数据行数:" + lines.Length + Environment.NewLine);
                if (lines.Length <= 1)
                {
                    textBox1.AppendText("数据格式错误,必须包含列名并且至少有2行数据。" + Environment.NewLine);
                    return;
                }

                //去除每行 首尾空白字符
                lines = TrimLines(lines);

                //删除最后面连续空行
                lines = RemoveTrailingEmptyLines(lines);

                //把连续的空格替换为制表符
                lines = ReplaceSpacesWithTabs(lines);

                //检测制表符数量
                (bool consistent, int[] tabCounts) = CheckTabCounts(lines);
                if (tabCounts[0] < 1)
                {
                    textBox1.AppendText("每行的制表符数量为0" + Environment.NewLine);

                    textBox1.AppendText("尝试转换空格为制表符 " + Environment.NewLine);
                }


                //分析每行制表符的数量
                (consistent, tabCounts) = CheckTabCounts(lines);
                textBox1.AppendText("每行的制表符数量为:" + tabCounts[0] + Environment.NewLine);
                if (tabCounts[0] < 1)
                {

                    return;
                }

                // 所有行中 制表符数量 出现最多的 制表符数量,大多数行中一致的制表符数量
                var maxMajorityItem = GetMajorityItem(tabCounts);
                //删除制表符不等于 大多数行中一致的制表符数量
                lines = RemoveNonMatchingLengthElements(maxMajorityItem, lines, tabCounts);

                (consistent, tabCounts) = CheckTabCounts(lines);
                if (consistent == false)
                {
                    //每行制表符的数量不一致
                    textBox1.AppendText("每行制表符的数量不一致 失败" + Environment.NewLine);
                    //展示出每行 每行制表符的数量
                    textBox1.AppendText("行\t制表符数量" + Environment.NewLine);
                    for (int i = 0; i < tabCounts.Length; i++)
                    {
                        textBox1.AppendText((i + 1) + "\t" + tabCounts[i] + Environment.NewLine);
                    }
                    return;
                }





                DataTable dataTable1 = new DataTable { };



                if (tabCounts[0] >= 1 && consistent)
                {
                    textBox1.AppendText("每行的制表符数量一致 表格数据正确" + Environment.NewLine);

                    // 处理数据
                    int rowCount = lines.Length;
                    int colCount = lines[0].Split('\t').Length;
                    string[] columnNames = lines[0].Split('\t');


                    //取第一行为表头时 表头不能重复
                    //判定第一行是否有重复值
                    if (HasDuplicate(columnNames))
                    {
                        //有重复值则 自动生成默认表头标题
                        textBox1.AppendText("取第一行为表头标题时 发现表头有重复值 自动生成默认表头标题" + Environment.NewLine);
                        for (int i = 0; i < colCount; i++)
                        {

                            dataTable1.Columns.Add("列" + (i + 1), typeof(string));
                        }
                    }
                    else
                    {
                        //没有重复值 取第一行为表头标题
                        textBox1.AppendText("取第一行为表头标题" + Environment.NewLine);
                        for (int i = 0; i < colCount; i++)
                        {

                            dataTable1.Columns.Add(columnNames[i], typeof(string));
                        }

                    }


                    for (int i = 1; i < rowCount; i++)
                    {
                        string[] cells = lines[i].Split('\t');
                        if (cells.Length == colCount)
                        {
                            dataTable1.Rows.Add(cells);
                        }
                    }
                    // 显示数据
                    dataTable = dataTable1;


                }

            }
            else
            {
                MessageBox.Show("剪贴板中没有文本数据。");
            }
        }
        public static List<Score> GetScores(List<List<string>> inputData)
        {
            Dictionary<int, Score> scores = new Dictionary<int, Score>();

            for (int i = 0; i < inputData.Count; i++)
            {
                int number = int.Parse(inputData[i][1]);
                int times = int.Parse(inputData[i][2]);

                if (!scores.ContainsKey(number))
                {
                    scores.Add(number, new Score() { Number = number });
                }

                scores[number].PositionScore += GetPositionScore(i + 1);
                scores[number].TimesScore += GetTimesScore(times);
            }

            int rank = 1;
            foreach (Score score in scores.Values)
            {
                score.Rank = rank++;
                score.TotalScore = score.PositionScore + score.TimesScore;
            }

            return scores.Values.ToList();
        }



        public static double GetPositionScore(int position)
        {
            switch (position)
            {
                case 1: return 1.0;
                case 2: return 0.9;
                case 3: return 0.8;
                case 4: return 0.7;
                case 5: return 0.6;
                case 6: return 0.5;
                case 7: return 0.4;
                case 8: return 0.3;
                case 9: return 0.2;
                default: return 0.1;
            }
        }

        public static double GetTimesScore(int times)
        {
            switch (times)
            {
                case 1: return 0.1;
                case 2: return 0.2;
                case 3: return 0.3;
                case 4: return 0.4;
                case 5: return 0.5;
                case 6: return 0.6;
                case 7: return 0.7;
                case 8: return 0.8;
                case 9: return 0.9;
                default: return 1.0;
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            // 显示数据
            DataTable resultTable = new DataTable();
            dataTable = resultTable;
 

        }

        /// <summary>
        ///  撤销 返回上一个表格
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            // 撤销和恢复 模式,不记录表格数据了
            Undo_Redo_Mode = true;

              var lastIndex = curr_history_index - 1;
            //如果有上一个表格
            if (lastIndex >= 0 )
            {
                curr_history_index = lastIndex;
                dataTable = dataTable_history[curr_history_index];
             
                textBox1.AppendText("撤销 返回上一个表格" +  Environment.NewLine);
            }
            else
            {
                textBox1.AppendText("无法撤销:已经是第一个表格了" +  Environment.NewLine);
            }



            Undo_Redo_Mode = false;
        }

        /// <summary>
        /// 恢复 返回下一个表格
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button8_Click(object sender, EventArgs e)
        {

            Undo_Redo_Mode = true;

            var nextIndex = curr_history_index +1;
            //如果有下一个表格
            if (nextIndex <= dataTable_history.Count-1)
            {
                curr_history_index = nextIndex;
                dataTable = dataTable_history[curr_history_index];
               
                textBox1.AppendText("恢复 返回下一个表格" + Environment.NewLine);
            }
            else
            {
                textBox1.AppendText("无法恢复:已经是最后一个表格了"  + Environment.NewLine);
            }





            //  撤销和恢复 模式,不记录表格数据了
            Undo_Redo_Mode = false;
        }

        /// <summary>
        /// 从剪贴板追加数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button9_Click(object sender, EventArgs e)
        {
            //克隆的 DataTable 中的数据
            DataTable clonedDataTable = _dataTable.Clone();
            clonedDataTable.Clear(); // 清空克隆的 DataTable 中的数据
            foreach (DataRow row in _dataTable.Rows)
            {
                clonedDataTable.ImportRow(row); // 导入原始 DataTable 中的每一行数据到克隆的 DataTable
            }



            // 从剪贴板读取数据
            if (Clipboard.ContainsText())
            {
                string clipboardData = Clipboard.GetText();

                string lineSeparator = GetLineSeparator(clipboardData);
                var lines = clipboardData.Split(new string[] { lineSeparator }, StringSplitOptions.None);

                if (lines.Length <= 1)
                {
                    textBox1.AppendText("数据格式错误,必须包含列名并且至少有2行数据。" + Environment.NewLine);
                    return;
                }

                lines = TrimLines(lines);
                lines = RemoveTrailingEmptyLines(lines);

                (bool consistent, int[] tabCounts) = CheckTabCounts(lines);
                if (tabCounts[0] < 1)
                {
                    textBox1.AppendText("每行的制表符数量为0" + Environment.NewLine);
                    lines = ReplaceSpacesWithTabs(lines);
                    textBox1.AppendText("尝试转换空格为制表符 " + Environment.NewLine);
                }

                (consistent, tabCounts) = CheckTabCounts(lines);
                if (tabCounts[0] < 1)
                {
                    return;
                }

                if (!consistent)
                {
                    textBox1.AppendText("每行制表符的数量不一致 失败" + Environment.NewLine);

                    textBox1.AppendText("行\t制表符数量" + Environment.NewLine);
                    for (int i = 0; i < tabCounts.Length; i++)
                    {
                        textBox1.AppendText((i + 1) + "\t" + tabCounts[i] + Environment.NewLine);
                    }
                    return;
                }

                if (tabCounts[0] >= 1 && consistent)
                {
                    textBox1.AppendText("每行的制表符数量一致 表格数据正确" + Environment.NewLine);

                    int rowCount = lines.Length;
                    int colCount = lines[0].Split('\t').Length;
                    string[] columnNames = lines[0].Split('\t');

                    // 追加新列到 DataTable
                    // 检查重复列名
                    foreach (string columnName in columnNames)
                    {
                        DataColumn existingColumn = clonedDataTable.Columns[columnName];
                        if (existingColumn == null)
                        {// 添加新列
                            clonedDataTable.Columns.Add(columnName, typeof(string));
                            int columnIndex = clonedDataTable.Columns.IndexOf(columnName);
                            int rowCount1 = clonedDataTable.Rows.Count;

                            // 添加对应列的数据
                            for (int i = 1; i < rowCount1; i++)
                            {
                                string[] cells = lines[i].Split('\t');
                                if (cells.Length > columnIndex)
                                {
                                    clonedDataTable.Rows[i - 1][columnIndex] = cells[columnIndex];
                                }
                            }
                        }
                        else
                        {// 列名重复,将数据添加到已存在列的最后一行

                            int rowIndex = clonedDataTable.Rows.Count - 1;
                            DataRow lastRow = clonedDataTable.Rows[rowIndex];
                        }
                    }

                    for (int i = 1; i < rowCount; i++)
                    {
                        string[] cells = lines[i].Split('\t');
                        if (cells.Length == colCount)
                        {
                            clonedDataTable.Rows.Add(cells);
                        }
                    }
                }
                dataTable = clonedDataTable;

            }
            else
            {
                MessageBox.Show("剪贴板中没有文本数据。");
            }
        }

        private void button10_Click(object sender, EventArgs e)
        {
            dataTable = CountStrings(dataTable);
        }



        /// <summary>
        /// 为给定的DataTable的第一列添加一个序号列,并返回处理后的DataTable副本
        /// </summary>
        /// <param name="table">待处理的源DataTable</param>
        /// <returns>添加了序号列的DataTable副本</returns>
        public DataTable AddSequentialNumberColumnToFirstColumn(DataTable table)
        {
            // 检查DataTable是否为空或无数据行
            if (table == null || table.Rows.Count == 0)
            {
                throw new ArgumentException("输入的DataTable不能为空或无数据行");
            }

            // 创建新的DataTable,包含序号列和其他原列
            DataTable processedTable = new DataTable();


            // 确定新序号列的唯一名称
            int suffixCounter = 1;
            string columnName = "序号";
            while (table.Columns.Contains(columnName)) // 检查是否存在同名列并适当命名
            {
                columnName = $"序号_{suffixCounter++}";
            }

            // 在第一位置添加新的序号列
            DataColumn numberColumn = new DataColumn(columnName, typeof(int));
            table.Columns.Add(numberColumn);
            numberColumn.SetOrdinal(0);  // 将这个新列设置为第一列

            // 填充新列的序号
            int rowIndex = 1;
            foreach (DataRow row in table.Rows)
            {
                row[columnName] = rowIndex++;
            }

            return table;
        }


        /// <summary>
        /// 为给定的DataTable的第一行添加一个序号行,并返回处理后的DataTable副本
        /// </summary>
        /// <param name="table">待处理的源DataTable</param>
        /// <returns>添加了序号行的DataTable副本</returns>
        public DataTable AddSequentialNumberRowToFirstRow(DataTable table)
        {
            // 检查DataTable是否为空或无列
            if (table == null || table.Columns.Count == 0)
            {
                throw new ArgumentException("输入的DataTable不能为空或无列");
            }

            // 创建序号行
            DataRow numberRow = table.NewRow();
            for (int i = 0; i < table.Columns.Count; i++)
            {
                // 尝试将列名作为序号,如果不是数字类型则填充为DBNull或特定标识符
                if (table.Columns[i].DataType == typeof(int) ||
                    table.Columns[i].DataType == typeof(long) ||
                    table.Columns[i].DataType == typeof(string) ||
                    table.Columns[i].DataType == typeof(short))
                {
                    numberRow[i] = i + 1; // 序号从1开始
                }
                else
                {
                    numberRow[i] = DBNull.Value; // 或使用任何适合列数据类型的默认值
                }
            }

            // 将序号行插入到DataTable的第一行
            table.Rows.InsertAt(numberRow, 0);

            return table;
        }


        /// <summary>
        /// 将输入的DataTable中所有列(从第二列开始)的数据依次纵向连接到第一列的末尾,并返回处理后的新的DataTable。
        /// 新表中保持原第一列的名称。
        /// </summary>
        /// <param name="inputTable">待处理的源DataTable</param>
        /// <returns>处理后的新的DataTable</returns>
        public DataTable StackColumnsVertically(DataTable inputTable)
        {
            // 检查输入的DataTable是否为空或列数不足2列
            if (inputTable == null || inputTable.Rows.Count == 0 || inputTable.Columns.Count < 2)
            {
                throw new ArgumentException("输入的DataTable不能为空、无数据行或列数不足2列");
            }

            // 创建一个新的DataTable用于存放处理后的数据
            DataTable processedTable = new DataTable();

            // 添加新列,列名与原第一列相同,但数据类型设置为object,以便能容纳任何类型的数据
            processedTable.Columns.Add(inputTable.Columns[0].ColumnName, typeof(object));

            // 先处理第一列,将所有值添加到新DataTable中
            foreach (DataRow row in inputTable.Rows)
            {
                processedTable.Rows.Add(row[0]);
            }

            // 遍历除第一列之外的所有列
            for (int columnIndex = 1; columnIndex < inputTable.Columns.Count; columnIndex++)
            {
                // 对当前列中的每一行进行遍历
                foreach (DataRow sourceRow in inputTable.Rows)
                {
                    // 获取当前列的值
                    object columnValue = sourceRow[columnIndex];

                    // 将当前列的值添加到新的DataTable中
                    processedTable.Rows.Add(columnValue);
                }
            }

            return processedTable;
        }

        //所有列的数据合并到一个新的单列
        private void button11_Click(object sender, EventArgs e)
        {
            dataTable = StackColumnsVertically(dataTable);
        }

        /// <summary>
        /// 增加序号列
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button12_Click(object sender, EventArgs e)
        {
            dataTable = AddSequentialNumberColumnToFirstColumn(dataTable);
        }

        /// <summary>
        /// //增加序号行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button13_Click(object sender, EventArgs e)
        {
            dataTable = AddSequentialNumberRowToFirstRow(dataTable);
            
        }

        private void button14_Click(object sender, EventArgs e)
        {
            // 提取所有数字并转换为 int 数组
            int[] numbers = dataTable.AsEnumerable() // 将 DataTable 转换为 EnumerableRowCollection
                                     .SelectMany(row => row.ItemArray)
                                     .SelectMany(element => element.ToString())
                                     .Where(char.IsDigit)
                                     .Select(char.ToString)
                                     .Select(int.Parse)
                                     .ToArray();

            // 初始化变量
            int totalNumbers = numbers.Length;
            int sumOfNumbers = numbers.Sum();
            int minNumber = numbers.Min();
            int maxNumber = numbers.Max();

            // 计算平均值、中位数、方差和标准差
            double average = totalNumbers > 0 ? (double)sumOfNumbers / totalNumbers : 0;
            double median = totalNumbers > 0 ? numbers.OrderBy(n => n).Skip(totalNumbers / 2).Take(1).DefaultIfEmpty(0).Average() : 0;
            double variance = totalNumbers > 1 ? numbers.Average(n => Math.Pow(n - average, 2)) : 0;
            double standardDeviation = Math.Sqrt(variance);

            // 输出结果到 textBox1
            textBox1.AppendText("多少列: " + dataTable.Columns.Count + Environment.NewLine);
            textBox1.AppendText("多少行: " + dataTable.Rows.Count + Environment.NewLine);
            textBox1.AppendText("多少个元素: " + (dataTable.Columns.Count * dataTable.Rows.Count) + Environment.NewLine);
            textBox1.AppendText("共有多少个数字: " + totalNumbers + Environment.NewLine);
            textBox1.AppendText("数字的总和: " + sumOfNumbers + Environment.NewLine);
            textBox1.AppendText("平均值: " + average + Environment.NewLine);
            textBox1.AppendText("最小值: " + minNumber + Environment.NewLine);
            textBox1.AppendText("最大值: " + maxNumber + Environment.NewLine);
            textBox1.AppendText("中位数: " + median + Environment.NewLine);
            textBox1.AppendText("方差: " + variance + Environment.NewLine);
            textBox1.AppendText("标准差: " + standardDeviation + Environment.NewLine);
        }

        /// <summary>
        /// 增加默认列名行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button15_Click(object sender, EventArgs e)
        {
            // 列名行变成第一行数据,并增加默认的列名行
            dataTable = TransformDataTable(dataTable);
            textBox1.AppendText("增加表格默认列名行" + Environment.NewLine);
        }
    }


    public class Score
    {
        public int Rank { get; set; }
        public int Number { get; set; }
        public double PositionScore { get; set; }
        public double TimesScore { get; set; }
        public double TotalScore { get; set; }
    }

}


网站公告

今日签到

点亮在社区的每一天
去签到