C# 确定字符串是否具有所有唯一字符

C# 确定字符串是否具有所有唯一字符,c#,algorithm,C#,Algorithm,我正在研究一个算法问题集,它提出了以下问题: “确定字符串是否具有所有唯一字符。假设您只能使用数组” 我有一个可行的解决方案,但我想看看是否有更好的时间复杂性方面的优化。我不想使用LINQ。感谢您提供的任何帮助 static void Main(string[] args) { FindDupes("crocodile"); } static string FindDupes(string text) { if (text.Length == 0 || text.Length

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

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

我有一个可行的解决方案,但我想看看是否有更好的时间复杂性方面的优化。我不想使用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);
}
static void Main(字符串[]args)
{
FindDupes(“鳄鱼”);
}
静态字符串FindDupes(字符串文本)
{
如果(text.Length==0 | | text.Length>256)
{
WriteLine(“字符串为空或太长”);
}
char[]str=新字符[text.Length];
char[]输出=新字符[text.Length];
int strLength=0;
int outputLength=0;
foreach(文本中的字符值)
{
bool dupe=false;
对于(int i=0;i
试试这个

    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;
    }
用法

输出

helo
helo
Crocdile

如果您只关心时间复杂度,那么可以将字符映射为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; 
public boolean ifUnique(字符串检查){
字符串str=“”;

对于(int i=0;i而言,以下代码有效:

 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;
    }
static void Main(字符串[]args)
{
isUniqueChart(“文本”);
Console.ReadKey();
}
静态布尔值isUniqueChart(字符串文本)
{
如果(text.Length==0 | | text.Length>256)
{
Console.WriteLine(“文本为空或太大”);
返回false;
}
布尔[]字符集=新布尔[256];
for(int i=0;i
如果字符串只有小写字母(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;
}
bool checkUnique(字符串s){
如果(s.尺寸()>26)
返回false;
int unique=0;
对于(int i=0;ipublicstaticboolcheckunique)(stringstr)
{
int累加器=0;
foreach(str中的int ASCICODE)
{
int-shiftedBit=1(0)
返回false;
累加器|=移位位;
}
返回true;
}
删除整个Unicode范围内的重复项 并非所有字符都可以用单个C#
字符表示。如果需要考虑扩展字符,则需要:

  • 使用
  • 人物
  • 在规范化字符串中查找重复项

删除重复字符的代码:

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

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();
    }
}


进一步的扩展可能允许使用选择器函数来确定如何规范化字符
将允许不区分大小写的重复删除。

这应该是在开销上的,因为你做了嵌套循环-遍历字符串的长度-而不是使用更简单的IndexOf函数。提示:在编码时,试着把事情想象成
抽象的
。如果我要求你写一个函数来统计每个p的年龄在这个线程中,您将如何调用该方法?
SumAges(int[]ages)
或-从目的中提取功能,并将其称为
Sum(int[]numbers)
。或者反之亦然。您是否会仔细考虑对字符串执行嵌套循环操作以检查字符串中是否有字符,而不是查找内置的BCL字符串方法?@DaveZych-嗨,Dave,我不知道codereview.stackexchange.com。在SO与CR上发布问题的协议是什么?此算法在扩展unicode和d上失败iacritics。你能建议两个空白字符串的用途吗?我觉得这两个表或结果中的任何一个都足够了。@SteveWellens为什么它在鳄鱼上失败了?它有重复的字母
o
对吗?PS“确定一个字符串是否有所有唯一的字符”表示布尔结果,而不是唯一字符字符串或删除重复字符的字符串。这是OP要求的最佳答案。您可以尽快找到重复并中断,如果符号已出现,则使用简单标志的静态映射是您可以执行的最快检查。编辑:@Ian即使…更改您的解决方案是,只将不重复的字符复制到新字符串中。使用显式算法仍然是最好的。而不是一些花哨的单行线。PS:if(array[(int)char)中键入错误-缺少括号
]
。上面的代码有几个语法错误,无效的表达式术语
char
应该是
value
这假设字符限制为255个。超出此范围的任何字符都会导致错误,例如Ā。为什么不使用字典呢?
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;
}
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;
}
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();
    }
}
 // ÅÅAaA 
 var input = "\u212BA\u030AAaA";

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