删除字符串中的重复项

时间:2011-08-07 16:14:15

标签: c# .net

我正在准备面试技术测试,我遇到了这个问题:

在不使用缓冲区的情况下删除字符串中的所有重复项,允许使用1或2个附加变量。

我想知道在做以下操作时,我使用的是缓冲区吗?感谢。

static void Main(string[] args)
{
    string temp = "amanisaman";
    temp = noDups(temp);
    MessageBox.Show(temp);
}

public string noDups(string word)
{
    string table = "";

    foreach (var character in word)
    {
        if (table.IndexOf(character) == -1)  
        {
            table += character; // would this count as a buffer storage?
        }
    }
    return table;
}

8 个答案:

答案 0 :(得分:3)

使用LINQ;

这假设您的临时字符串,并且您想要删除字符

string originalString = "amanisaman";
string newString = string.Join(" ", originalString.ToCharArray().Distinct());

这假定您要删除重复的单词。

string originalString = "this is my test string here, this test";
string newString = string.Join(" ", originalString).Split(new Char[] {' '}).Distinct());

答案 1 :(得分:3)

这是因为如果字符串中存在相同的char,则索引永远相同。 试试这个:

 static string noDups(string word)
        {
            string table = "";
            int pos = 0;
            foreach (var character in word.ToCharArray())
            {
                pos = table.IndexOf(character, Math.Abs(pos));
                if (pos == -1)
                {
                    table += character;
                }


            } 
            return table;

        }

我认为.IndexOf方法对此并不好。 您可以使用.Contains方法或LINQ。

使用LINQ:

 string input = "abahehe";
 string output = new String(input.ToCharArray().Distinct().ToArray());

答案 2 :(得分:2)

您发布的代码中存在许多错误(尝试编译它!),但以下方法通过为String类创建扩展方法来实现:

    static class Program
{
    static void Main(string[] args)
    {
        String temp = ("amanisaman");
        Console.WriteLine(temp.RemoveDupes());
        Console.ReadLine();
    }
    static String RemoveDupes(this String x)
    {
        return String.Join("", x.Distinct());
    }
}

答案 3 :(得分:1)

C#中的字符串是不可变的。因此,你必须以某种方式分配另一个内存位置,这是一个缓冲区,除非你要“不安全”。

这个问题实际上可能并不像正确答案那样寻找代码答案,在C#中,除非你“不安全”,否则这是不可能的。

答案 4 :(得分:0)

  

[...]不使用缓冲区,允许使用1或2个附加变量。

它们可能意味着你的解决方案应该使用恒定的内存量,无论你输入什么输入,而不是使用与输入字符串长度成比例增长的内存量。换句话说,您的解决方案应该具有O(1)而不是O(n)的内存要求。

从这个角度来看,我会说你的table算作“缓冲区”。虽然其最大容量由(Unicode)字母表中的字母数决定,但您的table很可能包含与输入字符串相同数量的字符 - 即,如果字符中没有重复的字符输入。

说到显示的具体方法noDups,因为你只填充table但似乎从来没有用过任何东西,你为什么不摆脱它呢?然后你的问题就会消失。

答案 5 :(得分:0)

O(n)解决方案:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

 void removeDuplicates(char *);

 void removeDuplicates(char *inp)
{
        int i=0, j=0, FLAG=0, repeat=0;

    while(inp[i]!='\0')
    {
            if(FLAG==1)
            {
                    inp[i-repeat]=inp[i];
            }
            if(j==(j | 1<<(inp[i]-'\0')))
            {
                    repeat++;
                    FLAG=1;
            }
                    j= j | 1<<(inp[i]-'\0');
                    i++;
    }

    inp[i-repeat]='\0';
}

 int main()
{
    char inp[100] = "aaAABCCDdefgccc";
    //char inp[100] = "ccccc";
    //char inp[100] = "\0";
    //char *inp = (char *)malloc(sizeof(char)*100);

    printf (" INPUT STRING : %s\n", inp);

    removeDuplicates(inp);

    printf (" OUTPUT STRING : %s:\n", inp);
    return 1;
}

答案 6 :(得分:-1)

是表被计为缓冲区。

我只想提一下字符串是不可变的,任何删除(或添加)都会导致创建新的字符串,也可以将其视为缓冲区。

为了减少额外的内存,我会执行以下操作:

string s = "ababagalamaga";
var h = new HashSet<char>(s);
var b = new StringBuilder();
foreach (char ch in h) {
    b.Append(ch);
}
Console.WriteLine(b);

答案 7 :(得分:-2)

“不使用缓冲区”是一个非常糟糕的要求。这是什么意思?新字符串是缓冲区吗?根据对此要求的解释,分配范围从C#中非常容易到不可能。