2009-02-26 67 views
6

Tôi phải thực hiện một hàm lấy chuỗi làm đầu vào và tìm ký tự không trùng lặp từ chuỗi này.Làm thế nào bạn có thể loại bỏ các ký tự trùng lặp trong một chuỗi?

Vì vậy, một ví dụ là nếu tôi vượt qua chuỗi str = "ĐHCĐ" nó sẽ trở lại "DHC" hoặc str2 = "KLKLHHMO" nó sẽ trở lại "KLHMO"

+1

Tiêu đề bị đặt tên sai - bạn muốn xóa các ký tự trùng lặp khỏi chuỗi. –

+0

Bạn có thể đăng những gì bạn đã thử cho đến nay không? – SquareCog

+0

Giải pháp LINQ nên thú vị. –

Trả lời

24

Một cách tiếp cận LINQ:

012.
public static string RemoveDuplicates(string input) 
{ 
    return new string(input.ToCharArray().Distinct().ToArray()); 
} 
6

Nó sẽ làm công việc

string removedupes(string s) 
{ 
    string newString = string.Empty; 
    List<char> found = new List<char>(); 
    foreach(char c in s) 
    { 
     if(found.Contains(c)) 
      continue; 

     newString+=c.ToString(); 
     found.Add(c); 
    } 
    return newString; 
} 

Tôi nên lưu ý điều này là không hiệu quả hình sự.

Tôi nghĩ rằng tôi đã mê sảng trong lần sửa đổi đầu tiên.

+1

Tôi đoán chính xác rằng bạn cố tình để lại sự thiếu hiệu quả như một bài tập cho người đọc, hoặc bạn có muốn gợi ý về việc làm công việc này nhanh hơn không? – SquareCog

+0

Thực tế bạn là chính xác, nếu đó là bài tập về nhà thì OP có thể lọc qua và tạo ra một thứ không khủng khiếp. Nó cũng phục vụ như là một đường cơ sở cho sự hiểu biết những gì đang xảy ra. Tuy nhiên, tôi không cần đề xuất về các cải tiến. –

6

Đối với chuỗi dài ký tự có kích thước byte (không phải cho ký tự rộng hoặc mã hóa khác), tôi sẽ sử dụng bảng tra cứu, một bit cho mỗi ký tự (32 byte cho bảng 256 bit). Lặp qua chuỗi của bạn, chỉ các ký tự đầu ra không có bit được bật, sau đó bật bit cho ký tự đó.

string removedupes(string s) 
{ 
    string t; 
    byte[] found = new byte[256]; 
    foreach(char c in s) 
    { 
     if(!found[c]) { 
      t.Append(c); 
      found[c]=1; 
     } 
    } 
    return t; 
} 

Tôi không tốt với C#, vì vậy tôi không biết đúng cách để sử dụng bitfield thay vì mảng byte.

Nếu bạn biết rằng các chuỗi của bạn sẽ rất ngắn, thì các cách tiếp cận khác sẽ cung cấp mức sử dụng và/hoặc tốc độ bộ nhớ tốt hơn.

+0

Tôi nghĩ rằng điều này sẽ nhanh hơn đáng kể so với cách tiếp cận của Quintin Robinson, nhưng sẽ sử dụng nhiều bộ nhớ hơn cho các chuỗi ngắn. – Sparr

+0

Nhưng bộ nhớ ít hơn đáng kể cho các chuỗi trung bình hoặc dài, nếu một mảng bit được sử dụng. – Sparr

+0

Trái tim của bạn ở đúng nơi, nhưng logic của bạn hơi lệch. Nó sẽ là nếu (tìm thấy [c]) {t + = c; tìm thấy [c] = 1;} Không cần khối khác. Mã hiện tại của bạn sẽ không thực hiện thủ thuật. – BFree

3

Nghe có vẻ như bài tập về nhà với tôi, vì vậy tôi sẽ mô tả ở mức cao.

  • Vòng qua chuỗi, kiểm tra mỗi nhân vật
  • Kiểm tra xem bạn đã nhìn thấy các nhân vật trước khi
    • nếu bạn có, loại bỏ nó khỏi chuỗi
    • nếu bạn chưa có, lưu ý rằng bây giờ bạn đã nhìn thấy rằng nhân vật
0

char * remove_duplicates (char * str) { char * str1, * str2;

if(!str) 
    return str; 

str1 = str2 = str; 

while(*str2)    
{ 
    if(strchr(str, *str2)<str2) 
    { 
     str2++; 
     continue; 
    } 

    *str1++ = *str2++;  
} 
*str1 = '\0'; 

return str; 

}

0
char* removeDups(const char* str) 
{ 
char* new_str = (char*)malloc(256*sizeof(char)); 
int i,j,current_pos = 0,len_of_new_str; 
new_str[0]='\0'; 

for(i=0;i<strlen(str);i++) 
{ 
len_of_new_str = strlen(new_str); 
for(j=0;j<len_of_new_str && new_str[j]!=str[i];j++) 
    ; 
    if(j==len_of_new_str) 
    { 
    new_str[len_of_new_str] = str[i]; 
    new_str[len_of_new_str+1] = '\0'; 
    } 
} 
    return new_str; 
} 

Hope this helps

+1

Đây là C#. Không C. –

1

câu trả lời của tôi bằng ngôn ngữ java.
Đăng ở đây để bạn có thể nhận được ý tưởng ngay cả khi nó bằng ngôn ngữ Java. Thuật toán sẽ vẫn giữ nguyên.

