繁体   English   中英

C#比较4个字符串数组

[英]C# Comparing 4 String arrays

我正在尝试比较四个数组。 四个数组中的两个存储文件名,而另两个数组存储哈希码。

存储文件名的数组之一与存储哈希码的数组之一相关,这些哈希码用于文件名数组中的文件。

例如,我有两个项目ProjectOneProjectTwo ProjectOne是一个数组称为的组合ProjectOneFiles和阵列ProjectOneHashcodes 这两个数组将始终具有相同的长度。

ProjectTwo将数组称为的组合ProjectTwoFiles和阵列ProjectTwoHashcodes 这些数组都将始终具有相同的长度。

但是ProjectOne 长度不必ProjectTwo长度相同 这是我目前拥有的:

private void Compare()
{
    String[] ProjectOneFiles = ProjOneFiles();
    String[] ProjectTwoFiles = ProjTwoFiles();
    String[] ProjectOneHash = ProjOneHash();
    String[] ProjectTwoHash = ProjTwoHash();

    for (int x = 0; x < ProjectOneFiles.length; ++x)
    {
        String Test1 = ProjectOneFiles[x];
        String Test2 = ProjectTwoFiles[x];
        String Test3 = ProjectOneHash[x];
        String Test4 = ProjectTwoHash[x];

        if (Test1 != Test2)
        {
            listBox6.Items.Add(Test1);
            listBox6.Items.Add(Test2);
        }
        else if ((Test1 == Test2) && (Test3 == Test4))
        {
            listBox7.Items.Add(Test1);
        }
        else
        {
            listBox8.Items.Add(Test1);
        }
    }
}

显然,现在我的问题出现在四个数组中的两个数组长度不相同的地方。 如果我尝试遍历并且使用最小的数组大小,那么我不会完全遍历最大的数组。

如果我尝试遍历一个有五个项目的数组,可以说是一百次,那显然是超出范围的异常。

我需要先比较两个文件名数组,然后如果它们相同,则比较两个哈希码数组。 如果它们满足某些要求,则需要将其放入三个列表之一,并且可能会填写所有三个列表。

我本来希望在LINQ中做到这一点:

    var onlyinfirst = 
        from s in ProjectOneFiles 
        where !ProjectTwoFiles.Contains(s) && 
              (ProjectOneHash.Contains(p) == ProjectTwoHash.Contains(p))
        select s;

    var onlyinsecond = 
        from s in ProjectTwoFiles 
        where !ProjectOneFiles.Contains(s) 
        select s;

    var onboth = 
        from s in ProjectOneFiles 
        where ProjectTwoFiles.Contains(s) 
        select s;

但是我一直坚持这样做,因为我不确定如何执行嵌套语句来删除我的if语句。 正如您在第一行中看到的那样,我试图做到这一点,但是我现在完全停滞了使用它。 文件名数组和哈希码数组都相关,因此LINQ语句必须通过一次传递,否则哈希码将不再与文件名关联(索引方式)。

我的很多问题都可以通过使用多维数组来解决,但是我发现它们非常令人困惑,我宁愿不必重写函数来使用它们。

额外的信息和功能来帮助说明

如果有人需要此信息来帮助回答我的问题,则文件名和数组是从这样的XML文档中提取的:

