某年某月某日的某个时候,去参加一次某个公司的C#技术面试。问题只是没有得到大小写是否要区分。
code如下,有人说这样写不对,我编译执行,觉得没问题。请大家帮忙看看:
犹豫这里格式很难把握,大家将就看。我只是从VS里面直接贴过来,看着太难看,所以折行显示了一下。应该不影响编译执行。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DeDup_Reverse
{
class Program
{
public static void DeDupAndReverse(string str)
{ char blank = ' ';
StringBuilder sbDeDup = new StringBuilder();
StringBuilder sbReverse = new StringBuilder();
for (int index = 0; index < str.Length; index++)
{
if ((!((sbDeDup.ToString()).Contains(str[index])) || (str[index].Equals(blank)))) {
sbDeDup.Append(str[index]);
}
else
{
continue;
}
}
for (int index = sbDeDup.Length -1; index >= 0; index--) {
sbReverse = sbReverse.Append(sbDeDup[index]);
}
for (int index = 0; index < sbReverse.Length; index++) {
System.Console.Write(sbReverse[index]);
}
}
public static void Main(string[] args)
{
string str = "Hello World";
DeDupAndReverse(str);
Console.ReadLine();
}
}
}
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 namespace DeDup_Reverse 6 { 7 class Program 8 { 9 public static void DeDupAndReverse(string str) 10 { 11 char blank = ' '; 12 StringBuilder sbDeDup = new StringBuilder(); 13 StringBuilder sbReverse = new StringBuilder(); 14 for (int index = 0; index < str.Length; index++) 15 { 16 if ((!((sbDeDup.ToString()).Contains(str[index])) || (str[index].Equals(blank)))) 17 { 18 sbDeDup.Append(str[index]); 19 } 20 else 21 { 22 continue; 23 } 24 } 25 for (int index = sbDeDup.Length - 1; index >= 0; index--) 26 { 27 sbReverse = sbReverse.Append(sbDeDup[index]); 28 } 29 for (int index = 0; index < sbReverse.Length; index++) 30 { 31 System.Console.Write(sbReverse[index]); 32 } 33 } 34 public static void Main(string[] args) 35 { 36 string str = "Hello World"; 37 DeDupAndReverse(str); 38 Console.ReadLine(); 39 } 40 } 41 }
我说下我意见啊,说的不好不要介意
首先 void DeDupAndReverse(string str)你的这个函数不应该是 void 类型,应该是string类型,返回的是你处理过的字符串,这样通用性才高,而你呢,在这个方法里面还输出到了控制台,也就是说,你写的这个方法只有这个代码可以用,没有一点通用性。
其次,你用了 StringBuilder 这个类,说明你知道他比 string 的效率高,但是 StringBuilder 的效率像你这样用是不高的,你需要告诉 StringBuilder 初始长度的大小,这样他的效率才是最高的。
下面是我改的代码,逻辑方面用的是你写的,我没变过,但是代码的通用性和效率就高多了!
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DeDup_Reverse { public static class StringExtension { public static string DeDupAndReverse(this string str) { char blank = ' '; StringBuilder sbDeDup = new StringBuilder(str.Length); for (int index = 0; index < str.Length; index++) { if ((!((sbDeDup.ToString()).Contains(str[index])) || (str[index].Equals(blank)))) { sbDeDup.Append(str[index]); } else { continue; } } StringBuilder sbReverse = new StringBuilder(sbDeDup.Length); for (int index = sbDeDup.Length - 1; index >= 0; index--) { sbReverse = sbReverse.Append(sbDeDup[index]); } return sbReverse.ToString(); } } class Program { public static void Main(string[] args) { string str = "Hello World"; Console.WriteLine(str.DeDupAndReverse()); Console.ReadLine(); } } }
哈哈,我也忽略了StringBuilder初始容量了。的确这是一个关键点,特别是字符串较长的时候。否则每次扩容*2都很耗时间的。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DeDupAndReverse { class Program { public static string ProcessString(string input) { StringBuilder sb = new StringBuilder(input.Length); HashSet<char> hashSet=new HashSet<char>(); foreach (var c in input) { if (c == ' ') { sb.Append(c); } if (hashSet.Contains(c)==false) { sb.Append(c); hashSet.Add(c); } } return sb.ToString(); } public static string DeDeup_Reverse(string toBeProcessed) { string toBeReversed = ProcessString(toBeProcessed); StringBuilder sbReversed = new StringBuilder(toBeReversed.Length); for (int i = toBeReversed.Length - 1; i >= 0; i--) { sbReversed.Append(toBeReversed[i]); } return sbReversed.ToString(); } public static void Main(string[] args) { string str = "Hello World, hello world"; Console.WriteLine(DeDeup_Reverse(str)); Console.ReadLine(); } } }
我更新了代码,大家再看看。
ProcessString 确实code简洁很多。非常感谢。吸收了下意见。看看这次还有什么问题么?
@simonzhang: 其实你的DeDeup_Reverse() ProcessString()这两个方法应该都是在Main()里面调用的,你在DeDeup_Reverse()调用rocessString()就说明:
给你一个字符串让你把他反转了你还要写一个方法
@博客¥: 理解。不过当时面试的哥们说了,只希望调用一次。所以我这么写的。不过写在哪里,只是看需求了。实现上最好帮忙看看有没有继续可以改进的地方。我这次也就是学习了。不过非常感谢了。
1 static string ProcessString(string input) 2 { 3 StringBuilder sb = new StringBuilder(); 4 HashSet<char> hashSet=new HashSet<char>(); 5 foreach (var c in input) 6 { 7 if (c == ' ') 8 { 9 sb.Append(c); 10 } 11 if (hashSet.Contains(c)==false) 12 { 13 sb.Append(c); 14 hashSet.Add(c); 15 } 16 } 17 return sb.ToString(); 18 }
个人简洁的解法。
主要觉得楼主不应该直接在里面打印结果,而应该作为返回值。
嗯,HASH表匹配重复是比较块,我本来的想法是用链表.但链表长了之后,查找性能会变差,还是hash表比较块.
var resultStr= string.Join("", "abcdefgabcddddd".ToArray().Distinct());
忘了处理空值;
public class CustomComparer : IEqualityComparer<char> { public bool Equals(char x, char y) { if (x == ' ' || y == ' ') { return false; } return x == y; } public int GetHashCode(char obj) { return 0; } }
写个自定义比较器就行。
var s = string.Join("","sss bbb ccc".ToArray().Distinct(new CustomComparer()));//s="a b c"
你这个使用微软封装的Distinct,请用原始的代码写嘛。
@wongdavid: 原始的一楼已经写了。换种思路而已。