public String removeDup(String s) 
    { 
    if(s==null) return null; 
    int l = s.length(); 
    //if length is less than 2 return string 
    if(l<2)return s; 
    char arr[] = s.toCharArray(); 

    for(int i=0;i<l;i++) 
    { 
     int j =i+1; //index to check with ith index 
     int t = i+1; //index of first repetative char. 

     while(j<l) 
     { 
     if(arr[j]==arr[i]) 
     { 
      j++; 

     } 
     else 
     { 
      arr[t]=arr[j]; 
      t++; 
      j++; 
     } 

     } 
     l=t; 
    } 

    return new String(arr,0,l); 
    } 
-1

một phiên bản sửa đổi của câu trả lời đầu tiên trong C# là dưới

chuỗi oldstr = "abacab";

chuỗi newstr = chuỗi mới (oldstr.Distinct().ToArray());

+0

Tôi không biết tại sao nó lại bị bỏ phiếu? – Krish

1

// đây là trong C#, xác nhận bỏ qua cho ngắn gọn giải pháp // nguyên thủy để loại bỏ ký tự trùng lặp từ một chuỗi cho trước

public static char[] RemoveDup(string s) 
    { 
     char[] c = new char[s.Length]; 
     int unique = 0; 
     c[unique] = s[0]; // Assume: First char is trivial 
     for (int i = 1; i < s.Length; i++) 
     { 
      if (s[i-1] != s[i] 
     c[++unique] = s[i]; 
     } 
     return c; 
    } 
0
String str="AABBCANCDE"; 
String newStr=""; 
for(int i=0; i<str.length(); i++) 
{ 
if(!newStr.contains(str.charAt(i)+"")) 
newStr= newStr+str.charAt(i); 
} 
System.out.println(newStr); 
3
void removeDuplicate() 
    { 
     string value1 = RemoveDuplicateChars("Devarajan"); 
    } 

    static string RemoveDuplicateChars(string key) 
    { 

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

Bạn không cần các dòng sau đây 1) string result = ""; và 2) kết quả + = giá trị; Bảng trở về sẽ đủ. – rajibdotnet

1

bạn có thể sử dụng HashSet:

static void Main() 
    { 
     string textWithDuplicates = "aaabbcccggg"; 

     Console.WriteLine(textWithDuplicates.Count()); 
     var letters = new HashSet<char>(textWithDuplicates); 
     Console.WriteLine(letters.Count()); 

     foreach (char c in letters) Console.Write(c); 
    } 
0

// Xóa cả hai bản sao trên thấp hơn

public static string RemoveDuplicates(string key) 
    { 
     string Result = string.Empty; 
     foreach (char a in key) 
     { 
      if (Result.Contains(a.ToString().ToUpper()) || Result.Contains(a.ToString().ToLower())) 
       continue; 
      Result += a.ToString(); 
     } 
     return Result; 
    } 
-1
var input1 = Console.ReadLine().ToLower().ToCharArray(); 
var input2 = input1; 
var WithoutDuplicate = input1.Union(input2); 
+0

Mặc dù mã này có thể giải quyết được vấn đề, một câu trả lời hay phải luôn luôn chứa một lời giải thích. – BDL

+0

Đồng ý. Tôi vừa đăng một cách khác để đạt được kết quả. Ofcourse "khác biệt()" từ cùng một thư viện địa chỉ nguyên nhân. – user2481149

0
class Program 
    { 
     static void Main(string[] args) 
     { 
      bool[] doesExists = new bool[256]; 
      String st = Console.ReadLine(); 
      StringBuilder sb = new StringBuilder(); 
      foreach (char ch in st) 
      { 
       if (!doesExists[ch]) 
       { 
        sb.Append(ch); 
        doesExists[ch] = true; 
       } 
      } 
      Console.WriteLine(sb.ToString()); 
     } 
    } 
0
Console.WriteLine("Enter String"); 

string str = Console.ReadLine(); 

string result = ""; 
result += str[0]; // first character of string 

for (int i = 1; i < str.Length; i++) 
{ 
    if (str[i - 1] != str[i]) 
     result += str[i]; 
} 

Console.WriteLine(result); 
0

Tôi thích Quintin Robinson câu trả lời, chỉ cần có một số cải tiến như loại bỏ List, bởi vì nó không được necessarry trong trường hợp này. Ngoài ra, theo ý kiến ​​của tôi, chữ hoa chữ thường ("K") và chữ thường char ("k") là giống nhau, vì vậy chúng nên được tính là một.

Vì vậy, đây là cách tôi sẽ làm điều đó:

private static string RemoveDuplicates(string textEntered) 
    { 

     string newString = string.Empty; 

     foreach (var c in textEntered) 
     { 
      if (newString.Contains(char.ToLower(c)) || newString.Contains(char.ToUpper(c))) 
      { 
       continue; 
      } 
      newString += c.ToString(); 
     } 
     return newString; 
    } 
+0

Đây không phải là cải tiến. 'Contains' phải quét tất cả các ký tự. Thao tác chuỗi tạo các chuỗi * mới * tạm thời. Điều này dẫn đến n^2 lần quét và khá * rất nhiều * chuỗi tạm thời. Câu trả lời được bình chọn hàng đầu với LINQ và Distinct thực sự nhanh hơn (chỉ quét một lần) và tiêu thụ ít bộ nhớ hơn –

0

Không chắc thế nào tối ưu nó là:

public static string RemoveDuplicates(string input) 
{ 
    var output = string.Join("", input.ToHashSet()); 
    return output; 
} 
0

Dưới đây là đoạn code để loại bỏ ký tự trùng lặp từ một chuỗi

 var input = "SaaSingeshe"; 
     var filteredString = new StringBuilder(); 
     foreach(char c in input) 
     { 
      if(filteredString.ToString().IndexOf(c)==-1) 
      { 
       filteredString.Append(c); 
      } 
     } 
     Console.WriteLine(filteredString); 
     Console.ReadKey(); 
Các vấn đề liên quan