<?xml version="1.0" encoding="utf-8"?>
<Projects>
  <Project Name="tfasdtyf">
    <TestCycle Number="2387468">
      <Files>
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest1.dll" />
        <HashCode Code="0E-C5-03-AD-CC-21-62-49-D9-36-3F-C4-F1-17-BC-11" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
        <HashCode Code="60-46-A3-6F-82-E4-0A-00-2A-60-83-47-B2-16-F3-25" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
        <HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
      </Files>
    </TestCycle>
  </Project>
  <Project Name="tfasdtyf">
    <TestCycle Number="23423">
      <Files>
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\DllTest.dll" />
        <HashCode Code="0E-C5-03-AD-CC-21-62-49-D9-36-3F-C4-F1-17-BC-11" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.exe" />
        <HashCode Code="60-46-A3-6F-82-E4-0A-00-2A-60-83-47-B2-16-F3-24" />
        <FileName File="C:\Users\brandonm\Documents\Visual Studio 2008\Projects\WpfDllTest\WpfDllTest\bin\x86\Release\WpfDllTest.vshost.exe" />
        <HashCode Code="76-7B-6F-37-0D-3A-F2-F4-32-D1-70-A5-75-3B-DE-95" />
      </Files>
    </TestCycle>
  </Project>
  <Project Name="Music">
    <TestCycle Number="12312">
      <Files>
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 A1 Shut Ya Mouth.mp3" />
        <HashCode Code="3E-92-80-93-D5-64-19-16-26-8D-39-2A-C7-0B-C8-EB" />
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 A1 Snake Eater.mp3" />
        <HashCode Code="8B-DF-19-AE-87-52-64-2E-85-CF-57-4B-85-4D-CC-E9" />
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 A1 Stuck in the System.mp3" />
        <HashCode Code="6A-30-A7-53-FF-29-A5-DF-6D-24-DF-41-74-EE-06-4D" />
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 Martin Solveig - Hello (Featuring Dragonette).mp3" />
        <HashCode Code="93-90-A3-9C-BE-81-63-03-D7-96-1F-72-E4-ED-2D-32" />
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\01 Stimming - Funkworm.mp3" />
        <HashCode Code="8F-E1-7A-F1-B7-80-C6-2F-DC-34-FD-82-A0-DA-35-5E" />
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\1. Downlink - Ignition.mp3" />
        <HashCode Code="3D-89-B3-C2-73-A6-A0-85-02-C0-B4-F9-C8-09-14-C7" />
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\02 B1 Psychedelic Runway.mp3" />
        <HashCode Code="00-72-5C-CE-25-73-98-31-69-71-68-48-31-A1-A3-5A" />
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\02 B1 Rapture.mp3" />
        <HashCode Code="1E-A6-53-07-10-FD-A3-4C-EF-D6-92-7F-CE-97-88-6E" />
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\02_Digital-Controller.mp3" />
        <HashCode Code="94-E0-CA-5F-2B-D2-56-7B-AF-2E-04-50-58-38-4D-B4" />
        <FileName File="C:\Users\brandonm\Desktop\Stuff\Dubstep\2. Downlink - Gamma Ray.mp3" />
        <HashCode Code="3C-7A-76-AD-A6-2C-D1-7E-61-24-C0-40-BD-A7-A9-41" />
      </Files>
    </TestCycle>
  </Project>
</Projects>

然后,我有四个与下面的函数类似的函数,它们提取项目的文件名和哈希码,这就是我获取每个数组的方式:

private String[] ProjOneFiles()
{
    //Intialize the functions in the DLL
    DllTest.Funtions Functions = new DllTest.Funtions();

    //Set the location where the XMLs can be found
    String Directory = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\";

    //Get and set the number of items in the directory
    int NumFiles = Functions.GetNumFiles(Directory);

    //Create a search string to be used to determine the fullpath name of the file
    //selected from the combobox
    String SelectedFile = comboBox1.SelectedItem.ToString();
    String SearchString = "*" + SelectedFile + "*.XML";

    //Get and set the TC that will be used to get the filenames and hashcodes
    int SelectedTC = int.Parse(comboBox2.SelectedItem.ToString());

    //Get and set an array containing a full path structure to the item selected from
    //the combobox using the search string created earlier. Get files returns an array
    //thus needs to be stored in an array
    String[] FullPaths = new String[NumFiles];
    FullPaths = System.IO.Directory.GetFiles(
                    "C:\\Users\\brandonm\\Desktop\\Backup\\XML", 
                    SearchString, 
                    System.IO.SearchOption.AllDirectories);

    int number = FullPaths.GetLength(0);

    // The number of items in the XML ie. Number of Filenames in a particular TC
    int NumXMLItems = NumXMLItemsListOne();

    // Initialize the array that will hold the Filenames and their equivalent Hashcodes
    String[] FileNames = new String[NumXMLItems];

    int y = 0;

    //Itteration through the all the XMLs in the location to add the current items into their arrays
    for (int x = 0; x < NumFiles; x++)
    {
        String FullPath = FullPaths[x];

        XPathNavigator Root = new XPathDocument(FullPath).CreateNavigator();

        foreach (XPathNavigator Cycle in Root.Select(
                           String.Format(@"//TestCycle[@Number = '{0}']", 
                           SelectedTC))
        )
        {
            foreach (XPathNavigator Nav in Cycle.Select(@"Files/FileName/@File"))
            {

                FileNames[y] = Nav.Value;
                //listBox4.Items.Add(Nav.Value);
                y = y + 1;
            }
        }
    }
    return FileNames;
}

