求一高效算法! --实在搞不定了

ChargeForward 2011-04-16 01:28:10
情况说明:
50000个字符串
字符串是有特点的, 形如 "1,3,5,54,68,998,52,34,65" 只有数字和英文逗号
需求说明:
从这50000个字符串中提取出其中的数字,并去重(distinct),时间要求:普通PC机(酷睿双核2.5GHZ,2G内存)50ms以内,如果能进30ms,那就更好了
我的代码如下

class Program
{
static void Main(string[] args)
{
while (true)
{
Stopwatch timer = new Stopwatch();
timer.Reset();
HashSet<string> ht = new HashSet<string>();
timer.Start();
for (int i = 0; i <= 50000; i++)
{
string apps = "112,2,3,4,5,6,7,8,9,10,112,12,13,14,15,16,17,18,19,20,";

char[] appCharArr = apps.ToCharArray();
int length = appCharArr.Length;
int startIndex = 0;
char[] tempcharArr = new char[] { '\0', '\0', '\0', '\0' };
#region
for (int j = 0; j < length; j++)
{
char c = appCharArr[j];
if (c == ',')
{
string s = new string(tempcharArr);
if (!ht.Contains(s))
{
ht.Add(s);
}
startIndex = 0;
tempcharArr = new char[] { '\0', '\0', '\0', '\0' };
}
else
{
tempcharArr[startIndex] = c;
startIndex++;
}
}
#endregion
}

timer.Stop();
int count = ht.Count;
Console.WriteLine(timer.Elapsed.ToString());
Console.ReadLine();
}
}
}

我的这段程序顶多只能跑到 155ms, 求坛子里的各路大神帮帮忙,小弟感激涕零!
...全文
1654 170 打赏 收藏 转发到动态 举报
写回复
用AI写文章
170 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2013-03-08
  • 打赏
  • 举报
回复
要求太简单了,可惜我来晚了
gengchenhui 2011-04-18
  • 打赏
  • 举报
回复
思维很发散,很强大。。。
showjim 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 146 楼 chargeforward 的回复:]
引用 105 楼 sbwwkmyd 的回复:

引用 102 楼 chargeforward 的回复:
在apps字符串很小的时候 你的程序快 当apps字符数大于30之后,你这个性能就开始下降了 54的程序开始超越

应该说在逗号的数量超过300的时候,扫描字符串的时候只做标识,扫完字符串再循环求结果。
54个字符不至于吧,54个逗号也应该不会

我的意思是说 54楼的程序
[/Quote]
54楼的程序应该说是最优算法了,可惜建了个类,很多开销都花在函数调用上了
showjim 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 146 楼 chargeforward 的回复:]
引用 105 楼 sbwwkmyd 的回复:

引用 102 楼 chargeforward 的回复:
在apps字符串很小的时候 你的程序快 当apps字符数大于30之后,你这个性能就开始下降了 54的程序开始超越

应该说在逗号的数量超过300的时候,扫描字符串的时候只做标识,扫完字符串再循环求结果。
54个字符不至于吧,54个逗号也应该不会

我的意思是说 54楼的程序
[/Quote]
开始一直搞错题意了,做了很多无用功,做错了的程序应该不会有比54楼快的时候。
但是你说有时候还会快,很意外啊。
zzxap 2011-04-18
  • 打赏
  • 举报
回复
static void Main(string[] args)
{
Stopwatch timer = new Stopwatch();
timer.Reset();

HashSet<int> big = new HashSet<int>();
bool[] small = new bool[100];

timer.Start();
string apps = "112,2,3,4,5,6,7,8,9,10,112,12,13,14,15,16,17,18,19,20,";

int number = 0;
for (int i = 0; i <= 500000; i++)
{


for (int j = 0; j < apps.Length; j++)
{
char c = apps[j];

if (c == ',')
{
if (number < 100)
{
small[number] = true;
}
else
{
big.Add(number);
}

number = 0;
}
else
{
number = number * 10 + (int) (c - '0');
}
}
}

timer.Stop();

for (int i = 0; i < small.Length; i++)
{
if (small[i])
{
Console.WriteLine(i);
}
}

foreach (var i in big)
{
Console.WriteLine(i);
}

Console.WriteLine("{0} ms", timer.Elapsed.TotalMilliseconds / 10);
}
}
ChargeForward 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 108 楼 beblong 的回复:]

我用JAVA代码实现了一遍,速度上最快可以进20ms以内,试验用数据量为,10个数字一组,逗号分隔,为一串,串的数量为50000,应该满足了。
因为JAVA虚拟机的执行效率问题,每次的时间会有很大的浮动,最快的时间不一定总会出现,改用C#实现的话,或许会好点,,速度上也会有提升。
虽然语言不一样,但是算法是通用的,先上代码(乱了点啊),有同时懂这2门语言的,麻烦翻译下试试
Java cod……
[/Quote]
最后的几条很经典, 54楼那个程序除了没有使用并发,其他都注意到了
ChargeForward 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 106 楼 bai_shou 的回复:]

