确定字符串是否包含所有唯一字符

时间:2012-10-01 04:05:07

标签: c# algorithm

我正在处理一个算法问题集,它提出了以下问题:

“确定字符串是否包含所有唯一字符。假设您只能使用数组”。

我有一个可行的解决方案,但我想看看在时间复杂度方面是否有更好的优化。我不想使用LINQ。感谢您提供的任何帮助!

static void Main(string[] args)
{
    FindDupes("crocodile");
}

static string FindDupes(string text)
{
    if (text.Length == 0 || text.Length > 256)
    {
        Console.WriteLine("String is either empty or too long");
    }

    char[] str = new char[text.Length];
    char[] output = new char[text.Length];

    int strLength = 0;
    int outputLength = 0;

    foreach (char value in text)
    {
        bool dupe = false;
        for (int i = 0; i < strLength; i++)
        {
            if (value == str[i])
            {
                dupe = true;
                break;
            }
        }
        if (!dupe)
        {
            str[strLength] = value;
            strLength++;

            output[outputLength] = value;
            outputLength++;
        }
    }
    return new string(output, 0, outputLength);
}

7 个答案:

答案 0 :(得分:8)

如果你关心时间复杂性,你可以将字符映射到int值,然后有一个bool值数组,记住你以前是否看过一个特定的字符值。

类似...... [未经测试]

bool[] array = new bool[256]; // or larger for Unicode

foreach (char value in text)
  if (array[(int)value])
    return false;
  else
    array[(int)value] = true;

return true; 

答案 1 :(得分:3)

试试这个,

    string RemoveDuplicateChars(string key)
    {
        string table = string.Empty;
        string result = string.Empty;
        foreach (char value in key)
        {
            if (table.IndexOf(value) == -1)
            {
                table += value;
                result += value;
            }
        }
        return result;
    }

使用

Console.WriteLine(RemoveDuplicateChars("hello"));
Console.WriteLine(RemoveDuplicateChars("helo"));
Console.WriteLine(RemoveDuplicateChars("Crocodile"));

输出

helo
helo
Crocdile

答案 2 :(得分:1)

public boolean ifUnique(String toCheck){
    String str="";
    for(int i=0;i<toCheck.length();i++)
    {
         if(str.contains(""+toCheck.charAt(i)))
             return false;
         str+=toCheck.charAt(i);
    }
    return true;
}

编辑:

您也可以考虑省略toCheck为空字符串的边界情况。

答案 3 :(得分:0)

以下代码有效:

 static void Main(string[] args)
    {
        isUniqueChart("text");
        Console.ReadKey();

    }

    static Boolean isUniqueChart(string text)
    {
        if (text.Length == 0 || text.Length > 256)
        {
            Console.WriteLine(" The text is empty or too larg");
            return false;
        }
        Boolean[] char_set = new Boolean[256];
        for (int i = 0; i < text.Length; i++)
        {
            int val = text[i];//already found this char in the string
            if (char_set[val])
            {
                Console.WriteLine(" The text is not unique");
                return false;
            }
            char_set[val] = true;
        }
        Console.WriteLine(" The text is unique");
        return true;
    }

答案 4 :(得分:0)

如果字符串只有小写字母(a-z)或只有大写字母(A-Z),你可以使用非常优化的O(1)解决方案。还有O(1)空格。

c ++代码:

bool checkUnique(string s){
    if(s.size() >26)
        return false;
    int unique=0;
    for (int i = 0; i < s.size(); ++i) {
        int j= s[i]-'a';
        if(unique & (1<<j)>0)
            return false;
       unique=unique|(1<<j);
   }
   return true;
}

答案 5 :(得分:0)

public static bool CheckUnique(string str)
{
    int accumulator = 0;
    foreach (int asciiCode in str)
    {
        int shiftedBit = 1 << (asciiCode - ' ');
        if ((accumulator & shiftedBit) > 0)
            return false;
        accumulator |= shiftedBit;
    }
    return true;
}

答案 6 :(得分:0)

在整个Unicode范围内删除重复项

并非所有字符都可以由单个C#char表示。如果您需要考虑combining characters和扩展unicode字符,则需要:


删除重复字符的代码:

我们跟踪熵,存储归一化的字符(每个字符是一个字符串,因为许多字符需要超过1个C#字符)。如果尚未将字符(规范化)存储在熵中,则将字符(以指定形式)附加到输出中。

public static class StringExtension
{
    public static string RemoveDuplicateChars(this string text)
    {
        var output = new StringBuilder();
        var entropy = new HashSet<string>();
        var iterator = StringInfo.GetTextElementEnumerator(text);

        while (iterator.MoveNext())
        {
            var character = iterator.GetTextElement();
            if (entropy.Add(character.Normalize()))
            {
                output.Append(character);
            }
        }

        return output.ToString();
    }
}

单元测试:

让我们测试一个字符串,其中包含字母A的变体,包括Angstrom符号。埃符号具有Unicode代码点u212B,但也可以将其与变音符号u030A一起构造为字母A。两者都代表相同的字符。

 // ÅÅAaA 
 var input = "\u212BA\u030AAaA";

 // ÅAa
 var output = input.RemoveDuplicateChars();

进一步的扩展可能允许选择器功能,该功能确定如何规范字符。例如,选择器(x) => x.ToUpperInvariant().Normalize()将允许不区分大小写的重复项删除。

相关问题