private String[] ProjOneHash()
{
    //Intialize the functions in the DLL
    DllTest.Funtions Functions = new DllTest.Funtions();

    //Set the location where the XMLs can be found
    String Directory = "C:\\Users\\brandonm\\Desktop\\Backup\\XML\\";

    //Get and set the number of items in the directory
    int NumFiles = Functions.GetNumFiles(Directory);

    //Create a search string to be used to determine the fullpath name of the file
    //selected from the combobox
    String SelectedFile = comboBox1.SelectedItem.ToString();
    String SearchString = "*" + SelectedFile + "*.XML";

    //Get and set the TC that will be used to get the filenames and hashcodes
    int SelectedTC = int.Parse(comboBox2.SelectedItem.ToString());

    //Get and set an array containing a full path structure to the item selected from
    //the combobox using the search string created earlier. Get files returns an array
    //thus needs to be stored in an array
    String[] FullPaths = new String[NumFiles];
    FullPaths = System.IO.Directory.GetFiles(
                     "C:\\Users\\brandonm\\Desktop\\Backup\\XML", 
                     SearchString, 
                     System.IO.SearchOption.AllDirectories);
    int number = FullPaths.GetLength(0);

    // The number of items in the XML ie. Number of Filenames in a particular TC
    int NumXMLItems = NumXMLItemsListOne();

    // Initialize the array that will hold the Filenames and their equivalent Hashcodes
    String[] HashCode = new String[NumXMLItems];

    int z = 0;

    //Itteration through the all the XMLs in the location to add the current items into their arrays
    for (int x = 0; x < NumFiles; x++)
    {
        String FullPath = FullPaths[x];

        XPathNavigator Root = new XPathDocument(FullPath).CreateNavigator();

        foreach (XPathNavigator Cycle in Root.Select(
                           String.Format(@"//TestCycle[@Number = '{0}']", 
                           SelectedTC))
        )
        {
            foreach (XPathNavigator Nav in Cycle.Select(@"Files/HashCode/@Code"))
            {
                HashCode[z] = Nav.Value;
                //listBox4.Items.Add(Nav.Value);
                z = z + 1;
            }
        }
    }
    return HashCode;
}

简单但不是特别优雅的方式:

private void Compare()
    {
        String[] ProjectOneFiles = ProjOneFiles();
        String[] ProjectTwoFiles = ProjTwoFiles();
        String[] ProjectOneHash = ProjOneHash();
        String[] ProjectTwoHash = ProjTwoHash();

        for (int x = 0; x < ProjectOneFiles.length || x < ProjectTwoFiles.length; ++x)
        {
            String Test1 = x < ProjectOneFiles.length ? ProjectOneFiles[x] : "";
            String Test2 = x < ProjectTwoFiles.length ? ProjectTwoFiles[x] : "";
            String Test3 = x < ProjectOneFiles.length ? ProjectOneHash[x] : "";
            String Test4 = x < ProjectTwoFiles.length ? ProjectTwoHash[x] : "";

            if (Test1.CompareTo(Test2) != 0)
            {
                listBox6.Items.Add(Test1);
                listBox6.Items.Add(Test2);
            }
            else if (Test3.CompareTo(Test4) == 0)
            {
                listBox7.Items.Add(Test1);
            }
            else
            {
                listBox8.Items.Add(Test1);
            }
        }
    }

要详细说明上面提到的Dictionary方法,您可以考虑使用以下方法:Dictionary hashDic = new Dictionary();