都用上C#了,还有什么效率可言? 这不是脱了裤子讲文雅吗?
要效率,你写个c/c++的dll,然后c#来调。
[/Quote]
整体项目是.net项目,只是某个业务点上需要搞性能, 如果用C++实现算法, C#调用COM组件的性能代价会比较高吧
ChargeForward 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 105 楼 sbwwkmyd 的回复:]

引用 102 楼 chargeforward 的回复:
在apps字符串很小的时候 你的程序快 当apps字符数大于30之后,你这个性能就开始下降了 54的程序开始超越

应该说在逗号的数量超过300的时候,扫描字符串的时候只做标识,扫完字符串再循环求结果。
54个字符不至于吧,54个逗号也应该不会
[/Quote]
我的意思是说 54楼的程序
焙焙龙 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 164 楼 sbwwkmyd 的回复:]

引用 163 楼 beblong 的回复:
Split,完全鄙视~~偷懒的做法

我觉得常规情况下,我会用Split配合HashSet简单方便,配合我自己的库循环中间就一行代码
C# code
foreach(string apps in value) apps.Split(',').toHash(hash)
[/Quote]

现在是非常规情况下,用split分隔,比较耗时,你写代码是简单了,机器跑起来麻烦了
a174740342 2011-04-18
  • 打赏
  • 举报
回复
《编程珠玑第二版》
http://wenku.baidu.com/view/a1b61af69e314332396893c2.html
推荐这本书,里面有54楼的思路.
a174740342 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 164 楼 sbwwkmyd 的回复:]
引用 163 楼 beblong 的回复:
Split,完全鄙视~~偷懒的做法

我觉得常规情况下,我会用Split配合HashSet简单方便,配合我自己的库循环中间就一行代码

C# code
foreach(string apps in value) apps.Split(',').toHash(hash)
[/Quote]
高手
ChargeForward 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 164 楼 sbwwkmyd 的回复:]

引用 163 楼 beblong 的回复:
Split,完全鄙视~~偷懒的做法

我觉得常规情况下,我会用Split配合HashSet简单方便,配合我自己的库循环中间就一行代码
C# code
foreach(string apps in value) apps.Split(',').toHash(hash)
[/Quote]
哈哈 学习了
showjim 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 163 楼 beblong 的回复:]
Split,完全鄙视~~偷懒的做法
[/Quote]
我觉得常规情况下,我会用Split配合HashSet简单方便,配合我自己的库循环中间就一行代码
foreach(string apps in value) apps.Split(',').toHash(hash)
焙焙龙 2011-04-18
  • 打赏
  • 举报
回复
Split,完全鄙视~~偷懒的做法
品风无声 2011-04-18
  • 打赏
  • 举报
回复
用一点空间来换不知道可不可以,
int i = -1;
bool p[10000] = {false}; //由于你产生的数字不高于4位
while(i++ < s.length)
{
int t = 0;
while(s[i] >= '0' && s[i] <= '9')
{
t = t*10 + s[i] - '0';
p[t] = true;
i++;
}
}
for(int i =0;i<10000;i++)
if(p[i]) Console.WriteLine(i); //i是你要求的数组的数!
ChargeForward 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 159 楼 wuxing2006 的回复:]

你要的是提分割数字而已, Split下就行,不用自己去分析字符串
[/Quote]
性能! 我有50000个完全不同的字符串, 把里面得数字提取出来, 测试标准--在我机器上要跑进30ms
ChargeForward 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 157 楼 wuxing2006 的回复:]

while (true)
{
Stopwatch timer = new Stopwatch();
timer.Reset();
Hashtable ht = new Hashtable();
timer.Sta……
[/Quote]
不敢恭维
wuxing2006 2011-04-18
  • 打赏
  • 举报
回复
你要的是提分割数字而已, Split下就行,不用自己去分析字符串
ChargeForward 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 150 楼 zzxap 的回复:]

C# code
static void Main(string[] args)
{
Stopwatch timer = new Stopwatch();
timer.Reset();

HashSet<int> big = new HashSet<int>();
……
[/Quote]
你这个不就是袁锋的回答么?
wuxing2006 2011-04-18
  • 打赏
  • 举报
回复
while (true)
{
Stopwatch timer = new Stopwatch();
timer.Reset();
Hashtable ht = new Hashtable();
timer.Start();
for (int i = 0; i <= 50000; i++)
{
string apps = "112,2,3,4,5,6,7,8,9,10,112,12,13,14,15,16,17,18,19,20,";
string[] appsArray = apps.Split(new char[]{','},StringSplitOptions.RemoveEmptyEntries);

#region
for (int j = 0; j < appsArray.Length; j++)
{
string s = appsArray[j];
if (!ht.Contains(s))
{
ht.Add(s, s);
}
}
#endregion
}

timer.Stop();
int count = ht.Count;
Console.WriteLine(count + " " + timer.Elapsed.ToString());
Console.ReadLine();
}
加载更多回复(145)

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