创建唯一字符串C#

时间:2017-09-29 15:11:38

标签: c# .net

我需要编写一个程序,从文本文件中读取名字和姓氏。然后,我需要最多4个名字的字符和4个姓氏的字符,并将它们组合成第三个字符串。问题是新字符串必须是唯一的。 例如

名字=詹姆斯 姓氏=杰克逊

新字符串将是JAMEJACK

名字=詹姆斯 姓氏=杰克

new string = JAMEJACK1 或新字符串= JAMSJACK

只要所有字符串都是唯一的,它的工作方式并不重要。

        LastName = input.Substring(12, 10);

        FirstName = input.Substring(21, 21);
        new string = LastName.Substring(0, 4) + FirstName.Substring(0, 4);

我知道这可能不是最好的方法,但我还是新手。

任何帮助或建议将不胜感激。 提前谢谢。

6 个答案:

答案 0 :(得分:1)

这段代码可以解决问题。我在其中添加了一些评论,并试图尽可能简单地解释它。

var uniqueList = new HashSet<string>();

for (int i = 0; i < 4; i++) //just for testing purposes
{
    string firstName = "James"; //first name
    string lastName = "Jackson"; //last name

    string shortFN = (firstName.Length >= 4) ? firstName.Substring(0, 4) : firstName; //check for name with 4 or less chars
    string shortLN = (lastName.Length >= 4) ? lastName.Substring(0, 4) : lastName; //with "true", it uses the whole name

    string newShortName = shortFN + shortLN; //adding up the words

    if (uniqueList.Contains(newShortName)) //find if its unique to the list of names
    {
        //not unique
        var repeatedNames = uniqueList.Count(x => x.Contains(newShortName)); //this will get how many names in the list are repeated
        newShortName += repeatedNames; //we add the number
        uniqueList.Add(newShortName); //now the name is unique, so we add it
    }
    else
    {
        uniqueList.Add(newShortName); //adding the new name to the list of names
    }
}

答案 1 :(得分:0)

如果不能与之前的条目进行比较,则无法确保唯一性。

我能想到的最简单的方法是将您输入的每个条目输入到列表中,然后在创建新条目时,将其与列表中的每个其他条目进行比较以获得唯一性,并在必要时重新生成。 p>

毫无疑问,有更好,更有效的方法可以做到这一点,但想想一个简单的答案在这里会更好。

这是一个伪代码示例:

List<string> CompareList = new List<string>();
        //...however you're gonna loop this

        string LastName = input.Substring(12, 10);

        string FirstName = input.Substring(21, 21);
        string generatedName = LastName.Substring(0, 4) +
                               FirstName.Substring(0, 4);
        bool nameIsUnique = true;

        foreach (var entry in CompareList)
        {
            if (entry == generatedName) nameIsUnique = false;
        }

        if (nameIsUnique) CompareList.Add(generatedName);
        else //Go back to generating a name, add a number on the end, etc
        //Go to next line in your text file, rinse, repeat.

答案 2 :(得分:0)

这样的事情对你有用吗?

    var names = new List<Name>
    {
        new Name { FirstName = "AAA", LastName = "BBB"  },
        new Name { FirstName = "AAA", LastName = "BBB"  },
        new Name { FirstName = "CCC", LastName = "DDD"  }
    };

    var trimmedNames = names.Select(x => new Name { FirstName = x.FirstName.Substring(0, 4), LastName = x.LastName.Substring(0, 4) });

    var grouped = trimmedNames.GroupBy(x => new { x.FirstName, x.LastName });
    var result = grouped.SelectMany(x => 
    {
        var uniqueNames = new List<string>();

        if (x.Count() > 1)
        {
            var index = 1;

            foreach (var singleName in x)
            {
                uniqueNames.Add($"{singleName.FirstName}{singleName.LastName}{index++}");
            }
        }
        else
        {
            uniqueNames.Add($"{x.Key.FirstName}{x.Key.LastName}");
        }

        return uniqueNames;
    }).ToList();

结果:

AAABBB1
AAABBB2
CCCDDD

甚至更简单:

    var result = grouped.SelectMany(x => 
    {
        var uniqueNames = new List<string>();

        var index = 1;

        foreach (var singleName in x)
        {
            uniqueNames.Add($"{singleName.FirstName}{singleName.LastName}{index++}");
        }

        return uniqueNames;
    });

但结果略有不同:

AAABBB1
AAABBB2
CCCDDD1

答案 3 :(得分:0)

Sam Marion在这里真的得到了赞誉,因为他是第一个提出建议的人,但这也是我的想法。

为什么不使用Dictionary<string, int>来存储所有组合名称,以及有多少名称。然后,一旦构建了Dictionary,就可以将数量增加一个重复数量。像这样:

Dictionary<string, int> usernameCollection = new Dictionary<string, int>();

foreach(string name in namesTextFile)
{
    string username = string.Concat(name.Split().Select(x => x.Length >= 4 ? x.Substring(0, 4) : x));

    if(usernameCollection.ContainsKey(username))
    {
        usernameCollection[username] = usernameCollection[username] + 1;
    }
    else
    {
        usernameCollection.Add(username, 1);
    }                   
}

我做了一个小提琴here来演示。

答案 4 :(得分:0)

我知道我参加派对有点晚了,但这是@ maccettura答案的一个版本。这不是采用直接子字符串,而是从名字和姓氏中组成随机子字符串,然后在仍然唯一的情况下添加计数。

public class Program
{
    // Take distinct set of random numbers in a given range
    public static List<int> GetDistinctRandomNumbers(int min, int max, int count)
    {
        // Must do error checks for if (min > max) etc...
        var rnd = new Random();
        var val = Enumerable.Range(min, max).OrderBy(x => rnd.Next());
        return val.Take(count).ToList();
    }

    // Get a substring of a string composed by extracting characters from given indices
    public static string GetStringByIndices(string str, List<int> indexes)
    {
        string result = string.Empty;
        foreach (var index in indexes)
            result += str[index];
        return result;
    }

    public static string CreateRandomString(string str1, string str2)
    {
        // Number of characters to extract from each string
        int len1 = (str1.Length < 4) ? str1.Length : 4;
        int len2 = (str2.Length < 4) ? str2.Length : 4;

        // Indices at which characters will be extracted from each string
        var str1Indexes = GetDistinctRandomNumbers(0, str1.Length, len1);
        var str2Indexes = GetDistinctRandomNumbers(0, str2.Length, len2);

        // Extracted strings
        var first = GetStringByIndices(str1, str1Indexes);
        var second = GetStringByIndices(str2, str2Indexes);

        // Potentially unique string
        return first + second;
    }

    public static void CreateUniqueList(string strToAdd, ref Dictionary<string,int> dict)
    {
        if (!dict.ContainsKey(strToAdd))
            dict.Add(strToAdd, 1);  // If not found in the dictionary, add it, with a count of 1
        else
        {
            int count;
            if (dict.TryGetValue(strToAdd, out count))
            {
                dict.Add(strToAdd + count.ToString(), count + 1);   // If found, add a new item where NewKey = ExistingKey + Count
                dict[strToAdd] += 1;    // Increment count of existing Key
            }
        }
    }

    public static void Main()
    {
        Dictionary<string, int> unique = new Dictionary<string, int>();

        for (int i = 0; i < 20; i++)
        {
            var str = CreateRandomString("Jennifer", "Lawrence");
            CreateUniqueList(str, ref unique);
        }

        Console.ReadLine();
    }
}

不可否认,这并没有给你任何特别的好处(我猜),写这个很有趣。

答案 5 :(得分:-1)

我喜欢GUID选项。你可以使用名字和姓氏的4个字符作为种子的一部分。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace randomseed
{
class Program
{
    static void Main(string[] args)
    {
        string first = "fir";
        string last = "LastName";
        string firstlast = first.Substring(0, first.Length > 4 ? 4 : first.Length)
            + last.Substring(0, last.Length > 4 ? 4 : last.Length);
        int seed = 0;
                    string uniqueString = firstlast + GenerateStringNameGuid(seed);
        string u2 = firstlast + GenerateStringNameGuid(seed);
        string u3 = firstlast + GenerateStringNameGuid(seed);

        Console.Write($"uniqueString = { uniqueString} \n");
        Console.Write($"uniqueString = { u2} \n");
        Console.Write($"uniqueString = { u3} \n");



    }

    public static string GenerateStringNameGuid(int seed)
    {
        var r = new Random(seed + Guid.NewGuid().GetHashCode());
        var guid = new byte[16];
        r.NextBytes(guid);

        return new Guid(guid).ToString();
    }
}

}

输出

uniqueString = firLast7e7d1ec5-a375-3384-7e39-89859fa55d6f
uniqueString = firLast047f91be-3f7c-e0aa-414e-ece64bf6833f
uniqueString = firLast00042b27-0afa-fd92-c127-95bd84235040