for(int i = 0; i < ProjectOneFiles.Length; i++)
{
    //Add to the dictionary using hashDic.Add(FILENAME_HERE, HASH_HERE).
}

for(int i = 0; i < ProjectTwoFiles.Length; i++)
{
    string projectOneValue;
    if(hashDic.TryGetValue(ProjectTwoFiles[i], out projectOneValue))
    {
        //If this code executes, you'll know that the file is in both projects.
        //The hash for the file in project one is in "projectOneValue."
        //The hash for the file in project two is in "ProjectTwoHash[i]".

        //You can remove this entry from the dictionary using
        //hashDic.Remove(FILE_NAME_HERE)
    }
    else
    {
        //If this code executes, then this file is only in ProjectTwo.
    }
}

//This loop will loop over all the files that are ONLY in ProjectOne.
foreach(KeyValuePair<string, string> kvp in hashDic)
{
    //kvp.Key is the filename.
    //kvp.Value is the hash.
    //For every pass of this loop you'll be looking at a different
    //file/hash that is ONLY in project one.
}

诚然,我最后跳过了一些内容,但是这对您有何作用?

我不确定您到底在哪里卡住,但似乎您只需要用手找出每个列表中哪些项目是唯一的,哪些项目不是唯一的。

在这种情况下,这应该有助于:

var onlyInListOne = ProjectOneFiles.Except(ProjectTwoFiles);
var onlyInListTwo = ProjectTwoFiles.Except(ProjectOneFiles);
var inBothLists = ProjectOneFiles.Intersect(ProjectTwoFiles);

我使用“ var”关键字保存类型,但是要从LINQ语句中吐出来的实际数据类型是IEnumerable。 如果需要将其作为列表,则只需在行尾调用.ToList(),如下所示:

var onlyInListOne = ProjectOneFiles.Except(ProjectTwoFiles).ToList();
var onlyInListTwo = ProjectTwoFiles.Except(ProjectOneFiles).ToList();
var inBothLists = ProjectOneFiles.Intersect(ProjectTwoFiles).ToList();

一般来说,虽然--ToList()并不是地球上最快的方法,所以尽管有时它是必需的,但是如果您真的不需要List对象,我会避免使用它。

.Except(...)仅将一个列表中的所有字符串排除在外,而排除另一个列表中的所有字符串。 .Intersect(...)仅查找两个列表中的文件。

如果还有其他特别想念的地方,请在评论中告诉我,我会帮忙的。

尝试这个。

private void Compare()
{
    String[] ProjectOneFiles = ProjOneFiles();
    String[] ProjectTwoFiles = ProjTwoFiles();
    String[] ProjectOneHash = ProjOneHash();
    String[] ProjectTwoHash = ProjTwoHash();

    //make project one the greater of the two always
    if (ProjectTwoFiles.Length > ProjectTwoFiles.Length)
    {
        Swap(ref ProjectOneFiles, ref ProjectTwoFiles);
        Swap(ref ProjectOneHash, ref ProjectTwoHash);
    }

    for (int x = 0; x < ProjectTwoFiles.length; x++)
    {
        String Test1 = ProjectOneFiles[x];
        String Test2 = ProjectTwoFiles[x];
        String Test3 = ProjectOneHash[x];
        String Test4 = ProjectTwoHash[x];

        if (Test1 != Test2)
        {
            listBox6.Items.Add(Test1);
            listBox6.Items.Add(Test2);
        }
        else if ((Test1 == Test2) && (Test3 == Test4))
        {
            listBox7.Items.Add(Test1);
        }
        else
        {
            listBox8.Items.Add(Test1);
        }
    }
    for (int x = ProjectTwoFiles.Length + 1; x < ProjectOneFiles.length; x++)
    {
        //add to some other list
    }
}

private static void Swap(ref string[] foo, ref string[] bar)
{
    string[] tmp = foo;
    foo = bar;
    bar = tmp;
}

诀窍是通过交换使ProjectOne成为更大的数组。 现在,所有操作都很容易,因为您始终可以预测更大的数组。

免责声明 :这只是解决您的问题。 根本没有优化。
可以从将DevelopSomalia()更改为DevelopCountry("Somalia")开始优化

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM