我正在准备面试技术测试,我遇到了这个问题:
在不使用缓冲区的情况下删除字符串中的所有重复项,允许使用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;
}
答案 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#中非常容易到不可能。